I am working on using Swagger to define my API's that are complying with the JSON-API spec.
It would be helpful if there was a way to wrapper the defined objects (and the parameters) with the JSON-API specific formatting. Ideally allowing the developers of the documentation to focus just on the contents of their custom content, and not have to duplicate the wrapper code.
Looking at JSON-API you are talking about having the top level root element, normally "data", and then the generic "type, id, attributes" elements that sit above each custom object.
Is that something that could be considered to be added to the spec?
Sure, thanks for bringing that up. Somewhat reminds me of a SOAP envelope (in concept, not meaning).
To help us better assess this, can you provide more details on what the structure would be like with JSON-API? It'd help rather than to dive into the whole spec and digging up the relevant details.
Also, if you're familiar with other API specifications that require something similar, it would help to have references to those as well.
The examples on http://jsonapi.org are pretty self-descriptive of this issue (and apply to HAL and potentially other message formats):
http://jsonapi.org/
I'm very interested in this area as well. I did a talk on JSON API last week, if you skip to slide 13 you might be able to get a quicker overview of the key features of JSON API than reading the whole spec (I hope!). However, I'm not sure if this idea can be implemented well without studying the spec in detail.
The other thing that would need to be considered is having a way to specify in the YAML file whether or not JSON API features such as pagination are supported by the server.
It would be really cool if we could specify a 'jsonapi' object directly under the location which could be automatically expanded by some sort of JSON API plugin to Swagger/OpenAPI. e.g:
paths:
/blog/posts:
jsonapi:
summary: "List of blog posts"
type: 'collection'
features:
pagination: true
data:
$ref: '#/definitions/BlogPost'
errors:
- $ref: '#/definitions/BlogPostError'
included:
- $ref: '#/definitions/BlogAuthor'
- $ref: '#/definitions/BlogComment'
This type of thing would abstract the YAML file from details such as headers and query parameters, which I think is great as it would allow API designers to focus on business logic and not the API implementation details - which is a great strength of JSON API.
Just brainstorming here:
JSON Schema for json-api is here: http://jsonapi.org/schema
We could define an allOf to inherit from that model:
allOf:
- $ref: 'Pet.yaml'
- $ref: 'http://jsonapi.org/schema'
However, if Pet.yaml redefined anything in the json-api schema, that would violate our REUSE guidelines, right? I'd imagine this is a big problem to resolve which reference's fields win when merging (as it's not parent, but an array of definitions.
Whether you reference definitions locally or remote, you can never override or change their definitions from the referring location. The definitions can only be used as-is.
I guess I'm just making sure we disquality allOf as a solution, if I'm thinking about this right.
Why would it violate the REUSE guidelines? JSON Schema allows you to define conflicting schema under allOf. It's useless, but it doesn't violate it. However, if we're looking to make things easier on users, we may want to allow for an easier construct (allOf is fairly horrible, imho). Since wrappers have been requested for other uses as well (pagination, for example), it doesn't have to be specific.
@webron the point is that if Pet.json and http://jsonapi.org/schema both define items, how are those fields merged? Clearly the intent is that Pet.json/items overrides http://jsonapi.org/schema/items, but there's really no way to determine that programatically.
Suffice it to say I still don't really understand what that clause in REUSE means.
...and yes, allOf is terrible. We should all be commenting on the v5 proposals en masse about oneOf, allOf, anyOf: https://github.com/json-schema/json-schema/wiki/v5-Proposals
allOf is does not merge objects. allOf means that a given value is validated against all-of the listed schema, one by one. So yeah, they can be conflicting and not make sense. Now, if items is defined in both, in such a way that you can write a value that validates against both, it's fine, but JSON Schema does not treat it as a merged schema.
Parent issues #579, #586
I'm having a discussion with Ron related to this in https://github.com/swagger-api/swagger-ui/issues/3073.
I'm not sure if this is wrapper is needed. Swagger is agnostic about the data exchange format, so you shouldn't have to specify anything other than consumes and produces. Other tools can use consumes and produces to determine what format to use to exchange data.
As an example, if we have to encode information about the data exchange format into the spec, then we are limited to only using that format for our paths. Instead, if we just use the consumes and produces arrays we can have multiple formats from the same path. This is useful when your app can use the same endpoint for multiple clients and return different formats based on the client. ( Spring can do this. )
We are using JSON-API with Spring and Ember. We generate controllers and models from the swagger specification. The Spring and Ember frameworks are then in charge of converting the models into JSON-API for sending over the wire.
By keeping the data exchange format out of the swagger spec you keep it flexible and agnostic.
Something is needed. It's horrible trying to specify anything using inheritance because of the brokenness of allOf. I hope that can be fixed in JSON-Schema, but in the meantime, a useful method here would be appreciated.
Most helpful comment
Something is needed. It's horrible trying to specify anything using inheritance because of the brokenness of
allOf. I hope that can be fixed in JSON-Schema, but in the meantime, a useful method here would be appreciated.