OpenAPI Client Generation

This project uses OpenAPI Generator to automatically generate the API client services and models based on the Apache Fineract Swagger specification.

Configuration

The generator is configured in package.json and uses custom templates located in templates/openapi-generator/.

  • Output Directory: src/app/api/
  • Spec Source: public/api/fineract.json (preprocessed into api-spec/fineract.json during generation)
  • Custom Templates: templates/openapi-generator/licenseInfo.mustache (adds Apache License header to all files)
  • Spec Preprocessor: scripts/preprocess-spec.mjs (rewrites operationIds for stable method names — see below)

Stable method names (important)

Generated method names are stable across spec versions by design. Without intervention, the typescript-angular generator names methods from the spec's operationIds, which the Fineract spec reuses across hundreds of endpoints; the generator then disambiguates them with a global, document-order counter (retrieveAll21, create6, ...). Any spec change reshuffles every number and breaks call sites throughout the app.

To prevent this, npm run copy-swagger runs scripts/preprocess-spec.mjs, which rewrites every operationId to a deterministic value derived from the HTTP method + request path:

EndpointGenerated method
GET /v1/clientsgetClients
GET /v1/clients/{clientId}getClientsClientId
PUT /v1/savingsaccounts/{id}putSavingsaccountsAccountId

Because (method, path) is unique per OpenAPI, these names are collision-free and independent of document order, so regenerating against a newer Fineract spec does not churn names. The preprocessor also fills in any missing responses.*.description, so generation passes validation without --skip-validate-spec. The committed spec (public/api/fineract.json) is never modified — only the throwaway api-spec/fineract.json copy the generator consumes.

The rationale and alternatives considered are recorded in DOCS/adr/0001-stable-openapi-operation-ids.md.

Commands

Generate the API Client

To (re)generate the API client, run:

npm run generate-api

This command will:

  1. Preprocess the spec (copy-swagger): run scripts/preprocess-spec.mjs to rewrite operationIds and patch missing response descriptions, writing api-spec/fineract.json.
  2. Clean the previous output (clean-api): remove src/app/api/api and src/app/api/model so endpoints removed upstream do not leave orphan files behind (the generator never prunes).
  3. Run the OpenAPI generator (typescript-angular, ngVersion=22.0.7) with the custom license header template.

Update the Swagger Spec

This is automated. .github/workflows/api-spec-sync.yml runs weekly, and opens a pull request whenever Apache Fineract‘s spec changes — with the removed operations and their call sites listed in the body. See ADR 0002. To run it on demand, use the workflow’s workflow_dispatch trigger; dry_run: true does everything except open the PR.

To do it by hand, replace public/api/fineract.json and run npm run generate-api. You can also point at a spec elsewhere via the FINERACT_SWAGGER_PATH environment variable. Because method names are stable (see above), most call sites continue to compile; only genuinely added/removed/renamed endpoints need attention.

Upstream serves the spec minified; the committed copy is Prettier-formatted, and public/ is not in .prettierignore. Run npm run format after replacing the file or CI's format job fails on a single 1.4 MB line.

The spec can be read straight out of the published image without booting anything:

CID=$(docker create apache/fineract:latest)
docker cp "$CID:/app/resources/static/fineract.json" ./fineract.json
docker rm -f "$CID"

Provenance

public/api/fineract.provenance.json records where the committed spec came from: the image reference and digest, the upstream commit, info.version, path/operation/schema counts, and hashes of both the raw upstream bytes and the committed file. It is written by the sync workflow — do not edit it by hand.

Maintenance

Custom Templates

If you need to customize the generated code further (e.g., adding common interceptors or changing the way models are generated), you can add more .mustache files to the templates/openapi-generator/ directory.

Ignoring Files

To prevent the generator from overwriting or creating certain files, add them to the .openapi-generator-ignore file in the root of the project. Currently ignored:

  • git_push.sh
  • README.md (inside src/app/api/)
  • .gitignore (inside src/app/api/)