OpenAPI Components

By Phil Sturgeon
Last update on July 02, 2024

The Components object in OpenAPI allows you to create reusable bits of OpenAPI that can then be pieced together like Lego blocks to build a better API description. This keeps things nice and tidy, and you can even spread them across multiple documents to share components between multiple APIs, or at least just keep your file sizes down.

components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        email:
          type: string
          format: email
  parameters:
    userId:
      name: id
      in: path
      description: ID of the user
      required: true
      schema:
        type: integer
  responses:
    NotFound:
      description: User not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  requestBodies:
    User:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/User'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

The full list of objects which can be defined in components is:

Using $ref with Components #

Once components have been defined they can be referenced with $ref. This is mostly the same definition of $ref in JSON Schema so it can help to learn how that works, but there are a few caveats to keep in mind.

The OpenAPI Documentation from the OpenAPI Initiative includes a brilliant example of an API for playing the classic board game Tic Tac Toe, and it demonstrates $ref nicely.

This has several parts that are used several times, so instead of copy-pasting everything they’ve defined reusable components for both schemas and parameters.

paths:
  # Whole board operations
  /board:
    get:
      summary: Get the whole board
      description: Retrieves the current state of the board and the winner.
      tags:
        - Gameplay
      operationId: get-board
      responses:
        "200":
          description: "OK"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/status"
  # Single square operations
  /board/{row}/{column}:
    parameters:
      - $ref: "#/components/parameters/rowParam"
      - $ref: "#/components/parameters/columnParam"
    get:
      # ... Hidden for readability...
    put:
      # ... Hidden for readability...

components:
  parameters:
    rowParam:
      description: Board row (vertical coordinate)
      name: row
      in: path
      required: true
      schema:
        $ref: "#/components/schemas/coordinate"
    columnParam:
      description: Board column (horizontal coordinate)
      name: column
      in: path
      required: true
      schema:
        $ref: "#/components/schemas/coordinate"
  schemas:
    errorMessage:
      type: string
      maxLength: 256
      description: A text message describing an error
    coordinate:
      type: integer
      minimum: 1
      maximum: 3
      example: 1
    mark:
      type: string
      enum: [".", "X", "O"]
      description: Possible values for a board square. `.` means empty square.
      example: "."
    board:
      type: array
      maxItems: 3
      minItems: 3
      items:
        type: array
        maxItems: 3
        minItems: 3
        items:
          $ref: "#/components/schemas/mark"
    winner:
      type: string
      enum: [".", "X", "O"]
      description: Winner of the game. `.` means nobody has won yet.
      example: "."
    status:
      type: object
      properties:
        winner:
          $ref: "#/components/schemas/winner"
        board:
          $ref: "#/components/schemas/board"

Hopefully this gives an idea of how $ref can be used, and if you’d like to learn more check out our advanced guide: Splitting Documents with $ref.

Create “Design Libraries” of Shared Components #

An OpenAPI document does not need to contain paths or webhooks, it could be just a components object with nothing else.

One of more of these “components only” documents could then be shared around forming a rudimentary “design library”, helping teams reuse data models and various other bits across multiple APIs, multiple departments, or even externally to your organization.

There are various proprietary tools out there to help with this, but the concept can be achieved by just sharing these openapi-components.yaml or similar on your network drive, Git repository, intranet, or public website.

Schema and Data Types