Skip to content

Proposal for v1.0 rc2 #341

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 54 commits into from
Feb 18, 2015
Merged

Proposal for v1.0 rc2 #341

merged 54 commits into from
Feb 18, 2015

Conversation

dgeb
Copy link
Member

@dgeb dgeb commented Feb 6, 2015

This represents a fairly thorough rewrite of JSON API by myself and @wycats. This rewrite is based upon feedback we've received and our experience building both client and server implementations of the spec. I regret that changes of this scope and magnitude are proposed in a single pull request, but this has been necessitated by the condensed time in which we had to work.

The overarching goal of this rewrite has been to bring rigor and simplicity to JSON API, transforming it from a loose set of guidelines to a specification that can be fully implemented to create compatible clients and servers. In general, SHOULDs have been minimized and replaced with MUSTs, and any MAYs that remain tend to be paired with MUSTs.

The current spec has been refactored into a base spec, rules for extending it (including official extensions for bulk and patch updates), as well as recommendations (e.g. for forming URLs) that are deemed beyond-the-scope of the spec.

Some of the major changes in the base specification include:

  • Rules for extending the spec with media type parameters have been defined.
  • Polymorphism is supported.
  • Every resource object MUST include both type and id members.
  • Attribute and association keys MUST be dasherized (e.g. "first-name"). [Note: no longer a requirement; this has been moved to the new Recommendations page]
  • Primary resources MUST now appear under the top-level "data" key.
  • Linked resources (in a compound document) MUST now appear in an array directly under the top-level "linked" key.
  • Top-level links relate to the primary data, including self. Support for URI templates in links has been removed.
  • Link objects within resources have been more fully described, and can now include self links, relationship URLs (for manipulating the relationship), related resource URLs (for fetching related resource objects), linkage to other objects in a compound document, and meta info.
  • Pagination links have been established and a page query param has been reserved. The spec remains agnostic about pagination strategies.
  • Filtering rules have been moved to the recommendations page, but the base spec reserves the filter query param.
  • Support for creating, updating, and deleting multiple resources in a single request has been moved to the Bulk extension.
  • JSON Patch support has been moved to the Patch extension.
  • URL rules have been moved to the new Recommendations page.
  • Response statuses have been further defined.

Please review and leave general feedback below. I hope we can merge this soon and handle specific concerns in more targeted issues.


Some relevant links to modified pages:

@tkellen
Copy link
Member

tkellen commented Feb 6, 2015

cc @bobholt

@aaronshaf
Copy link

Thank you for your work on this!

"Steve Klabnik",
"Dan Gebhardt"
]
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There appears to be a comma missing here.

@kurko
Copy link

kurko commented Feb 6, 2015

Sad Panda. I can see the benefits, but at the same time it means my team (backend+frontend web+mobile) either changes tons of endpoints or leaves JSONAPI entirely (at least for the time being). Nonetheless, I am +1 on this.

@gr0uch
Copy link
Contributor

gr0uch commented Feb 7, 2015

Looks like a good revision/rewrite of the spec, clarifies a lot of ambiguities. Though I have to say that to many who expected a slow moving spec that will be upgraded extensibly at the 1.0-rc phase, massive breaking changes is a disappointment. +1 though.

With regards to versioning I don't see any elaboration on this? How can we expect the application/vnd.api+json media type to be consistent with our expectations?

@bobholt
Copy link
Contributor

bobholt commented Feb 7, 2015

I'll probably give this a full read on Monday, but in general, positive on removing ambiguities and moving toward marking the spec as stable. Thanks for the heads-up, @tkellen.

@xogeny
Copy link

xogeny commented Feb 7, 2015

My interest in JSON-API comes from the fact that I think Siren, HAL and Collection+JSON are all very good first steps with respect to designing hypermedia APIs but I'm always on the lookout for new media types that help to improve on those.

Unfortunately, JSON-API takes a big step backwards (in my opinion) by making the design decision that entities MUST have an id but only MAY have a self URI. I feel this disregards best practices with respect to hypermedia APIs.

Now, to your credit a) you don't seem to claim that this is a hypermedia format anywhere on your web site (although I think it is implicit in the presence of links) so perhaps this isn't a fair comparison (although you yourselves make comparisons to HAL) and b) I strongly suspect that this is really a compromise design to try and maximize compatibility with existing conventions for APIs (e.g., Ruby on Rails). So, these seem to be explicit design decisions and not something you've overlooked.

You are, of course, free to make those decisions and I'm free to not like them. I was just hoping for something that didn't reinforce what I consider to be bad practices (at least when trying to move in the HATEOAS direction). Most people probably think I'm just being a RESTafarian, but the issue for me isn't really about RESTfulness but more about raising awareness of self-discoverable APIs where clients don't need to know/construct URLs for endpoints.

