.../articles/
How to Split and Structure an OpenAPI Schema

How to Split and Structure an OpenAPI Schema

2019.12.22

In the previous article, I wrote about our approach to development centered around the OpenAPI schema.

A common pain point when writing OpenAPI or Swagger files is that the file tends to balloon in size relative to its actual content. (There aren't that many endpoints, yet it ends up hundreds of lines long 😇)

I consider this problem of files growing too large to be fairly serious, so I've been thinking about splitting the schema into multiple files using $ref.

That said, it seems like there currently aren't many tools that integrate with OpenAPI and can resolve file references, so I've also been thinking it might be more convenient to keep everything in a single file after all.

So, I tried out a method for managing the schema as split files while ultimately combining them into a single schema.


Managing the schema by splitting it into files

First, let's look at how to manage the schema by splitting it into files. I've put together an example schema in a repository, which I'll use as a reference here.

The starting point is root.yml, and the other files are organized into directories according to the namespaces of the OpenAPI Object, with each file referencing others via relative paths.

From root.yml, we reference the files defined for each path. Definitions for /users go into ./paths/users.yml, and definitions for /users/{user_id} go into ./paths/users-by-id.yml.

# root.yml
paths:
  /users:
    $ref: ./paths/users.yml
  /users/{user_id}:
    $ref: ./paths/users-by-id.yml

Under each path, the parameters and responses for each method are described.

# paths/users.yml
get:
  operationId: usersGet
  summary: get user list
  tags: [user]
  parameters:
    - $ref: ../components/parameters/page.yml
    - $ref: ../components/parameters/per_page.yml
  responses:
    200:
      description: ok
      content:
        application/json:
          schema:
            $ref: ../components/schemas/user_list.yml
post:
  operationId: usersPost
  summary: create new user
  tags: [user]
  requestBody:
    description: user information
    required: true
    content:
      application/json:
        schema:
          $ref: ../components/schemas/user_input.yml
  responses:
    201:
      description: created
      content:
        application/json:
          schema:
            $ref: ../components/schemas/user.yml

Commonly used parameters reference files defined under components/parameters, and objects returned in request bodies or responses reference files defined under components/schemas.

Splitting files this way makes it clear where to add or edit things when you need to update the schema.

Combining the schema

The approach described so far makes the schema easier to manage, but ultimately it's nice to have the schema as a single file.

So, we use openapi-generator to combine the schema.

openapi-generator can generate client-facing code and the like based on a schema, and if you look at the generator types available via the command, there are openapi and openapi-yaml (not mentioned in the README?).

DOCUMENTATION generators:
    - cwiki
    - dynamic-html
    - html
    - html2
    - openapi
    - openapi-yaml

Using this generator, you can produce a schema in JSON or YAML with all file references expanded, based on root.yml.

# Output the combined schema in JSON format
$ openapi-generator generate -g openapi -i root.yml -o generated
# Output the combined schema in YAML format
$ openapi-generator generate -g openapi-yaml -i root.yml -o generated

This lets us manage the schema as split files while ultimately being able to output it as a single combined schema. As far as I can tell, the file references are being expanded correctly.


A side note

Is OpenAPITools official?

Some articles introduce openapi-generator as if it were an official tool, but if you look at the GitHub organization, it says the following:

NOTE: This organization is not affiliated with OpenAPI Initiative (OAI)

So it doesn't appear to be official, but development seems active, and it seems to be relatively widely used among similar tools, so for now I plan to keep using it.

Is it painful to write a schema once you've split it into files?

Using Swagger Editor or various editor plugins makes editing easier, since they validate the schema and offer key completion as you write.

However, once you split the schema into files, no single file constitutes a valid OpenAPI schema on its own, so it can be tough unless you already have a decent understanding of how to write a schema.

At the point where openapi-generator combines the files, obvious schema errors become apparent, but not being able to tell before then is a bit painful.

Right now I run the generator every time the schema changes, so it would be nice to be able to detect schema changes and edit with a live preview.

  • Addendum

I tried using chokidar to detect changes to the split schema files and run openapi-generator.

Running the watch npm script below will detect changes to the schema definition YAML files and generate the combined schema. Please install the necessary packages such as openapi-generator and npm-run-all.

{
  "scripts": {
    "validate-generated-schema": "openapi-generator validate -i generated/openapi/openapi.yaml",
    "run-generator": "openapi-generator generate -g openapi-yaml -i root.yml -o generated",
    "generate": "npm-run-all -s run-generator validate-generated-schema",
    "watch": "chokidar 'root.yml' '**/*.yml' -c 'yarn generate'"
  }
}

Also, if you want to edit the schema as a single file, Stoplight Studio looks like a good option too.

written by

.../article/

Articles

All articles

From Firebase to Vercel, Contentful to microCMS — a migration log written with Claude Code

From Firebase to Vercel, Contentful to microCMS — a migration log written with Claude Code

We moved our corporate site's hosting and CMS, and made it bilingual along the way. The constraints we only found by running against real data were more useful than the migration itself, so this post focuses on where we got stuck.

Can't Read POST Data with Firebase Functions × Remix?

Can't Read POST Data with Firebase Functions × Remix?

How to read POST data from a Remix action when running on Firebase Functions.

Generative AI for Executives and Leaders: An Approach to Self-Driven DX

Generative AI for Executives and Leaders: An Approach to Self-Driven DX

Building a structure where executives and leaders themselves can identify issues and evaluate solutions using generative AI. We introduce how combining this with our hands-on support dramatically improves both the quality and speed of digital transformation.

Deploying a Monorepo Next.js App (App Router) to AWS Amplify

Deploying a Monorepo Next.js App (App Router) to AWS Amplify

Notes on the obstacles we hit while deploying a Next.js app managed in a monorepo to AWS Amplify.

Keeping Production Running Smoothly with Remote Work and Online Meetings [Documentation]

Keeping Production Running Smoothly with Remote Work and Online Meetings [Documentation]

Many production companies have adopted remote work as a result of the pandemic, and we are one of them.

Designing an E-Commerce Site That Sells: How to Find Great Reference Examples

Designing an E-Commerce Site That Sells: How to Find Great Reference Examples

There is no single formula for e-commerce design that sells. Driving revenue requires a solid concept, and getting to that concept requires thorough research.

Productivity Tools We Recommend as a Production Company, Including Services That Work Well Solo

Productivity Tools We Recommend as a Production Company, Including Services That Work Well Solo

With remote work becoming the norm during the COVID-19 pandemic, our team now works from home most days of the week.

We Released Thought Recorder, a Figma Plugin for Keeping a Commit History of Your Designs

We Released Thought Recorder, a Figma Plugin for Keeping a Commit History of Your Designs

We hope this helps web designers who work in Figma. Read on for how to use it.

How to Build an E-Commerce Site, and Which Platforms We Recommend

How to Build an E-Commerce Site, and Which Platforms We Recommend

Shopping online for fashion, appliances, and even groceries is now routine. With the pandemic accelerating the shift, we receive a steady stream of questions about which platform to use and how much it costs.

Generating FastAPI Schema Classes from OpenAPI

Generating FastAPI Schema Classes from OpenAPI

We chose FastAPI, a relatively modern framework, for a Python API project. FastAPI can generate an OpenAPI definition from your backend code, but here we do the opposite: generating FastAPI schema classes from an OpenAPI definition prepared in advance.

View all articles

Contact us