Skip to content

media type for request with existing vendor tree #1020

Closed

Description

@bf4

We have an internal API that uses an Accept: application/vnd.ourcompany.v2 header in requests.

We're writing a v3 and are planning on using JSON API, which specifies a request with Accept: application/vnd.api+json and response with Content-Type: application/vnd.api+json.

What the correct way to structure the Accept header with two vendor trees?

  • application/vnd.ourcompany.v3+json, application/vnd.api+json
  • application/vnd.ourcompany.v3+json; ext=jsonapi
  • application/vnd.ourcompany.v3+vnd.api+json
  • application/vnd.api+json; ext=ourcompany; version=3.0

etc?

I've been reading a bunch, but I can't figure out

Can you provide some guidance for this?

refs:

Activity

  1. ethanresnick commented on Apr 5, 2016

    @ethanresnick
    Member

    A media type in the vendor tree is used in the Accept header just like any other media type (i.e. there aren't vendor-type-specific rules). So the client just provides a comma-separated list of acceptable media types:

    Accept: application/vnd.ourcompany.v3+json, application/vnd.api+json 
    

    If the client wants to indicate that it prefers one type over another, it can use the q parameter, like so:

    Accept: application/vnd.ourcompany.v3+json; q=0.5, application/vnd.api+json 
    

    (The above header indicates that JSONAPI is preferred over vnd.ourcompany.v3+json. See here for more details on "q" values.)

  2. ethanresnick commented on Apr 13, 2016

    @ethanresnick
    Member

    @bf4 I re-read your question here after seeing your comment in #406, and I think I misunderstood it originally. Any media types listed in the Accept header are supposed to be independent of one another, so it's not appropriate to list multiple media types only to have the server use the presence of one type (i.e. the application/vnd.ourcompany.v3+json) as a signal to change the content it returns under another media type (i.e. application/vnd.api+json). If you can't use URI versioning, you should use a separate header, like X-API-Version: 3 (and then add Vary: X-API-Version).

  3. bf4 commented on Apr 14, 2016

    @bf4
    ContributorAuthor

    @ethanresnick Let me see if I understand you

    Given a company has an API
    And that API use the JSON API (media type: `application/vnd.api+json`)
    And that the company is making breaking changes to the existing API
    And so would like to use version the changes
    Then the company should continue to specify their API media type, as it has not changed
    And communicate the version in the
      URI (`example.com/v3/`) or 
      domain (`api3.example.com/`),
      via custom headers ( `X-API-Version: 3`, `Vary: X-API-Version`) OR 
      ask clients to understand a custom media type `application/vnd.ourcompany.v3+json` as including JSON API
    BUT not as 
      `application/vnd.ourcompany.v3+json, application/vnd.api+json` nor
      `application/vnd.ourcompany.v3+json, ext=jsonapi` nor 
      `application/vnd.api+json; ext=ourcompany; version=3.0` nor
      `application/vnd.api+json; version = 3.0`
    And that this is how users of JSON API should expect their APIs to evolve
  4. bf4 commented on Apr 21, 2016

    @bf4
    ContributorAuthor

    So, I think I also misunderstood the spec w/r/t content negotiation.

    The client must sends a request with Content-Type: application/vnd.api+json and the server respond with Content-Type: application/vnd.api+json.

    But, regarding the Accept header

    Clients that include the JSON API media type in their Accept header MUST specify the media type there at least once without any media type parameters.

    So, the only requirement on the Accept header is that if a client has an Accept header that includes application/vnd.api+json, that it must appear without a media type parameter at least once.

    So, there'd be no problem with a request with the headers Content-Type: application/vnd.api+json and Accept: application/vnd.ourcompany.v3, right?

    The only problem there is that we must interpret application/vnd.ourcompany.v3 as the client accepting application/vnd.api+json, which is fine because we 'own' it.

  5. bf4 commented on Apr 18, 2017

    @bf4
    ContributorAuthor

    Noting that it appears from #406 and https://github.com/cerebris/jsonapi-resources/issues/874 that Accept: application/vnd.api+json; version=3.0 or Accept: application/vnd.api+json; version=3.1 would appear to be a valid way for me to version my api without changing the mime type.

  6. bf4 commented on Jun 4, 2017

    @bf4
    ContributorAuthor

    @steveklabnik xrefs for a quick timeline of changes in points of view on the subject:

    tl;dr Accept is for media types. Unless each API version happens to be a new media type, URL versioning is less confusing and just works better, if you need versioning at all

    • 2011 http://blog.steveklabnik.com/posts/2011-07-03-nobody-understands-rest-or-http#i_want_my_api_to_be_versioned

      The first thing that people do when they want a versioned API is to shove a /v1/ in the URL. THIS IS BAD!!!!!1. Accept solves this problem. What you're really asking for is "I'd like the version two representation of this resource." So use accept!

      It's a Vendor MIME Type. After all, we don't really want just any old JSON, we want my specific form of JSON. This lets us still have our one URL to represent our resource, yet version everything appropriately.

    • 2012 https://web.archive.org/web/20120229044244/http://blog.steveklabnik.com:80/posts/2011-07-03-nobody-understands-rest-or-http

      specifically don't agree that versioning the media type is how to properly version APIs. Hypermedia APIs should not actually use explicit versioning, but I'd rather see a version in the URI with HATEOAS than no HATEOAS and versioned media types.

    • 2013 Update to mention the correct content-type #6 (comment)

      Versioning through accept headers is an anti-pattern. We won't be supporting it.

    • 2014 Versioning of the APIs #68 (comment)

      How you version your API is completely orthogonal to JSON API itself, which is concerned about HTTP semantics and the arrangement of your JSON.

      At Balanced, we've versioned through the Accept header. If I were making a new project, I'd not version at all. Someone else may version through URLs. It doesn't really matter.
      URL versioning has nothing to do with HTTP. Accept may. It doesn't affect anything in JSON API directly.

    • 2016 Clarify the versioning strategy for APIs #406 (comment)

      no, that's the version of JSON API itself. Which is what media type parameters are for: to parameterize the media type.
      I personally recommend "versioning" through URLs.

      I still think that using the media type to version is just plain incorrect. Media type parameters are for the media type, not for the underlying service.

      REST says nothing about URLs, let alone the structure of URLs.
      Version changes aren't always about only representation changes. If they were, then yes, the media type would be correct, as it would be about requesting a different representation.

      I specifically don't agree that versioning the media type is how to properly version APIs. Hypermedia APIs should not actually use explicit versioning, but I'd rather see a version in the URI with HATEOAS than no HATEOAS and versioned media types.

    and for fun @brandur on REST/Hypermedia vs. GraphQL/RPC

    • 2013 https://brandur.org/accessible-apis
    • 2014 https://brandur.org/elegant-apis
    • 2017 https://brandur.org/api-paradigms

      hypermedia had a very hard time building any kind of traction
      After five years of strong evangelism at every API conference in the world and very little actual adoption, it’s a pretty safe bet that hypermedia isn’t going to be the next big thing.
      GraphQL is a fan favorite right now
      One possibility for the next big paradigm in APIs is just to make them a set RPCs (remote procedure calls) and use something like GRPC to generate libraries in a huge variety of languages that users can pull down and use at their leisure.
      Here’s one final strong opinion: religious adherence to REST is overrated and its perceived advantages have never materialized as fully as its proponents hoped. Whatever we choose next should aim to be flexible and efficient, and GraphQL seems like a good candidate for that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions