Components and $ref

OpenAPI · Practical · 12 min

Reuse keeps large API descriptions consistent and generates cleaner SDK types.

Anything you repeat belongs in components, in the section for its kind: schemas, parameters, responses, requestBodies, headers, examples, securitySchemes, links, callbacks, and (3.1) pathItems.

Reference it with a JSON Reference: $ref: '#/components/schemas/Book'. The part after # is a JSON Pointer into the document. References can point to other files too: $ref: './schemas/book.yaml' or 'common.yaml#/components/responses/NotFound'.

Good reuse patterns:

  • Named schemas for every domain object. Generators turn each into a named class or type; inline anonymous schemas become awkward names like InlineResponse2001.
  • Shared parameters (Limit, Cursor) and shared error responses (NotFound, ValidationError).
  • Separate input and output shapes when they differ (NewBook vs Book), or rely on readOnly/writeOnly.

$ref semantics: in 3.0, a $ref object replaces the whole object, so sibling keywords are ignored. In 3.1, inside schemas $ref behaves like JSON Schema and siblings are allowed (e.g. a description next to $ref); Reference Objects elsewhere may only add summary and description.

Keep the tree navigable: split by domain (schemas/, paths/) for big APIs, and bundle into a single file for publishing.

Example

paths:
  /books:
    get:
      operationId: listBooks
      parameters:
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: A page of books
          content:
            application/json:
              schema: { type: array, items: { $ref: '#/components/schemas/Book' } }
        '400': { $ref: '#/components/responses/ValidationError' }
components:
  parameters:
    Limit: { name: limit, in: query, schema: { type: integer, minimum: 1, maximum: 100, default: 20 } }
  responses:
    ValidationError:
      description: The request is invalid
      content:
        application/problem+json:
          schema: { $ref: './schemas/problem.yaml' }   # another file
  schemas:
    Book: { $ref: './schemas/book.yaml' }

Remember

  • Put repeated schemas, parameters and responses in components
  • $ref is a JSON Pointer, locally or into other files
  • Named schemas become clean SDK types
  • 3.1 allows siblings next to $ref inside schemas

Watch out for

  • Inlining the same schema in many places so it drifts and generates many duplicate types.

Check yourself

  1. What does `#/components/schemas/Book` in a `$ref` denote?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: learn.openapis.org/referencing/overview.html