@ahx
Copy link

ahx commented Feb 7, 2015

Two questions, which i would probably have to answer to my colleagues, but i am not sure how:

  1. Are underscores allowed in attribute names? (Please?)
  2. Why the change from "href" to "resource" in link objects?

:hurtrealbad: ❤️
The rest of the changes will definitly hurt (like "type is required in all requests" or "id field must be in all responses and must be a string"), but make sense.
+1

@dgeb
Copy link
Member Author

dgeb commented Feb 7, 2015

@kevin-brown thanks for the correction - fixed!

@aaronshaf you're welcome - hope it meets your needs!

@kurko @daliwali As a maintainer of a couple implementations myself, I completely sympathize with your wishes to change the spec slowly and minimize breakages as we approach 1.0. As difficult as this massive set of changes might be to absorb, the goal is to stabilize the spec at 1.0 very soon and avoid such turbulence afterward. My view of the current (rc1) spec is that it's more of a "guidebook" with so much wiggle room that client and server implementations will rarely match up without customization. We've really tried to remove such ambiguities with this PR, and I'm hopeful from your +1s that you agree.

@bobholt looking forward to your feedback.

@xogeny I feel that JSON API has all the pieces in place to be a hypermedia format, but that full hypermedia support is definitely optional. Self links and richer relationship links would need to be required instead of optional, and it's a good question whether this is a bridge too far for many implementations. Perhaps we should consider a "hypermedia extension" that changes these MAYs to MUSTs?

@ahx thanks for your questions. As for our decision to go with dasherized attributes - we wanted to avoid requiring out-of-band knowledge to parse a response. One approach to this in the spec is to say that, for instance, a client MUST convert underscores to dashes (which provides some wiggle room for servers). We took a more direct approach by making the requirement on the server. Let's discuss further. Also, the change from href to resource was driven by the introduction of self links, and the possible confusion between the target of self vs. href.

Thanks to everyone so far for your comments and review. I know that this many changes isn't easy to process all at once and can be tough to swallow for those with current implementations. Trust me when I say it hasn't been easy for me either and I am very much looking forward to a stable 1.0.

@darkbaby123
Copy link

I also don't think dasherized attribute is required. I understand that you want people to parse the response to fit the model layer or other things. But it doesn't mean we need to choose a "hard to used directly" attribute format. It feels like increasing the parse difficulty to force people to do right thing. While it doesn't have to be.

@gr0uch
Copy link
Contributor

gr0uch commented Feb 7, 2015

hmm, also I disagree with the dasherized key names as well, seems unnecessary. I would be in favor of dropping any requirement on key naming.

@barelyknown
Copy link

Are you or @wycats able to provide any insight as to the role that json:api will play with Ember Data? If the plan is for json:api to be supported as the default serializer/adapter format, the changes seem totally worth it (even if they are large and a bit of a pain to deal with for existing implementations).

@jacqueline-homan
Copy link

