In RAML one can specify the bodies of requests / responses by including a JSON Schema:
#%RAML 1.0
title: My API
version: v1
baseUri: http://example.com
mediaType:
- application/json
types:
Entity: !include schema.json#definitions/Entity
PostEntity: !include schema.json#definitions/PostEntity
/entities:
post:
body:
type: PostEntity
responses:
201:
body:
type: Entity
I’d like to conform my API to the JSON-API spec. However, I am not sure how to create my schema.json
to describe the Entity
and PostEntity
bodies. Is there a way to reuse the JSON-API Schema and only specialize the data models (I’m thinking about the resource attributes
in particular) or should I rewrite my schema from scratch to specify my data models and try conform to JSON-API ? If so, is there a way to test the conformance of my own schema, apart from testing payloads from my own schema against the JSON-API schema ?
I failed to find a good RAML (or API Blueprint or OpenAPI) + JSON-API workflow online. How and where do people usually define JSON-API models (payloads) ?
Turns out that this seems to work.
In this schema I’m defining a success
response Intenty
that has a fixed type
and a required myModelAttribute
attribute:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "My API Schema",
"id": "http://example.com/schema.json",
"definitions": {
"Entity": {
"allOf": [
{"$ref": "http://jsonapi.org/schema#/definitions/success"}
],
"properties": {
"data": {
"allOf": [{"$ref": "http://jsonapi.org/schema#/definitions/resource"}],
"required": ["attributes"],
"properties": {
"type": {
"type": "string",
"pattern": "Entity"
},
"attributes": {
"type": "object",
"required": ["myModelAttribute"],
"properties": {
"myModelAttribute": {
"type": "string",
}
}
}
}
}
}
}
},
"anyOf": [{"$ref": "#/definitions/Entity"}]
}
The next JSON is both valid against the schema above and JSON-API:
{
"data": {
"type": "Entity",
"id": "1",
"attributes": {
"myModelAttribute": "It works",
"This": "is still a valid JSON-API payload",
},
"relationships": {
"author": {
"data": {"id": "42", "type": "people"}
}
}
},
"included": [
{
"type": "people",
"id": "42",
"attributes": {
"name": "John",
"age": 80,
"gender": "male"
}
}
]
}
Definitely not the nicest way to to describe models, but at least it seems that I can work from a single source of truth for the API bodies…
Unfortunately, this only works in the very simplest of interactions with a {json:api} service. Any use of the includes or fields parameters will render this invalid.
I guess you could create a coupling between a field in your service and its representations as serialized, and return a link to the aggregate schema in metadata. However, I’m not sure how you would create a static schema which could handle the dynamism of {json:api} correctly.