Reputation: 1609
I want to describe the JSON my API will return using JSON Schema, referencing the schemas in my OpenAPI configuration file.
I will need to have a different schema for each API method. Let’s say I support GET /people
and GET /people/{id}
. I know how to define the schema of a "person" once and reference it in both /people
and /people/{id}
using $ref
.
[EDIT: See a (hopefully) clearer example at the end of the post]
What I don’t get is how to define and reuse the structure of my response, that is:
{
"success": true,
"result" : [results]
}
or
{
"success": false,
"message": [string]
}
Using anyOf
(both for the success/error format check, and for the results, referencing various schemas (people-multi.json
, people-single.json
), I can define a "root schema" api-response.json
, and I can check the general validity of the JSON response, but it doesn’t allow me to check that the /people
call returns an array of people and not a single person, for instance.
How can I define an api-method-people.json
that would include the general structure of the response (from an external schema of course, to keep it DRY) and inject another schema in result
?
I have two JSON schemas describing the response format of my two API methods: method-1.json
and method-2.json
.
I could define them like this (not a schema here, I’m too lazy):
method-1.json
:
{
success: (boolean),
result: { id: (integer), name: (string) }
}
method-2.json
:
{
success: (boolean),
result: [ (integer), (integer), ... ]
}
But I don’t want to repeat the structure (first level of the JSON), so I want to extract it in a response-base.json
that would be somehow (?) referenced in both method-1.json
and method-2.json
, instead of defining the success and result properties for every method.
In short, I guess I want some kind of composition or inheritance, as opposed to inclusion (permitted by $ref
).
Upvotes: 2
Views: 649
Reputation: 1609
So JSON Schema doesn’t allow this kind of composition, at least in a simple way or before draft 2019-09 (thanks @Relequestual!).
However, I managed to make it work in my case. I first separated the two main cases ("result" vs. "error") in two base schemas api-result.json
and api-error.json
. (If I want to return an error, I just point to the api-error.json
schema.)
In the case of a proper API result, I define a schema for a given operation using allOf
and $ref
to extend the base result schema, and then redefine the result
property:
{
"$schema: "…",
"$id": "…/api-result-get-people.json",
"allOf": [{ "$ref": "api-result.json" }],
"properties": {
"result": {
…
}
}
}
(Edit: I was previously using just $ref
at the top level, but it doesn’t seem to work)
This way I can point to this api-result-get-people.json
, and check the general structure (success
key with a value of true
, and a required result
key) as well as the specific form of the result for this "get people" API method.
Upvotes: 1