How to split a Swagger spec into smaller files
If you’re writing a Swagger API spec and it’s becoming too large, you can split it into multiple files. Swagger supports JSON Reference (draft) for using remote and local pieces of JSON to build up a Swagger document.
JSON Reference Overview
JSON Reference uses the special key $ref
to define a “reference” to a piece of JSON. For example following JSON has a reference to http://example.com/foo.json
:
Imagine the JSON file at http://example.com/foo.json
is following JSON:
If we “resolve” the JSON object that had a $ref
it will give us this:
As you see object containing the $ref
value is replaced with the object that reference was pointing to. Object containing $ref
con not have any other property. If they did, those properties would’ve got lost during resolution.
Remote And Local References
JSON References can be remote or local. A local reference, just like a local link in a HTML file starts with #
. A local reference uses a JSON Pointer (RFC 6901) to point to a piece of JSON inside current document. Consider following example:
After reference resolution, that JSON will be transformed to to this:
Note that "info"
was not removed from our JSON and the key "info"
was not added to the "information"
object. We just replaced what is inside "info"
object with object containing $ref
reference. Using local $ref
is a great way of avoiding repeating yourself when writing a JSON object.
As a convention, when defining a JSON Schema (RFC draft) all the objects that will get repeated go to "definitions"
object. Swagger embraces this and uses "definitions"
object as a place to hold your API models. The API models are used in parameters, responses and other places of a Swagger spec.
Using JSON References to split up a Swagger spec
Swagger spec can use $ref
s anywhere in the spec. You can put a reference instead of any object in Swagger. By default Swagger encourages spec developers to put their models in "definitions"
object. But you can do more than that and use $ref
s to put parts of your API spec into different files. For simplicity I am going to use YAML for rest of examples.
Imagine you have a Swagger spec like this:
This Swagger spec is very simple but we can still split it into smaller files.
First we need to define our folder structure. Here is our desired folder structure:
We keep root items in index.yaml
and put everything else in other files. Using index.yaml
as file name for your root file is a convention. In folders that hold only one file we also use index.yaml
as their file name.
Here is list of files with their contents:
index.yaml
info/index.yaml
definitions/index.yaml
definitions/User.yaml
paths/index.yaml
paths/foo.yaml
paths/bar.yaml
Note that in paths/bar.yaml
we are using a local reference while in the file itself the local reference will not get resolved. Most resolvers will resolve remote references first and the resolve local references. With that order, $ref: '#/definitions/User'
will be resolved inside index.yaml
after definitions/User.yaml
is populated in it.
Tools
json-refs
is the tool for resolving a set of partial JSON files into a single file. Apigee’s Jeremy Whitlock did the hard work of writing this library.
Here is an example of how to use JSON Refs and YAML-JS to resolve our multi-file Swagger:
Repository
You can find the example in this blog post in this GitHub repository