http://jsonapi.org/format/#crud
Problem/Motivation
While working on #2931785: The path for JSON API to core, I think we overlooked one very important thing wrt spec compliance. The fact that the JSON API module for Drupal incorporates two spec extensions:
- Fancy filters: https://gist.github.com/e0ipso/efcc4e96ca2aed58e32948e4f70c2460
- Partial success: https://gist.github.com/e0ipso/732712c3e573a6af1d83b25b9f0269c8
… yet we support Accept: application/vnd.api+json and Content-Type: application/vnd.api+json. Which signifies we're implementing the base spec. Additionally, we're not even mentioning in jsonapi.api.php that this module implements more than just the base spec!
http://jsonapi.org/format/#content-negotiation says:
Content Negotiation
Client Responsibilities
Clients MUST send all JSON API data in request documents with the header
Content-Type: application/vnd.api+jsonwithout any media type parameters.Clients that include the JSON API media type in their
Acceptheader MUST
specify the media type there at least once without any media type parameters.Clients MUST ignore any parameters for the
application/vnd.api+json
media type received in theContent-Typeheader of response documents.Server Responsibilities
Servers MUST send all JSON API data in response documents with the header
Content-Type: application/vnd.api+jsonwithout any media type parameters.Servers MUST respond with a
415 Unsupported Media Typestatus code if
a request specifies the headerContent-Type: application/vnd.api+json
with any media type parameters.Servers MUST respond with a
406 Not Acceptablestatus code if a
request’sAcceptheader contains the JSON API media type and all instances
of that media type are modified with media type parameters.Note: The content negotiation requirements exist to allow future versions
of this specification to use media type parameters for extension negotiation
and versioning.
… and sadly, JSON API's extension system was reverted. http://jsonapi.org/extensions/ currently says An extension system is currently under development […]
… on May 21, 2015.
In https://github.com/json-api/json-api/issues/614, Roy Fielding (of REST fame) is quoted to have written that media type negotiation like vnd.api+json is meaningless. He clarified his statement at https://github.com/json-api/json-api/issues/614#issuecomment-101741478. That issue spawned https://github.com/json-api/json-api/pull/650, which tried to improve things, but it was considered "too late before the imminent 1.0 release". Then, ironically, it is https://github.com/json-api/json-api/pull/660, which is mentioned nor linked in neither of the two issues above (614 an 650), and it simply removed the concept of/support for extensibility altogether. This was May 21, 2015.
It was worked on a bit in November 2015, in https://github.com/json-api/json-api/issues/915. Again in December 2015, in https://github.com/json-api/json-api/pull/957. And then again in https://github.com/json-api/json-api/pull/1195, in July 2017. And finally, https://github.com/json-api/json-api/issues/1207 in August 2017.
https://github.com/json-api/json-api/issues/1207 is the latest and greatest, confirmed by spec author dgeb at https://github.com/orbitjs/orbit/issues/479#issuecomment-358654119 on Jan 18, 2018. but it still hasn't actually gone anywhere — there's still nothing spec implementers can actually do …
Finally, note that http://jsonapi.org/format/#content-negotiation (quoted in full above) says the server must send an error response if any media type parameters are specified!
Proposed resolution
- Update
jsonapi.api.phpto state that the JSON API module implements the base spec + 2 extensions - Figure out how to communicate in our HTTP responses that it's the base spec + 2 extensions … even though the JSON API spec literally forbids it, and there's a whole string of GitHub issues: 614, 650, 660, 915, 957, 1207.
Remaining tasks
Discuss!
User interface changes
TBD
API changes
TBD
Data model changes
TBD
| Comment | File | Size | Author |
|---|---|---|---|
| #49 | 2955020-49.patch | 72.26 KB | wim leers |
| #49 | interdiff.txt | 589 bytes | wim leers |
| #47 | 2955020-47.patch | 71.98 KB | wim leers |
| #47 | interdiff.txt | 1.48 KB | wim leers |
| #44 | interdiff.txt | 7.1 KB | wim leers |
Comments
Comment #2
effulgentsia commentedDo we need Partial Success in jsonapi in Drupal core? What's the use case for it? Could it be moved to
jsonapi_extrasorjsonapi_partial_success? That doesn't entirely address this issue, but I'm just trying to wrap my head around the scope of what's needed in core.Comment #3
e0ipso@effulgentsia the case for partial success is for improved DX. Before the extension we had bug reports opened regularly about missing entities from collections (because they had failed somehow due to access denied or whatever), and missing fields that failed. Having an error in one of the items in the collection should not imply failing the whole request, but we still want comprehensive errors explaining what went wrong in the entities (or fields) that should have been there.
After the extension, and its documentation, have been available no more issues about that have appeared which I take as a good sign.
Comment #4
gabesulliceFrom my perspective, partial success seems like something we can do conventionally without negotiating it as an extension because we're free to put information in the
metamember at will.@e0ipso, I completely agree that is has been a boon for DX reasons, but I'm not sure that we want to say that it's a necessary extension.
I believe the use case is primarily because of how we handle access control on collection routes. We check
$entity->access('view')on every resource. In many cases, users were requesting/jsonapi/node/foospecifying apage[limit]of 50, but then receiving < 50 resources. Their most common "error" was not filtering bystatus === 1. To address this, whenever access is denied to a resource, we make a note of it by putting an error object undermeta.errors.I don't think this would be possible. It would be really hard to pass off this information to another module in all the places where it comes up.
That said, I'm generally concerned that treating every omitted entity for access reasons as an "error" is the wrong approach from a technical perspective. Omitting inaccessible resources should be considered "normal" behavior not an error because including them would be "unsuccessful" on our part. We would have failed at providing access control appropriately.
From that perspective, the DX win is simply communicating that "entities were removed for access reasons," not in the extension itself.
We could communicate that in a number of different ways.
Saying that partial success is in extension makes me think it's negotiable, i.e., that by not including the extension, errors would not be serialized in the response. This would be akin to "development vs. production mode."
Comment #5
e0ipsoTo be clear, I'm using extension not in the sense of negotiable plugins but in the sense that we are going further than the base spec and describing more of the API's behavior. Hence extending the specification document with our own rules. Both "extensions" are not negotiable. This is the main reason why we are not requiring the extension key in the Accept request header, nor responding with the extensions in use in the Content-Type response header.
In summary, I firmly believe that both fancy filters and partial success should remain as part of the module, even after an eventual core inclusion. I'm open to call them something different to extension given that 1) the extension system is in the limbo in JSON API spec and 2) they are cornerstones of our implementation and are non-negotiable.
Comment #6
gabesullice+1 to keeping them for core inclusion.
This is why I want to be really careful about how we treat partial success. Let's not tie ourselves to a specification WRT to surfacing errors, I think we need to test and solidify that a bit more. I think partial success can be a "convention" for now.
I do think Fancy Filters are an extension that should be negotiated between client/server.
So, @e0ipso, I think we agree more than we think, as usual. I don't think we want to put JSON API in core and require that developers download a contrib module to do filtering or have good DX. That's non-negotiable :)
Comment #7
wim leersWell, the spec also does not allow us to specify extensions in the request/response headers anyway, because an extension mechanism has not yet been specified!
Why haven't I thought of this? :D 👌
Comment #8
wim leersOops, cross-posted with #6.
Agreed that they're important to keep for the wonderful JSON API DX.
I won't say no to better test coverage for this either. What parts of it do you feel are not solid enough yet? My impression is that the majority of it is already stable?
This is honestly the bit I'm torn on the most. On the one hand I agree, because Partial Success merely uses
meta, which is specifically for application-specific implementations, whereasFancy Filtersis much more fundamental.On the other hand, the JSON API spec — despite being quite great — is utter garbage when it comes to filtering. http://jsonapi.org/format/#fetching-filtering says this:
That's literally all the JSON API spec has to say about it. Obviously this makes it impossible to have multiple interoperable implementations!
This is where I'm torn: every JSON API implementation must come up with its own decisions/design/convention/"extension" for filtering, because otherwise it's impossible to do any filtering.
Given this, the best we can do AFAICT is:
jsonapi.api.phpand explain the rationale.Thoughts?
Comment #9
gabesulliceError handling is not handled consistently across routes. It's not clear to me that we have a policy for what keys we use in our error objects. Some errors are not surface-able at all. I linked to a comment where I catalogued issues related to errors, but I'll reproduce it here:
Sorry, this is a harsh and very narrow perspective on filtering. Filtering strategies should never be part of the base spec and should always be extension-based. Full stop. There can be entirely different, yet completely valid filtering strategies for all kinds of different use-cases all with varying levels complexity and tradeoffs. Specifying a filtering strategy in the spec would be entirely overbearing and make it far too rigid to be useful.
As I was saying above, fancy filtering is entirely severable and negotiable. The filtering strategy is really application dependent.
We've implemented what I think is a great default, but it has its limitations and is a pretty opinionated approach. I think it's essential that we make fancy filters a negotiable piece.
Re: Partial Success, I tried to make a case in #6 that we do not want to document it as an extension, but a less formal convention (for now).
I've started to make some really promising progress in the last week with the JSON API editors about coming up with a negotiation strategy so that we will be forward-compatible with JSON API 1.1 in Github #1207.
Let's postpone a practical decision on how we should indicate the fancy filtering extension until that is resolved/stalled.
Comment #10
e0ipsoFrom #9:
I don't agree that we need to have a negotiation layer for this. I wonder why you think it's essential. What are the limitations you are thinking about?
We could look into refactoring the query builder part (again) to make it a swappable service, but I am convinced that this is not an easy task. Even if this was already done we'd face maintenance on a complex, unbounded and abstract URL to Entity Query layer. I don't like that idea.
As for:
I completely agree. The spec is rightfully agnostic about the types of queries different apps can do. Where we start to drift apart is that our application is Drupal, and our queries are the ones supported by Entity Query. We can even extend fancy filters further, to add support aggregation (as we've talked in Slack several times). So I think that one filtering strategy is good. I'll go further and say that it's recommendable to avoid duplicate code paths for the same feature.
#8++ I like both suggestions. I'd like to have the extensions moved to drupal.org eventually, so they belong to the community and not to my gist collection.
Comment #11
wim leersDiscussion is still ongoing in https://github.com/json-api/json-api/issues/1207. Hopefully that will reach consensus soon, then we won't be forced to invent our own approach anymore.
Comment #12
e0ipso@Wim Leers we've been about to reach consensus before in this regard and it got stale. But I agree that ideally we'd want to implement the extension system.
Do we want to set some sort of timeout to wait for consensus?
I still think that we must have fancy filters by default (even if no profile is negotiated), and then let it be replaced by whatever if it comes the time via the extension system. That means that we don't need to support profile negotiation for now. Note that partial success is also a non-negotiable extension that is always on.
Comment #13
wim leersGood idea. Shall we say April 15, i.e. just after DrupalCon?
From a DX/consumer developer POV I wholeheartedly agree. Fancy filters are a super powerful feature.
Comment #14
e0ipso#13 great to both accounts. If no one disagrees we'll time out after April 15.
Comment #15
wim leersJust cross-posted this date to https://github.com/json-api/json-api/issues/1207#issuecomment-378654093.
Comment #16
e0ipsoThis is the actual proposal: https://github.com/json-api/json-api/pull/1268
Comment #17
wim leersEarlier today, I posted a review of the actual proposal/PR: https://github.com/json-api/json-api/pull/1268#issuecomment-394334144. AFAICT details still need to be refined, but in broad strokes, I think the proposal A) works, B) can already be implemented.
Taking this on.
Comment #18
wim leersPer:
I am reducing the scope to only Fancy Filters.
Comment #19
wim leersThis was simpler than I thought.
This will still need tests to verify that if a request lists profiles that are not supported result in a 400.
Next:
Comment #20
wim leersAlthough, don't we also need to have profiles for our sorting and pagination? This is what @e0ipso raised in #2812923-2: [FEATURE] Implement extension system, 1.5 year ago.
But http://jsonapi.org/format/#fetching-sorting is actually sufficiently prescriptive for basic usage, and hence is actually usable. The same is true for http://jsonapi.org/format/#fetching-pagination. But http://jsonapi.org/format/#fetching-filtering is empty; it doesn't say anything except that
?filtershould be used for sorting; that's it!So … I'm a bit torn.
I think the right thing to do here is to indeed have a profile for sorting and pagination too.
Comment #21
wim leersTurning this into a . This is where all the discussion happened. Closing #2812923: [FEATURE] Implement extension system as a duplicate.
Comment #23
gabesulliceI think I disagree about a profile for
sortand I certainly disagree about a profile forpage.Why?
As you mentioned, the spec is already sufficient to describe our use of
sort, the only place where we've extended beyond the normative language of the spec is to follow the recommendation of using full-stop delimited field names for relationships (this is the only thing that is extension-worthy).As for pagination, I think the pagination language of the spec is very intentionally silent on filtering strategies and enforces the use of HATEOAS links for communicating pagination links. IOW, I think this that it's the server's prerogative to add/update/change the link templates for pagination links at will and a compliant client should use those links as provided. If we had documented this better from the start, I would have gone so far as to say that we should not even consider it a BC break to move to cursor-based pagination in 2.x without a BC-flag.
Our pagination docs enforce this pattern:
You can take notice that the only mention of "offset" in the docs is in the sample server response document.
Comment #24
wim leers#19 had some unexpected failures, because I didn't think to think certain tests locally. Fixing.
Comment #25
gabesulliceI'm not sure that this is the right application of the profile media type parameter in this context.
Fancy filtering changes nothing about the response document. So, if I'm reading the PR correctly, we should be advertising the fancy filter extension via the
jsonapi.profilesdocument member and requiring a client to specify the profile in the query parameter when filtering, but not providing it in every response header.The current approach would work for partial success because that dictates how the document should be interpreted, but not for fancy filters because it's about how a server should interpret a request's query.
Am I thinking about this correctly? Maybe I'm missing something.
Comment #26
wim leersTest coverage:
Note that this is a stricter reading of the spec. But that's fine. It makes things simpler for future maintenance/BC.
This turned out to be extraordinarily difficult because
\Symfony\Component\HttpFoundation\AcceptHeader::fromString()is broken; it parsesAccept: text/html;charset="UTF-8"as two separate media types… And the same for$acceptable_profiles = AcceptHeader::fromString('application/vnd.api+json;profile="https://www.drupal.org/jsonapi/profile/fancy_filters"'): this results in aapplication/vnd.api+jsonand ahttps://www.drupal.org/jsonapi/profile/fancy_filtersitem … 😭https://github.com/symfony/symfony/commit/6b601bd9a639ca141ebfcc3b6b91c2... created the current logic, and its test coverage leaves much to be desired. It looks like Symfony recently improved this in Symfony 4: https://github.com/symfony/symfony/commit/b435e80cae24e85d6e0e923ae932b2... (for https://github.com/symfony/symfony/pull/24699).
So, either way, it looks very unlikely that this will get fixed in the Symfony version that Drupal depends upon. This sadly means we'll need our own parsing. Fortunately, we can keep this to a minimum :)
Comment #27
wim leers#23:
This is exactly the doubt I was having.
That's what I thought, until I looked at https://www.drupal.org/docs/8/modules/json-api/collections-and-sorting … we apparently support not only a path/pointer to sort and a direction, but also a language (
langcode, see\Drupal\jsonapi\Query\Sort::LANGUAGE_KEY).Mostly agreed.
I disagree that it's only HATEOAS. Because our pagination strategy assigns a particular meaning to
page[offset]andpage[limit]. That's something a client may very well rely upon. Arguably,page[offset]is not an API, butpage[limit]is. Even thoughpage[offset]is only mentioned in the sample response document, that is still the only way a client can ensure they get 2 or 100 responses. Of course, if we say that the client is not allowed to specify a limit, aka that's not a supported API, then sure … but if that were the case, we should also have hardcodedpage[limit].Comment #28
wim leers#25:
You may be correct in a purely theoretical perspective. But there's only one explicit mention of that in https://github.com/json-api/json-api/pull/1268's current PR:
For example:
/jsonapi/user/uservs/jsonapi/user/user?filter[name]=Wimhave vastly different content.This makes for fairly large variations in
Content-Typeresponse header. When for example requesting individual resources, there is indeed little point in listing the Fancy Filters profile in the media type'sprofileparameter. But there's also no harm. And listing it always is simpler. Both in our implementation and our test coverage. But perhaps most importantly, it's also simpler when reverse proxies are involved; rather than needing to know the many possibleprofiles, they can just hardcode a particularContent-Type, because the Drupal JSON API module will always respond in the same way.And when thinking of the future, when the JSON API module gains support for additional profiles, old clients would continue to request the current set of profiles. Therefore caching the different variations becomes simpler.
Additionally, it's totally feasible for JSON API response documents to start to contain more links (cfr. HATEOAS); when Fancy Filters is supported, there are various links one could imagine (e.g. on a
user--userresource, links to filtered collections of all other resources for which the current user is the owner, e.g.{"links": {"owned-articles": "https://example.com/node/article?filter[uid]=18a503f7-5900-457b-a40c-49d4a3136e09).Comment #29
wim leersThis is only testing the simple case of accepting only a media type with unsupported profiles. We should also test two other cases:
Acceptvalues; one with unsupported profiles, one without profiles — which should then result in a 200Comment #30
wim leersAddressed #29.
Comment #31
wim leersAnd finally, the updates to the
jsonapitop-level document member! Lots of test expectations had to be updated, hence the size of this interdiff.Unfortunately there is something super weird going on with:
CommentTestEntityTestTestMediaTestTermTestFor some reason, they get all the
jsonapi.links.profilelinks twice! I have not been able to figure out how this happens. It'd be great if somebody else could take a stab at this.Comment #33
gabesullice#27: count me convinced. Let's have extensions for sort and page :)
#28
Given that the spec says:
I think (1) is the proper understanding of how a profile alters the document. A profile is about "assigning meaning" to the structure/syntax of the document and allowed query params, not about 0, 1 or 2 items being returned.
Consider this language:
^ Emphasis mine. It's the "to indicate that the profile has been applied" language that makes me think that we just want to add that media type profile when
?profile=https://www.drupal.org/jsonapi/profile/fancy_filtersis in the request URL.I'm not sure I fully understand this use case, can you expand on that point? (I'll admit I'm having a little bit of a pavlovian response to this line of reasoning, it's eerily similar to the
?_formatreasoning that's been a big pain point for us. I'll try to overcome that! :P)Finally, I don't see that we're handling: "servers applying profiles to a JSON API document MUST include a top-level links object with a profile key".You fixed this already!
Comment #34
wim leersDiscussed with @gabesullice, and we agreed this belongs in 2.x.
I'll continue working on this on Monday; this will be my top priority.
Comment #35
wim leers😅
Comment #36
wim leersI think #2864680: Spec Compliance: JSON API's schema disallows duplicate resource identifiers. EntityReferenceItems which reference the same entity must have an "arity" also amounts to a profile:
relationship_arity.Comment #37
wim leersThis patch should fix the failures in tests other than the 4 mentioned in #31.
#33:
I totally get where your'e coming from. But
That's not quite true either, because https://github.com/json-api/json-api/pull/1268 says
and its commit says:
So a profile can cover an aspect of a JSON API implementation that results in no alterations to JSON API documents whatsoever.
A. I think it's good that you're reading it as strictly as possible.
B. See above; some profiles don't have anything in the document, so following this logic they'd never appear in the
Content-Typeresponse hader!C. The spec says
MUSTin case the document is being altered compared to the base spec. The spec does not sayMUST NOTwhen the document is not being altered. And this is IMHO consciously: it allows a JSON API implementation to KISS, by always sending the sameContent-Typeresponse header if it does not have any optional/negotiable JSON API profiles.D. Certainly having the
profilequery parameter there is not a hard requirement to list profiles in theContent-Typeresponse header. That query parameter can be used to require a profile to be applied. But a profile can also be requested usingAccept. It's even allowed to respond to anAccept: application/vnd.api+jsonrequest with aContent-Type: application/vnd.api+json; profile="https://www.drupal.org/jsonapi/profile/fancy_filters https://www.drupal.org/jsonapi/profile/page_limit https://www.drupal.org/jsonapi/profile/sort_language"response; it's not required that a JSON API server makes every profile optional.That's why I added the following to
jsonapi.api.php:All of this is supported by the spec:
The combination of these choices allows our implementation to remain simple and maintainable. If everything becomes negotiable, then that is an enormous burden on us maintainers. We can still choose to support negotiable profiles in the future.
I interpreted your original remark as also meaning that when
?profile=https%3A%2F%2Fwww.drupal.org%2Fjsonapi%2Fprofile%2Ffancy_filtersis missing, we also should omit that profile from theContent-Typeresponse header. And I thought you meant that this should be true for every profile. Add to that the fact that you can also request a profile to be applied using theAcceptheader, and then you reach the point where there can be several variations of responses to the same URL, each with different combinations of profiles applied. Not only is this more complex, it also makes caching in a reverse proxy super hard, because that requires reverse proxies to normalize the values of theAcceptrequest header. To be able to normalize them, the reverse proxy needs to know about all the values that the application cares about. This is brittle and a nightmare to support.But now I suspect you were not at all suggesting to respect
Acceptheader based JSON API profile negotiation. You're only suggestionprofilequery parameter based JSON API profile negotiation. Is that correct?And I evensuspect that you meant this should only be applied to the Fancy Filters profile, because that is what defines our interpretation of the
filterquery parameter, and if that profile is not specified, then theoretically speaking our JSON API implementation is not supposed to know how to interpret it. Is that correct? (To this I say: it's fine to not specify this in the query parameter; it's fine for clients to know that this is the default filtering mechanism. That'd also prevent a pretty significant BC nightmare when updating to 2.x.)Comment #39
wim leersThe last one was the trickiest;
JsonApiDocumentTopLevelNormalizerhad to be modified in just the right spot.Comment #40
wim leersFixed CS violations.
Comment #43
wim leersComment #44
wim leersStill to be done:
profilequery parameter:Implemented all three, but test coverage is still necessary. I'd first like feedback on the general approach.
Comment #45
wim leersI believe #44 implements 100% of https://github.com/json-api/json-api/pull/1268 😀 🎉 🤞
Looking forward to feedback!
Comment #47
wim leersComment #49
wim leersComment #50
wim leers@gabesullice and I discussed this in detail last week, together with core committers @xjm, @webchick, @effulgentsia and @lauriii.
Until https://github.com/json-api/json-api/pull/1268 lands and JSON API spec version 1.1 is released, the JSON API module for Drupal would not possibly be able to implement this according to the spec, since the spec hasn't been finalized yet. This might be okay for a contrib module, but imagine what the consequences are for when JSON API is added to Drupal core: we'd end up with potentially our own fork of the spec. This is too big a risk.
It's better for now to let JSON API to work as it does: its primary addition is "fancy filters", and the spec already gives us the leeway to implement this as we see fit: http://jsonapi.org/format/#fetching-filtering.
Therefore, postponing this. Also removing this from #2931785: The path for JSON API to core.
Comment #51
wim leersJSON API maintainers just committed profile support to v1.1
https://github.com/json-api/json-api/commit/55cd721e55d4facec6e3242f2724...! See it at http://jsonapi.org/format/upcoming/#profiles.
The 1.1 version of the JSON API spec has not yet been released though. But this does mean this is up for debate again.
What do people think? Should we do this in 2.0? I'm inclined to say "yes" — I think the probability of this still changing is very low. Of course, we can only be 100% certain if this actually ships in a new JSON API spec version.
Comment #52
wim leersDiscussed with @gabesullice. He pointed out that we already postponed this to a 2.x minor release because it wouldn't break BC anyway. That's still true today.
Plus:
1.1 is still not released, so there's still a risk.
Hence, marking this postponed again, until there's an actual JSON API spec update released.
Comment #53
effulgentsia commentedHm, this is a tough one. On the one hand, I can see the logic for not including this in a tagged release of 2.x until after the spec is finalized. On the other hand, I think us implementing the spec and having real apps/sites in the wild using the implementation and reporting problems, if any, would be an extremely valuable way of validating the spec, and perhaps even having an opportunity to fix the spec (if necessary) prior to its release.
As a parallel, we began the HTML5 initiative in Drupal 8 core in 2011, even though the spec wasn't finalized as a W3C Recommendation until late 2014. It just so happened that Drupal 8.0 wasn't released until 2015, but we didn't know that would be the case in 2011. If 8.0 was ready in early 2014, we would have released it then, ahead of the HTML 5.0 final spec release. I realize it's a different situation though, in that browsers had already implemented the HTML5 spec draft, so we had pretty good confidence it wouldn't change much, whereas for json:api 1.1, we might be among the first implementors, so it might still be somewhat unstable.
Comment #54
wim leersThe difference is that HTML is declarative, and browsers interpret it. It won't require code changes on specific projects. Or, if browsers change, then everybody has to.
With JSON API, clients would need to be modified.
That, plus, Drupal 8 was still very far from being released, so any changes that would still need to happen would not impact actual production sites!
Comment #55
gabesulliceI think the next step if for us to begin drafting our profile specifications.
That will help us validate the profile concept and ensure that all the things that we want to have profiles for are actually permissible within the boundaries of this profile specification.
For example, I'd like to test that the way we handle relationship arity is actually something we can express as profile—all of the given examples are simply about contextualizing keys/values in a document, like how to interpret a timestamp.
WRT to end-user facing API changes, I think it's fine to postpone any of that.
None of our profiles are negotiable and the spec says we can apply profiles by default (we're already doing this, in a way). Clients won't need to request that our profiles be applied, so clients won't need to be updated. IOW, there's very little that we're supposed to actually do except document our profiles.
AFAICT, the only requirements we will eventually be forced to respect are these:
But of course, we can't do any of that until we actually have profiles written and publicized. And if I snapped my fingers and had that done, we could still postpone API changes because these requirements are additive changes that won't break BC.
As for publicizing our profiles, I've already reached out to the JSON API maintainers to figure out how we should expect to do that.
Comment #56
wim leersQuoting https://github.com/json-api/json-api/issues/600#issuecomment-429380085:
Comment #57
effulgentsia commentedI agree with that, and it's similar to what I was suggesting at the beginning of #53. #55 goes into a bit more detail on what that might entail for us. I still think it would be valuable for patches to be posted here (even if they're not committed until the spec is out of beta) that implement as closely as we can to the 1.1 spec, just to identify in the process of writing and reviewing those patches if there are any last-minute alterations that we want to propose to the spec.
Comment #58
wim leersAgreed. Now to find the time.
Comment #59
wim leersMy upstream comment I linked to in #56 triggered a public announcement: https://github.com/json-api/json-api/issues/600#issuecomment-430763592 + https://twitter.com/jsonapi/status/1052647059982077953 :)
Time to work on this, to help validate the spec.
Comment #60
wim leers#3020136: Author and register a JSON:API profile for resource versioning is doing this for #2992833: Add a version negotiation to revisionable resource types! 🎉
Comment #61
wim leersI'd like to see us move this forward again. Let's get a patch here that is green and does add the necessary profile metadata to our responses.
Comment #62
gabesulliceI too would like to see this move forward again. The JSON:API spec maintainers are getting a bit antsy because of the lack of adoption of v1.1. This would help.
However, I don't think this issue qualifies as a critical, moving it down to a major.
Comment #63
wim leersDrupal will not adopt 1.1 until 1.1 is finalized; it's too big a risk for Drupal otherwise.
But we could and should have green patches proving that it's working; that should give sufficient confirmation to the spec maintainers?
On the other hand: since we're now very early in the Drupal 8.8 cycle, we could commit this and revert before 8.8.0 if version 1.1 of the spec is not finalized before the 8.8.0 beta (per https://www.drupal.org/core/roadmap, the week of October 14, 2019). Would that work better for the spec maintainers? Nonetheless, that would still mean no significant real-world use, so it wouldn't be very different from just having a green patch.
Comment #64
effulgentsia commentedI think getting a working patch here is a good place to start. If that patch turns out to be large or complex, then we may want to come up with ideas for how to best support people in testing and reviewing it, especially if those tests and reviews are needed for the spec maintainers to feel confident about finalizing the spec. If the patch turns out to be relatively small and simple, then perhaps it can just remain here as a patch until the spec is finalized.
Comment #65
wim leersSounds good! Thanks for chiming in @effulgentsia 🙏
Comment #70
bradjones1As of Oct. 1 2020, spec v 1.1 is in RC3.
Also, worth noting that this will help unlock functionality in clients, e.g. Orbit.js.
Comment #71
bbralaI want to add here that if we have a definition I can probably get the filter implementation into (the very good) laravel-json-api package, which would be nice :)
Comment #73
bradjones1Some progress upstream! Since this is effectively blocked on json:api 1.1, I'm marking this PP. However, the json:api lead maintainer has committed to getting 1.1 out in June. Let's help him out with that and then we can start on this and the related #3279320: Implement extension link relation type for resource collection links on entrypoint which would be an extension.
Comment #74
bradjones1Adding tag for tracking json:api 1.1 related issues.
Comment #75
bradjones1Comment #78
bradjones1JSON:API 1.1 is out. Removing the PP.
Comment #79
bbralaWe need to revisit this with the implemented profiles and extentions in mind:
And the difference is basically defined here:
Comment #80
bbralaComment #81
bbralaComment #82
bbralaFancy filters: This would be an refinement of the
filterparameter, therfor a profile.Partial success: This is harder, is this an extention? If so this data could be added (while scoped by extention key) to the document. You could also say its an profile, it just adds some new information to another 'loosely defined' part of the document, therefor doesn't really rewrite the spec.