@dgeb and @wycats : I've been knee-deep in a MAJOR F# project that I've pretty much had to do 90% of the work on all by myself so far where once the database end is completely set up, will be transformed into a web app. It is a data-heavy app (think: Intellius on steroids but for providing dossiers on NGO's instead of individuals). As of right now, I am writing data to a JSON file. How well will the JSON API play with an F# app? Or at this stage, should I consider changing from writing to JSON to XML and then build a custom F# parser for the XML as part of the app?

@wycats
Copy link
Contributor

wycats commented Feb 7, 2015

@barelyknown the plan is for Ember Data to have first class support for JSON API. Feedback from Ember Data was a big input into this round of changes.

@barelyknown
Copy link

@wycats As long as that's the case, I'm all for it. Hopefully we can finalize v1 soon.

@csantero
Copy link
Contributor

csantero commented Feb 7, 2015

@jacqueline-homan Check out JSONAPI.NET.

@mitchlloyd
Copy link
Contributor

@dgeb Would it be possible to add an example to the pagination section of the document? I read through this section several times and I'm still having trouble visualizing how this is supposed to work. I think an example here would be really helpful.

I'm very excited about these changes. Thank you for your hard work.

@jerel
Copy link
Contributor

jerel commented Feb 7, 2015

Why switch to dasherized key names when that's not a valid format for variables on server or client? Curious what the reason is.

Otherwise, I'm very happy to have this stablize on this small set of requirements so we have a target to aim for.

@johnnyoshika
Copy link

Dasherized attribute name would be really unfortunate, and would make it cumbersome to consume the API using JavaScript.

Resource URLs **SHOULD** only be specified by the server and therefore are
typically only included in response documents.
Attribute names **MUST** consist of only lower case alphanumeric characters
and dashes (U+002D: HYPHEN-MINUS, "-"). Attribute names **MUST NOT** begin
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As for our decision to go with dasherized attributes - we wanted to avoid requiring out-of-band knowledge to parse a response @dgeb

Out-of-band knowledge? How's dashes better? In 9 years of work, I've never seen an API using dashes, not even docs mentioning it. I really don't understand this argument. Could you elaborate?

@dgeb
Copy link
Member Author

dgeb commented Feb 8, 2015

I discussed with @wycats and we've agreed to move attribute and association naming requirements out of the base spec and into the new Recommendations page. I'll elaborate further once I've updated this PR.

@sandstrom
Copy link
Contributor

This looks great! (my only comment is that dasherized attribute names feels suboptimal, but it seems like they're already gone)

@dgeb
Copy link
Member Author

dgeb commented Feb 8, 2015

I've just amended this PR with a commit to move field naming requirements to the new Recommendations page. We're now treating all names (including those for attributes, associations, and resource types) and URLs as opaque to the spec. This keeps the spec leaner and more flexible.

The naming rules did mitigate a potential conflict with default sort order, in which names couldn’t begin with a -. As an alternative, the concept of a default order is removed; sort order must now be explicitly specified with a + or - prefix. For instance, GET /posts?sort=-created,+title.

In hindsight, I think the naming requirement did cross lines, so thanks to everyone for pushing back on it.

P.S. We can continue to discuss recommendations well after the spec hits 1.0, so let's do so in more focused issues / PRs after this is merged.

@SphtKr
Copy link
Contributor

SphtKr commented Feb 9, 2015

👍 Thrilled that id is required again!

@dgeb Questions:

  • The Sparse Fieldsets section doesn't have the same "A server MAY choose to support..." caveat that the Inclusion, Sorting, and Pagination sections do. I imagine this is an omission, but just in case, are servers/endpoints required to support sparse fieldsets?
  • Are dot-separated paths supported for sorting as they are for inclusion? Forbidden? Agnostic?
  • Slightly pedantic, but arguably "The top level of a document MUST NOT contain any additional members [besides data, meta, links,linked]." and "Error objects MUST be returned as a collection keyed by "errors" in the top level of a JSON API document" conflict. (I'd like to return errors at the same time as data but frankly I'm probably wrong).

@wycats Thrilled to hear that Ember Data is still targeting this, that's why I started JSONAPI.NET in the first place, to facilitate making Ember Data apps (@jacqueline-homan yes, come have a look we'd appreciate your feedback!)

@SphtKr
Copy link
Contributor

SphtKr commented Feb 9, 2015

One more question:

It looks as though requesting multiple IDs via a single GET (e.g. /posts/1,2,3) has been removed, and I suppose the only part of the spec bearing on this now is the Filtering Recommendations, where you'd accomplish this via posts?filter[id]=1,2,3. That's okay, but it's funny to me that there's a bulk extension covering PUT, POST, and DELETE but no clear way to do for GET.

@miguelsan
Copy link
Contributor

One question. In the FAQ we read:

Once JSON API is stable, it will always be backwards compatible using a never remove, only add strategy. #46

What's been out of that, when we are talking about v1.0? Shouldn't it be stable? Has the strategy changed?

@dgeb
Copy link
Member Author

dgeb commented Feb 9, 2015

@mitchlloyd there are simple pagination examples on the home page and the extensions page. These both make use of the reserved links (prev, next, first, and last) as well as the reserved page query param. The example profile (on the extensions page) shows how an implementation might include additional pagination data in meta.

@SphtKr those are all valid points / questions that I'll try to resolve soon. I need to confer with @steveklabnik and @wycats.

@miguelsan we hope to release v1.0 very soon and then maintain the stability mentioned in the FAQ afterward. We're trying to get all the churn out now, so this is a critical time for the spec.

@mgenev
Copy link

mgenev commented Feb 19, 2015

@wycats is there a timeline for ember data matching this spec?

@wycats
Copy link
Contributor

wycats commented Feb 19, 2015

@mgenev Stay tuned! You will be happy with the answer!

@barelyknown
Copy link

@wycats That is such good news. Awesome.

@mtparet
Copy link

mtparet commented Feb 23, 2015

Every resource object MUST include both type and id members

Usually the name of the resource is the type so why do we need to specify again although there is no need ? (it does not mean we can't specify it when needed)

@nwjsmith
Copy link
Contributor

@mtparet AFAIK it's to make supporting polymorphic relationships trivial to support, and it greatly simplifies the lookup of resources in client caches/linked resource lists. See: http://jsonapi.org/format/#document-structure-resource-identification

@ahacking
Copy link

The type is needed for heterogenous collections generally, and polymorphism is a particular case of that.

Always having a type makes processing uniform for all cases and avoids the need to partition results into typed collections and the associated problems that come with that, primarily the inability to order results. Having a type as a field of a resourve also means where supported, the type can be changed.

@ethanresnick
Copy link
Member

I know I'm way late on this—I sort of tuned out of JSON-API after @ahacking got me thinking more about annotated, backwards-compatible syntaxes that could be enabled with JSON-LD—but I wanted to offer some feedback.

I think these are very good changes overall and I appreciate all the work that @dgeb and others have done to get us here. In particular, I think going all in on the (type, id) requirement makes a lot of sense, given the central role that plays in Ember Data. I also like the overall simplifications and the moving of a bunch of stuff out of the base spec.

But I am really sad to see that this PR still doesn't enable linking in embedded objects (i.e. #238). We got so close to solving that with #311, so this feels like a step backward. The current resolution to #238 (create new, normalized resources) seems to impose SQL-driven logic on JSON-API API's that may be backed by non-SQL datastores. And it just makes a lot of APIs more complicated: by far, the most annoying aspect of the current API I've built on this spec is the extra, normalized resources I've had to create.

If I think there might be a solution to the embedded linking problem that's relatively simple—sort of an adaptation of the ideas in #311 to the changes in v1.0rc2—should I open a new issue for it? Or is this issue considered settled?

@bintoro
Copy link
Contributor

bintoro commented Feb 25, 2015

But I am really sad to see that this PR still doesn't enable linking in embedded objects

Pardon my naivete, but why can't we support a links structure within complex attributes (a.k.a. embedded objects) as well?

{
  "data": {
    "type": "people",
    "name": "Victor Mayonnaise",
    "address": {
      "street": "12 Mean Street",
      "links": {
        "city": {
          "type": "cities",
          "id": "123"
        },
        "state": {
          "type": "states",
          "id": "12"
        },
        "country": {
          "type": "countries",
          "id": "1"
        }
      }
    }
  }
}

I've read through the relevant threads and never saw this option even floated, so there must be something I'm missing.

@ahacking
Copy link

@bintoro those discussions occurred well before the current changes. You should be able to search the issues (which are prossibly closed now).

@ethanresnick yes I would like to see specific linking out of rich/complex/embedded fields. In my use cases those rich/complex attributes are not standalone resources and are not addressable at an endpoint, they exist purely as structured fields within a resource. Thanks for opening #369 !

@bintoro I think the links bag applies at a resource object level, not at an arbitrary field level, but I may be wrong.

@bintoro
Copy link
Contributor

bintoro commented Feb 25, 2015

@ahacking Looking at #311 again, it appears that what I suggested above was indeed the standard practice sometime in the days of yore, pre-RC1 or so, but was later disallowed. Then #311 came along and proposed to move all links to the top level. Great. However, when that was backtracked on, links was rehabilitated on the main resource object only, not on complex values. But I'm unable to figure out why.

There's nothing that suggests links must be inherent to the root of a resource object. I see links simply as a means of packaging the representation of relationships, no matter where they appear.

Unless someone can point out why links within complex attributes is a problem, I believe they should be explicitly allowed. Having to normalize nested objects for API purposes is far from a trivial transformation.

I also considered maintaining just one links object per resource and storing everything there:

{
  "data": {
    "type": "people",
    "name": "Victor Mayonnaise",
    "address": {
      "street": "12 Mean Street",
    },
    "links": {
      "address.city": {
        "type": "cities",
        "id": "123"
      },
      "address.state": {
        "type": "states",
        "id": "12"
      },
      "address.country": {
        "type": "countries",
        "id": "1"
      }
    }
  }
}

But this is no good because then address is not self-contained. Ideally, you should be able to GET /people/1/address and receive a full representation, not just the street. (EDIT: Illustration only! Not saying servers must expose such partial resources.)

@ethanresnick
Copy link
Member

@bintoro After thinking about this some more, I really like your proposal to nest "links" keys within complex attributes. I originally wanted to have only one "links" key, more inline with the proposal you made directly above, but I agree that it's awkward to have the complex attribute split up, like "address" is in your example. (Still, if there are strong objections to parsers having to recursively search for "links" keys, splitting up the complex attribute wouldn't be the end of the world.)

I also considered a couple other solutions that tried to get the best of the above (i.e. a single "links" key and not splitting up the complex attribute), but both of them caused more trouble than they were worth.

I'm going to open up a separate issue for this, since I haven't heard otherwise from @dgeb and it doesn't make sense to keep discussing it in this PR.

@dgeb
Copy link
Member Author

dgeb commented Feb 27, 2015

I'm going to open up a separate issue for this, since I haven't heard otherwise from @dgeb and it doesn't make sense to keep discussing it in this PR.

I agree this deserves its own issue for discussion. I begin to lose track of issues once they're closed. Thanks @ethanresnick.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy