Open wycats opened 6 years ago
Other interesting features:
photoURL(width: 100, height: 100)
)In my mind, a schema spec is the high-order bit here. I think a large piece of what people like about GraphQL is the tooling like GraphiQL that's enabled by automated schema discovery.
While there is plenty of prior art in open specs for schema, I think there's a clear benefit to using JSON:API itself to discover/manipulate schema. That's the path I've taken in https://github.com/cardstack/cardstack, and it has gone well. I would be very happy to roll those learnings into a more careful/generalized specification effort.
When I say "use JSON:API to discover/maniuplate schema" I mean that you can have JSON:API resources like "content-type" and "field" and relationships between them, and what falls out is that you can leverage the same tooling that manipulates your data to manipulate your schema.
The introspection can give tremendous capabilities. For instance one thing that I wish I could have is the ability of providing the links (and hypermedia in general) through introspection, outside the body, only to clients that really need it and ask for it.
In any case, with good introspection capabilities you can build endless tools, I am big fan of it as I think it blends together the best of hypermedia-based APIs and RPC.
However introspection capabilities by itself is quite beefy. We need to specify what kind of things we would like to make available through it and possibly break it down to small isolated features so that we maximize reusability. For instance, for varicose data types and links, instead of reinventing the wheel maybe reuse (and contribute) to json (hyper) schema.
For instance one thing that I wish I could have is the ability of providing the links (and hypermedia in general) through introspection, outside the body, only to clients that really need it and ask for it.
JSON Hyper-Schema! (oh, I see you mentioned it- thanks, @vasilakisfil !)
Hyper-Schema is intended to facilitate content negotiation with media type parameters, and we're also looking at the Prefer
header as media type parameters have some challenges (notably that you're not technically supposed to use parameters not defined by the media type itself, and application/json
is unlikely to define them, although JSON API's media type could.
in our implementation of JSON:API we also have a discovery implemented in JSON:API: https://github.com/crnk-project/crnk-framework/tree/master/crnk-meta/src/main/java/io/crnk/meta/model. Has been helpful in many occasions. It is not strictly used for JSONAPI/JSON-only, so it is too elaborate in some areas, while in others it is also not yet complete (like validation topics).
The vague "here is a link which is just a URL to something and nobody knows what it does and we dont recommend HEAD or OPTIONS or provide any other metadata" approach that many RESTy HATEOAS systems take means introspection (browsing about the API) is tough to standardize.
Of course GraphQL can do this, but that's just down to them picking a single format, and "endpoint based" APIs have multiple. For example, Siren has multiple browsers.
If JSON API was recommending folks used JSON HyperSchema, or made other recommendations on how to HATEOAS beyond "here is a URL figure it out", then introspection would be a lot easier, and more standard.
JSONata seems to be a good and simple alternative to querying JSON data. We can take some ideas from it.
In my mind, a schema spec is the high-order bit here. I think a large piece of what people like about GraphQL is the tooling like GraphiQL that's enabled by automated schema discovery.
💯
Schema support is also one of the things we've been wanting in the Drupal implementation: https://www.drupal.org/project/jsonapi/issues/2822768
@wimleers yes but in order to get automatic discovery and tooling, we need to "stanardize" somehow how a generic client can fetch this schema.
Obviously.
If JSON Schema (hyper or otherwise) was the official suggestion, then that’s standardised already:
Link: <http://foo/bar.json>; rel=describedby
@philsturgeon JSON Hyper-Schema seems like it supports describing individual resources well. But, I’m not seeing anything in the spec that mentions how it would support auto-discovery of all the resources an API exposes. Am I just missing it or are there suggestions for how this might be presented?
@jaredcnance you would start with an entry point resource (which might be an empty string or empty JSON object for the actual resource payload), and the schema for that would have links to all directly accessible resources in the API. Some of those might be templates that require client input to resolve, e.g. jumping straight to a single element of a collection by supplying its id to plug into the URI Template in the link.
If there are any resources that are not directly accessible, which would happen if you decide that clients must always go first to a collection and then look up individual elements of the collection, then you would discover those resources as you follow the entry point links to the directly accessible resources.
@handrews are you aware of any general implementations of this (JSON:API or not)? I would like to explore this idea bit further.
I'm aware of one JavaScript implementation of Hyper-Schema draft-07: https://github.com/mokkabonna/json-hyper-schema which (based on the checklist on the README) is pretty close to complete.
As far as an API with an entry point resource using Hyper-Schema as I described, I'm not aware of one off the top of my head, but that's the approach that I wrote into the spec as an example, so I'm hoping that people will try it :-)
There's an encouraging amount of interest in draft-07 as a runtime system, while draft-04 (the last version that anyone really implemented at all) was mostly just used to generate documentation as far as I can tell).
From my experience of creating a JSON:API hypermedia API for movietickets.com for the past 3 years and having our website/mobile apps and external companies integrate with our production API I would say the following are the top 3 deficiencies JSON:API has compared to GraphQL in order of importance IMHO:
Filter Standard. I wish JSON:API had a standard for the filter=?
query parameter. The vast majority of the use cases for our and I imagine almost all REST API's is the readonly/idempotent GET
operations where depending on the client scenario the client wants to filter to meet the requirements of some scenario. We had to come up with a proprietary filtering standard. For pragmatic purposes we adopted the OData 4 query specification which I talked about on the {json:api} discussion board 3 years ago. In the end I don't care what the filter standard is just that JSON:API has one but I am not going to hold my breath. One of GraphQL greatest strengths is the query feature of the specification.
Sideposting Standard. The JSON:API constraint of creating/updating 1 resource at a time is too arduous and non performant. For example the creating of order and order items in 1 POST call was a real scenario we needed/wanted and had to address. The workaround of creating some "wrapper" types was a non-starter as suggested by some, especially as the heterogeneous design of a JSON:API document was such a natural (ergonomically) way to support sideposting. Therefore we basically allowed side-posting but had to document this was non-standard JSON:API with our rationale to clients of the API.
Schema Standard. Everybody has pretty much picked this one and I 100% agree. Having a schema/introspection features in JSON:API would be a beautiful thing and I mean a beautiful thing. But this is NOT number 1 because as much as this would be beautiful not having a schema does not impede clients from integrating to the API after developers discover and play around with the API in a sandbox environment supplemented by documentation. Therfore I consider a schema standard a desirable want but not a need. But in IMHO, NOT having filter and sideposting standards are/were major impediments to the development and adoption of our JSON:API compliant hypermedia API that had to be overcome with non JSON:API ways because they simply don't/didn't exist (as of yet) - for us they were absolute needs.
Just my two cents...
@scott-mcdonald regarding "sideposting", that's not a term I've heard before but it sounds like it at least includes bulk operations on collections. I've found that HTTP PATCH using application/json-patch+json
(RFC 6902 JSON Patch) as the request media type is very useful for bulk operations. You can, for instance, append, insert, remove, or re-order array elements with it. And you can PATCH on a filtered collection to simplify the operation in many cases. That makes the process more or less orthogonal to JSON:API, which may or may not be a benefit depending on how you look at it.
For bulk operations see #1254
@handrews "Sideposting" is/was being discussed here in #1197 for your edification. "Operations" which may or may not deprecate "sideposting" is being discussed in #1254.
First off, +1 on the schema support; that's very much needed.
But I'd push back on trying to support the rest of the features listed; why reinvent that wheel? I think jsonapi and graphql could really help each other actually. GraphQL works best with lean servers, who delegate all the real data fetching to a service; and leverage the data loaders for optimization. If jsonapi had a schema, it could be the perfect data access layer for a graphql server.
It's the deterministic resource urls that make json-api perfect for a data layer with heavy caching; sideloading and more complex queries only make resources urls less deterministic.
regarding the filter standard: I think it probably was a good decision to have filtering not within the main specification but as recommendationto maintain flexibility over the data store in use. But already a much more elaborate recommendation would be great to see. The current recommendation covers only the very basics. That new recommendation could be implemented as profile (see https://github.com/json-api/json-api/pull/1268) to signal clients support for it.
also agree that having schema support in place would be great to see. In that regard it would also be worthwhile to tackle the generation of client stubs (like Typescript, Swift, etc.). Not sure whether OpenAPI can help with that or not.
maybe a ticket could be created for those two? both as candidates for JSON:API 1.2 to maybe get 1.1 out in the not-to-distant future.
next to GraphQL also gRPC might be a source of inspiration.
also agree that having schema support in place would be great to see. In that regard it would also be worthwhile to tackle the generation of client stubs (like Typescript, Swift, etc.). Not sure whether OpenAPI can help with that or not.
There are a lot of tools for generating code for JSON Schema, whether the OpenAPI version of it or otherwise. Also, OpenAPI has been adding experimental support for regular JSON Schema (including hyper-schema if desired) in addition to their own weird dialect of it.
Finally, we (the JSON Schema project) are working towards increased support for code generation, which is one reason why we've been working with OpenAPI to get them on standard JSON Schema so they can take advantage of that whenever it happens (it will be post-draft-08).
created #1281 maybe to put the schema discussions in a dedicated ticket. JSON Schema would looks good to me, but have not yet followed it or OpenAPI closely. Interesting would also be how to make JSON Schema or something else queryable from a JSON API endpoint. Would be great to be able to lookup and search for those with JSON:API and retrieving the result in a JSON:API document. We have application with up to 1000+ resource types served by a single endpoint where fetching the entire thing becomes impartical and the sorting/filtering/paging, etc. is higly desirable. The other thing might be at some point in the future a DSL to have a more compact representation of JSON Schema similar to the DSL of GraphQL maybe.
I also agree that deep querying, schemas, and maybe introspection are the biggest items here. Standardized mutations would be very nice too, but we technically already do have an RPC escape hatch:
POST /myArbitraryRPCMutation
{
"data": {
"type": "mutations",
"meta": { /* whatever data my operation needs. */ }
}
}
Is there any work being done in the introspection side of things?
Is there any work being done in the introspection side of things?
describedby
has been added to v1.1 Link Object
Is there any work being done in the introspection side of things?
describedby
has been added to v1.1 Link Object
But that is to be used within a given resource, right? Is there anything like an instrospection query in the 1.1 spec?
Thanks.
In principle, JSON:API describes a very similar data and querying model to GraphQL.
But there are a number of areas where JSON:API is behind. In most cases, there has been some activity on this repo to try to address it, but not much recent traction:
Not all of these necessarily need to be in the base spec; some could be official recommendations or part of a profile designed for better toolability. The base spec would then become a basis for tools operating against the protocol, while the enhanced protocol would be the basis for zero-config client-side ORM-like tools.
However we do it, we have a strong need to improve deficiencies of JSON:API relative to GraphQL, and I think that we should focus some energy on closing those gaps.
I'm opening this thread to collect feedback from the community about prioritization of features on this list (which features would most help you as a GraphQL user) as well as to collect other use-cases that make JSON:API seem inferior to GraphQL that I've missed in my initial pass.
For a more free-wheeling conversation, I suggest http://discuss.jsonapi.org 😄
Please also feel free to link to other issues in this repository, and I'll link them up in the list above.