Skip to content

Overview ​

SAF uses OpenAPI to define and generate shared schemas and APIs across frontend and backend. This includes:

  • API routes
  • Business objects
  • Product events

Packages using @saflib/openapi can generate:

  • TypeScript types (dist/openapi.d.ts and per-operation/schema fragments)
  • JSON schemas (dist/openapi.json) for runtime validation

Use product/init to copy base into a new product. Use openapi/init to scaffold an offshoot spec (+ sibling *-test package). Use openapi/add-route, add-schema, and add-event to extend an existing spec.

The pkg: Extension ​

SAF extends OpenAPI to support linking schemas across NPM packages. This way an API spec can be split by domain and product/platform without relying on brittle relative paths.

Cross-package schema $refs can use a SAF pkg: convention resolved at generate time:

yaml
schema:
  $ref: "pkg:@scope/product-offshoot-spec/openapi.yaml#/components/schemas/Widget"

The most common use of this is the shared error object which lives in @saflib/openapi.

yaml
schema:
  $ref: "pkg:@saflib/openapi/schemas/error.yaml"

Package structure ​

Where a spec package lives in the product tree — {product}/service/spec, offshoot slices, and how http / sdk depend on it — is described in monorepo service layout. The golden reference implementation is saflib/base:

LocationPackageRole
base/service/spec@saflib/base-specProduct API contract
base/service/test@saflib/base-testShared schema factories for tests
base/__offshoot-name__/spec(offshoot spec)Bounded feature slice; paths woven into the parent openapi.yaml