openapi: 3.0.2 info: version: 1.0.0 title: "{json:api} Specification" description: > An include file to define the [{json:api} 1.0 specification](http://jsonapi.org/format). N.B. I've got some confusion going on between a validating a jsonapi schema and defining one! This file also provides a limited demonstration of jsonapi with path items for collections, items and their methods. You should be able to open in a modern version of [swagger-editor](https://github.com/swagger-api/swagger-editor) or [swagger-ui-watcher](https://github.com/moon0326/swagger-ui-watcher). This file was created by downloading the [schema definition](http://jsonapi.org/schema) and then editing as needed to make it useful with the Open API Specification. It is subject to the `CC0 1.0 Universal` license as it is derived from the {json:api} specification. Several changes had to be made to that schema since it is non-normative and primarily only documented the results of GET operations. See especially definitions of `post_datum`, `post_resource`, `datum`, and `metaonly` that were added. **USAGE** You can reference definitions in this schema with `$ref` as defined in the OAS specification, but be aware that the "[[Reference Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#reference-object)] cannot be extended with additional properties and any properties added SHALL be ignored." So $refs are pretty useless if you are trying to keep things DRY. Specifically, you'll need to copy and the path items into your own schema doc and "extend" them by adding what you need (e.g. security, additional parameters, referneces to your app's request/response schemas, etc.). For example: ``` paths: /courses/: get: description: Returns a collection of courses operationId: find courses security: - basicAuth: [] - oauth: [auth-columbia, read] parameters: # I wish I could pull all these in at once... - $ref: './jsonapi.yaml#/components/parameters/include' - $ref: './jsonapi.yaml#/components/parameters/sort' - $ref: './jsonapi.yaml#/components/parameters/pageSize' - $ref: './jsonapi.yaml#/components/parameters/pageNumber' - name: 'filter[id]' in: query description: exact id required: false style: form schema: $ref: './jsonapi.yaml#/components/schemas/id' responses: '200': description: course response content: application/vnd.api+json: schema: $ref: '#/components/schemas/CourseCollection' '401': description: not authorized content: application/vnd.api+json: schema: $ref: './jsonapi.yaml#/components/schemas/error' ``` You can locate this file on a web server or in a local directory and `$ref` it appropriately; `swagger-ui-watcher` will follow the `$ref`s and can be used to "bundle" your schema into a single JSON document as follows: ``` swagger-ui-watcher -b myapp.json --path myapp.yaml ``` contact: name: Alan Crosswell email: alan@columbia.edu url: "http://www.columbia.edu/~alan" license: name: CC0 1.0 Universal url: "https://creativecommons.org/publicdomain/zero/1.0/" externalDocs: description: Read more about {json:api} here url: https://jsonapi.org/ servers: - url: "{serverURL}" description: provide your server URL variables: serverURL: default: http://localhost:8000/v1 description: path for server # not sure why but swagger-editor only prompts for the variable if there's more than one server listed. - url: "{serverURL}" description: provide your server URL variables: serverURL: default: http://localhost:8000/v1 description: path for server # Example generic paths and their methods: path parameters are {collection} and {id} paths: /{collection}/: parameters: - name: collection in: path required: true schema: type: string get: description: get a collection operationId: get collection parameters: - $ref: '#/components/parameters/include' - $ref: '#/components/parameters/sort' - $ref: '#/components/parameters/pageSize' - $ref: '#/components/parameters/pageNumber' responses: '200': description: "[OK](https://jsonapi.org/format/#fetching-resources-responses-200)" content: application/vnd.api+json: schema: $ref: '#/components/schemas/success' '404': description: "[Not found](https://jsonapi.org/format/#fetching-resources-responses-404)" content: application/vnd.api+json: schema: $ref: '#/components/schemas/failure' default: description: collection response content: application/vnd.api+json: schema: $ref: '#/components/schemas/JSONAPIresponse' post: description: "[add](https://jsonapi.org/format/#crud-creating) item to a collection" operationId: post item requestBody: description: item to post content: 'application/vnd.api+json': schema: $ref: '#/components/schemas/post_datum' responses: '201': description: >- [Created](https://jsonapi.org/format/#crud-creating-responses-201). Assigned `id` and/or any other changes are in this response. content: 'application/vnd.api+json': schema: $ref: '#/components/schemas/datum' '202': description: >- Accepted for [asynchronous processing](https://jsonapi.org/recommendations/#asynchronous-processing). content: 'application/vnd.api+json': schema: $ref: '#/components/schemas/datum' headers: Content-Location: description: URL for status of processing schema: type: string format: uri-reference '204': description: >- [Created](https://jsonapi.org/format/#crud-creating-responses-204) with the supplied `id`. No other changes from what was POSTed. '403': description: "[Forbidden](https://jsonapi.org/format/#crud-creating-responses-403)" content: 'application/vnd.api+json': schema: $ref: '#/components/schemas/failure' '404': description: >- [Related resource does not exist](https://jsonapi.org/format/#crud-creating-responses-404). content: 'application/vnd.api+json': schema: $ref: '#/components/schemas/failure' '409': description: "[Conflict](https://jsonapi.org/format/#crud-creating-responses-409)" content: 'application/vnd.api+json': schema: $ref: '#/components/schemas/failure' default: description: other post response content: 'application/vnd.api+json': schema: $ref: '#/components/schemas/JSONAPIresponse' /{collection}/{id}/: parameters: - name: collection in: path required: true schema: type: string - name: id in: path required: true schema: $ref: '#/components/schemas/id' get: description: get an item operationId: get item responses: '200': description: "[OK](https://jsonapi.org/format/#fetching-resources-responses-200)" content: application/vnd.api+json: schema: $ref: '#/components/schemas/datum' '404': description: "[Not found](https://jsonapi.org/format/#fetching-resources-responses-404)" content: application/vnd.api+json: schema: $ref: '#/components/schemas/failure' default: description: get item response content: application/vnd.api+json: schema: $ref: '#/components/schemas/JSONAPIresponse' patch: description: "[update](https://jsonapi.org/format/#crud-updating) an item" operationId: patch item requestBody: description: item to patch content: 'application/vnd.api+json': schema: $ref: '#/components/schemas/datum' responses: '200': description: "[OK](https://jsonapi.org/format/#crud-updating-responses-200)" content: application/vnd.api+json: schema: $ref: '#/components/schemas/datum' '202': description: >- Accepted for [asynchronous processing](https://jsonapi.org/recommendations/#asynchronous-processing). content: 'application/vnd.api+json': schema: $ref: '#/components/schemas/datum' headers: Content-Location: description: URL for status of processing schema: type: string format: uri-reference '204': description: >- [Patched](https://jsonapi.org/format/#crud-updating-responses-204). No other changes from what was PATCHed. '403': description: "[Forbidden](https://jsonapi.org/format/#crud-updating-responses-403)" content: 'application/vnd.api+json': schema: $ref: '#/components/schemas/failure' '404': description: >- [Resource does not exist](https://jsonapi.org/format/#crud-updating-responses-404). content: 'application/vnd.api+json': schema: $ref: '#/components/schemas/failure' '409': description: "[Conflict](https://jsonapi.org/format/#crud-updating-responses-409)" content: 'application/vnd.api+json': schema: $ref: '#/components/schemas/failure' default: description: get item response content: application/vnd.api+json: schema: $ref: '#/components/schemas/JSONAPIresponse' delete: description: "[delete](https://jsonapi.org/format/#crud-deleting) an item" operationId: delete item responses: '200': description: "[OK](https://jsonapi.org/format/#crud-deleting-responses-200)" content: application/vnd.api+json: schema: $ref: '#/components/schemas/onlymeta' '202': description: >- Accepted for [asynchronous processing](https://jsonapi.org/recommendations/#asynchronous-processing). content: 'application/vnd.api+json': schema: $ref: '#/components/schemas/datum' '204': description: >- [Deleted](https://jsonapi.org/format/#crud-deleting-responses-204). '404': description: >- [Resource does not exist](https://jsonapi.org/format/#crud-deleting-responses-404). content: 'application/vnd.api+json': schema: $ref: '#/components/schemas/failure' # Following is {json:api} schema definition in a form suitable for $ref usage components: schemas: JSONAPIresponse: oneOf: - $ref: "#/components/schemas/success" - $ref: "#/components/schemas/failure" - $ref: "#/components/schemas/info" success: type: object required: - data properties: data: $ref: "#/components/schemas/data" included: description: >- To reduce the number of HTTP requests, servers **MAY** allow responses that include related resources along with the requested primary resources. Such responses are called `compound documents`. type: array items: $ref: "#/components/schemas/resource" uniqueItems: true meta: $ref: "#/components/schemas/meta" links: description: Link members related to the primary data. allOf: - $ref: "#/components/schemas/links" - $ref: "#/components/schemas/pagination" jsonapi: $ref: "#/components/schemas/jsonapi" additionalProperties: false failure: type: object required: - errors properties: errors: type: array items: $ref: "#/components/schemas/error" uniqueItems: true meta: $ref: "#/components/schemas/meta" jsonapi: $ref: "#/components/schemas/jsonapi" links: $ref: "#/components/schemas/links" additionalProperties: false info: type: object required: - meta properties: meta: $ref: "#/components/schemas/meta" links: $ref: "#/components/schemas/links" jsonapi: $ref: "#/components/schemas/jsonapi" additionalProperties: false onlymeta: properties: meta: $ref: "#/components/schemas/meta" additionalProperties: false meta: description: >- Non-standard meta-information that can not be represented as an attribute or relationship. type: object additionalProperties: true data: description: >- The document's `primary data` is a representation of the resource or collection of resources targeted by a request. oneOf: - $ref: "#/components/schemas/resource" - description: >- An array of resource objects, an array of resource identifier objects, or an empty array ([]), for requests that target resource collections. type: array items: $ref: "#/components/schemas/resource" uniqueItems: true - $ref: "#/components/schemas/nulltype" post_datum: description: >- singular item being [created](https://jsonapi.org/format/#crud-creating). `id` is optional and may be ignored if supplied and created by the system. properties: data: $ref: "#/components/schemas/post_resource" datum: description: singular item properties: data: $ref: "#/components/schemas/resource" resource: description: Resource objects appear in a JSON API document to represent resources. type: object required: - type - id properties: type: $ref: "#/components/schemas/type" id: $ref: "#/components/schemas/id" attributes: $ref: "#/components/schemas/attributes" relationships: $ref: "#/components/schemas/relationships" links: $ref: "#/components/schemas/links" meta: $ref: "#/components/schemas/meta" additionalProperties: false # unfortunately $ref resource and tring to change required doesn't work. post_resource: description: A POSTable resource object has an optional id. type: object required: - type properties: type: $ref: "#/components/schemas/type" id: $ref: "#/components/schemas/id" attributes: $ref: "#/components/schemas/attributes" relationships: $ref: "#/components/schemas/relationships" # not clear what it means to try to POST links but the spec says POST a Resource Object... links: $ref: "#/components/schemas/links" meta: $ref: "#/components/schemas/meta" additionalProperties: false relationshipLinks: description: >- A resource object **MAY** contain references to other resource objects (`relationships`). Relationships may be to-one or to-many. Relationships can be specified by including a member in a resource's links object. type: object properties: self: description: >- A `self` member, whose value is a URL for the relationship itself (a `relationship URL`). This URL allows the client to directly manipulate the relationship. For example, it would allow a client to remove an `author` from an `article` without deleting the people resource itself. $ref: "#/components/schemas/link" related: $ref: "#/components/schemas/link" additionalProperties: true links: type: object additionalProperties: $ref: "#/components/schemas/link" link: description: >- A link **MUST** be represented as either: a string containing the link's URL or a link object. oneOf: - description: A string containing the link's URL. type: string format: uri-reference - type: object required: - href properties: href: description: A string containing the link's URL. type: string format: uri-reference meta: $ref: "#/components/schemas/meta" attributes: description: >- Members of the attributes object (`attributes`) represent information about the resource object in which it's defined. type: object # properties: # ^(?!relationships$|links$|id$|type$)\w[-\w_]*$: # type: object # description: Attributes may contain any valid JSON value. additionalProperties: false # TODO: This validates rather than defines: relationships: description: >- Members of the relationships object represent references from the resource object in which it's defined to other resource objects. N.B. this is validation, not useful for inclusion. type: object # properties: # ^(?!id$|type$)\w[-\w_]*$: # $ref: "#/components/schemas/relationship" additionalProperties: $ref: "#/components/schemas/relationship" relationship: description: A single relationship description type: object properties: links: $ref: "#/components/schemas/relationshipLinks" data: description: Member, whose value represents `resource linkage`. oneOf: - $ref: "#/components/schemas/relationshipToOne" - $ref: "#/components/schemas/relationshipToMany" meta: $ref: "#/components/schemas/meta" anyOf: - required: - data - required: - meta - required: - links additionalProperties: false relationshipToOne: description: >- References to other resource objects in a to-one (`relationship`). Relationships can be specified by including a member in a resource's links object. anyOf: - $ref: "#/components/schemas/empty" - $ref: "#/components/schemas/linkage" reltoone: description: A singular relationship type: object properties: links: $ref: "#/components/schemas/relationshipLinks" data: $ref: "#/components/schemas/relationshipToOne" meta: $ref: "#/components/schemas/meta" reltomany: description: A multiple relationship type: object properties: links: $ref: "#/components/schemas/relationshipLinks" data: $ref: "#/components/schemas/relationshipToMany" meta: $ref: "#/components/schemas/meta" reltoonedata: description: A singular relationship, data only. type: object properties: data: $ref: "#/components/schemas/relationshipToOne" reltomanydata: description: A multiple relationship, data only. type: object properties: data: $ref: "#/components/schemas/relationshipToMany" relationshipToMany: description: >- An array of objects each containing `type` and `id` members for to-many relationships. type: array items: $ref: "#/components/schemas/linkage" uniqueItems: true empty: $ref: "#/components/schemas/nulltype" linkage: description: The `type` and `id` to non-empty members. type: object required: - type - id properties: type: type: string id: type: string meta: $ref: "#/components/schemas/meta" additionalProperties: false pagination: type: object properties: first: description: The first page of data oneOf: - type: string format: uri-reference - $ref: "#/components/schemas/nulltype" last: description: The last page of data oneOf: - type: string format: uri-reference - $ref: "#/components/schemas/nulltype" prev: description: The previous page of data oneOf: - type: string format: uri-reference - $ref: "#/components/schemas/nulltype" next: description: The next page of data oneOf: - type: string format: uri-reference - $ref: "#/components/schemas/nulltype" jsonapi: description: An object describing the server's implementation type: object properties: version: type: string meta: $ref: "#/components/schemas/meta" additionalProperties: false error: type: object properties: id: description: A unique identifier for this particular occurrence of the problem. type: string links: $ref: "#/components/schemas/links" status: description: >- The HTTP status code applicable to this problem, expressed as a string value. type: string code: description: >- An application-specific error code, expressed as a string value. type: string title: description: >- A short, human-readable summary of the problem. It **SHOULD NOT** change from occurrence to occurrence of the problem, except for purposes of localization. type: string detail: description: >- A human-readable explanation specific to this occurrence of the problem. type: string source: type: object properties: pointer: description: >- A JSON Pointer [RFC6901] to the associated entity in the request document [e.g. `/data` for a primary data object, or `/data/attributes/title` for a specific attribute]. type: string parameter: description: A string indicating which query parameter caused the error. type: string meta: $ref: "#/components/schemas/meta" additionalProperties: false nulltype: description: OAS doesn't allow the null type so use this. type: object nullable: true default: null id: type: string description: "[resource object identifier](https://jsonapi.org/format/#document-resource-object-identification)" type: type: string description: "[resource object type](https://jsonapi.org/format/#document-resource-object-identification)" parameters: include: name: include in: query description: "[list of included related resources](https://jsonapi.org/format/#fetching-includes)" required: false style: form schema: type: string sort: name: sort in: query description: "[fields to sort by](https://jsonapi.org/format/#fetching-sorting)" required: false style: form schema: type: string pageSize: name: "page[size]" in: query description: size of page for paginated results required: false schema: type: integer format: int32 pageNumber: name: "page[number]" in: query description: page number of results required: false schema: type: integer format: int32 pageLimit: name: "page[limit]" in: query description: limit for this page of paginated results required: false schema: type: integer format: int32 pageOffset: name: "page[offset]" in: query description: collection items offset for paginated results required: false schema: type: integer format: int32 # unable to properly represent fields and filters? swagger-edit appears to not implement this correctly. fields: name: fields in: query description: "sparse fieldsets: `fields[TYPE]=field1,field2,...`" required: false style: deepObject schema: type: string filter: name: filter in: query description: "filter[NAME]=value(s)" required: false style: deepObject schema: type: string