Operator Guide: OpenAPI Schema Loading, Code Generation, and Swagger Serving¶
This guide explains where Syfon loads OpenAPI schemas, how make gen works, how specs are served at Swagger endpoints, and how to update the GA4GH schema version.
1) Schema sources and default inputs¶
GA4GH DRS canonical schema¶
Syfon vendors the upstream GA4GH DRS schemas as a Git submodule:
- Submodule path:
ga4gh/data-repository-service-schemas - Default DRS OpenAPI input:
ga4gh/data-repository-service-schemas/openapi/data_repository_service.openapi.yaml
The Makefile defaults are:
OPENAPI ?= ga4gh/data-repository-service-schemas/openapi/data_repository_service.openapi.yaml
SCHEMAS_SUBMODULE ?= ga4gh/data-repository-service-schemas
OPENAPI_DIR ?= apigen/openapi
CODEGEN_CONFIG_DIR ?= apigen/codegen
Additional local OpenAPI inputs¶
Syfon also maintains local OpenAPI inputs for additional generated packages:
apigen/openapi/lfs.openapi.yamlapigen/openapi/bucket.openapi.yamlapigen/openapi/metrics.openapi.yamlapigen/openapi/internal.openapi.yaml
2) OpenAPI code generation tasks in this repository¶
All OpenAPI generation is centralized in make gen.
| Target | Inputs | Outputs | Generator mode |
|---|---|---|---|
make gen |
GA4GH DRS spec plus local OpenAPI YAML files under apigen/openapi/ |
apigen/openapi/*.yaml, apigen/server/*, apigen/client/* |
oapi-codegen with custom Fiber templates |
Notes on make gen¶
make gen performs this flow:
- Validate input and optionally initialize the GA4GH schema submodule.
- Bundle the upstream GA4GH DRS schema with Redocly into
.tmp/drs.base.yaml. - Copy the bundled DRS spec into
apigen/openapi/openapi.yaml. - Apply the local
x-go-namefixup for the checksum parameter. - Generate DRS server bindings into
apigen/server/drs/drs.gen.go. - Generate LFS, bucket, metrics, and internal server bindings into
apigen/server/*. - Generate DRS, LFS, bucket, metrics, and internal client bindings into
apigen/client/*. - Apply the post-codegen DRS
service-infotype fix so generated output does not require handwritten compat shims.
How generated code is used¶
The generated surface is split deliberately:
apigen/server/drscontains the generated DRS server interfaces, routers, models, and helper types.apigen/server/lfsapi,apigen/server/bucketapi,apigen/server/metricsapi, andapigen/server/internalapicontain generated server-side contract packages for the local OpenAPI specs.apigen/client/*contains the generated client-side contract packages consumed acrosssyfon,git-drs, anddata-client.- The
clientmodule itself is handwritten, but it consumes generatedapigenrequest and response types so client and server stay aligned.
Common change recipes¶
| Change you are making | Edit these files first | Regenerate with | Why |
|---|---|---|---|
| Add or remove a DRS endpoint | ga4gh/data-repository-service-schemas submodule |
make gen |
Keeps the bundled DRS spec and generated DRS bindings aligned. |
| Add or change a DRS field or model | Upstream spec or Syfon DRS overlay | make gen |
Refreshes generated DRS client and server shapes. |
| Change LFS, bucket, metrics, or internal request/response shapes | apigen/openapi/*.openapi.yaml |
make gen |
Refreshes the generated package that owns that contract. |
| Change route behavior, auth, middleware, or validation logic only | cmd/server, internal/api/*, internal/api/middleware/* |
No regen needed | These are handwritten runtime concerns, not generated contracts. |
Update docs served at /index/openapi.yaml |
apigen/openapi/*.yaml and embed/load code |
make gen plus tests |
The runtime docs endpoint reads the bundled spec files. |
Service-info type fix¶
If oapi-codegen emits N200ServiceInfo... or N200ServiceInfoJSONResponse... references in DRS output, the repository keeps small handwritten compat.go alias files in apigen/client/drs and apigen/server/drs.
Those aliases exist because the /service-info response is a composed schema and oapi-codegen currently emits references to response-scoped enum names that it does not define.
What usually changes in git¶
- DRS changes usually touch the submodule pointer,
apigen/openapi/openapi.yaml, andapigen/server/drsplusapigen/client/drs. - LFS changes usually touch
apigen/openapi/lfs.openapi.yamland the generatedlfsapipackages. - Bucket, metrics, and internal schema changes follow the same pattern in their corresponding
apigen/openapi/*.openapi.yamlfile and generated package directories. - Pure runtime changes usually do not touch
apigen/at all.
3) Runtime serving path to Swagger¶
Swagger/OpenAPI serving flow:
- Server startup calls
docs.RegisterSwaggerRoutes(api). GET /index/swaggerreturns the Swagger UI page.- The UI loads
GET /index/openapi.yaml. GET /index/openapi.yamlis built by merging runtime spec documents:- required:
openapi.yaml(DRS),lfs.openapi.yaml - optional:
bucket.openapi.yaml,metrics.openapi.yaml,internal.openapi.yaml,compat.openapi.yaml - Spec files are read from embedded assets first via
apigen/openapi/specs_embed.go(ReadSpec), with filesystem fallback for local dev.
Sanity checks¶
make genshould complete without recreating.openapi-generatormetadata or a removedapigen/modelpackage.go test ./cmd/server ./tests/endpoints/...should pass for DRS route and coverage changes.- Route/spec changes should also be validated against:
/index/swagger/index/openapi.yaml/index/lfs.openapi.yaml/index/bucket.openapi.yaml/index/internal.openapi.yaml
4) Confirming currently pinned GA4GH schema version¶
Run from repo root:
# authoritative submodule pointer committed in superproject
git ls-tree HEAD ga4gh/data-repository-service-schemas
# branch hint configured for the submodule
cat .gitmodules
# initialize or refresh local submodule checkout
make init-schemas
# actual checked-out commit in local submodule worktree
git -C ga4gh/data-repository-service-schemas rev-parse HEAD