• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar
  • Skip to footer

REST API Tutorial

  • REST
  • JSON
  • Dark Mode
Home / Guides / Content Negotiation in REST APIs

Content Negotiation in REST APIs

Generally, resources can have multiple presentations, mostly because there may be multiple different clients expecting different representations. Asking for a suitable presentation by a client, is referred as content negotiation.

HTTP has provisions for several mechanisms for “content negotiation” — the process of selecting the best representation for a given response when there are multiple representations available.RFC 2616

Server-driven Vs Agent-driven Content Negotiation

If the selection of the best representation for a response is made by an algorithm located at the server, it is called server-driven negotiation. If that selection is made at agent or client-side, its called agent-driven content negotiation.

Practically, you will NOT find much usage of server-side negotiations because, in that way, you have to make lots of assumptions about client expectations. Few things like client context or how the client will use the resource representation are almost impossible to determine. Apart from that this approach makes the server-side code complex, unnecessarily.

So, most REST API implementations rely on agent-driven content negotiations. Agent driven content negotiation rely on usage of HTTP request headers or resource URI patterns.

  1. Content negotiation using HTTP headers

    At server side, an incoming request may have an entity attached to it. To determine it’s type, server uses the HTTP request header Content-Type. Some common examples of content types are “text/plain”, “application/xml”, “text/html”, “application/json”, “image/gif”, and “image/jpeg”.

    Content-Type: application/json

    Similarly, to determine what type of representation is desired at client side, HTTP header ACCEPT is used. It will have one of the values as mentioned for Content-Type above.

    Accept: application/json

    Generally, if no Accept header is present in the request, the server can send pre-configured default representation type.

    Implementing Accept header based content negotiation is most used and recommened way.
  2. Content negotiation using URL patterns

    Another way to pass content type information to the server, the client may use the specific extension in resource URIs. For example, a client can ask for details using:

    http://rest.api.com/v1/employees/20423.xml
    http://rest.api.com/v1/employees/20423.json
    

    In above case, first request URI will return a XML response whether second request URI will return a JSON response.

Defining preferences

It is possible to have multiple values in Accept header. The client may want to give multiple values in the accept header when the client is not sure about if its desired representation is present or supported by the server at that time. [RFC 2296]

For example,

Accept: application/json,application/xml;q=0.9,*/*;q=0.8

Above Accept header allows you to ask the server a JSON format. If it can’t, perhaps it could return XML format (the second level). If it’s still not possible, let it return what it can.

The preference order is defined through the q parameter with values from 0 to 1. When nothing is specified, the implicit value is 1.

Was this article helpful?

Share this:

  • Twitter
  • Facebook
Previous Tutorial:
Idempotent REST APIs
Next Tutorial:
Statelessness in REST APIs

Reader Interactions

Comments

  1. Mike says

    February 6, 2020 at 6:58 pm

    Just curious, and I may need to post this under a different topic, but I was looking to determine the correlation between Accept and Content-Type headers versus swagger consumes and produces keywords. I would expect a 1-1 relation, but simply adding a produces in a swagger does not require a user to send in an accept header. Can someone explain the correlation or point me to a site that has this info? Swagger.io discusses the headers and keywords, but not their correlation, which I am looking for.

    Thank you in advance for any help, and sorry if this should be under a different topic.

    Reply
  2. Oswald says

    September 8, 2019 at 12:16 am

    I think there is some confusion in the “Content negotiation using URL patterns” because it shows an example using an extension to locate a URI. While in the “REST Resource Naming Guide” section “Do not use file extenstions” you recommend not to use file extensions.

    Reply
    • Admin says

      September 12, 2019 at 5:21 pm

      I tried to show the possible ways to achieve it.

      Reply
  3. KSN says

    January 4, 2019 at 12:14 pm

    I have different GET request with the different content-type returned.

    @GET
    @Produces(“application/text+xml;qs=0.75;charset=’utf-8′”)
    public Source getText( ) {
    }

    @GET
    @Produces(“application/xml;qs=0.5;charset=’utf-8′”)
    public Source getXml( ){
    }

    When I request from FireFox which goes into the first method due to FireFox set the Accept-header: “text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8”.

    Why it is going into first even the request header has “application/xml”?

    Any help will be appreciated!!

    Thanks in advance.

    Reply
  4. James Passmore says

    November 15, 2018 at 5:01 pm

    They are too generic, Roy Fielding in comment 31 of his blog tells us:
    …
    In terms of testing a specification, the hardest part is identifying when a RESTful protocol is actually dependent on out-of-band information or if the authors are just overspecifying things for the purpose of documentation. What I look for are requirements on processing behavior that are defined outside of the media type specification. One of the easiest ways to see that is when a protocol calls for the use of a generic media type (like application/xml or application/json) and then requires that it be processed in a way that is special to the protocol/API.
    …

    Reply
  5. Xavier says

    November 8, 2018 at 10:03 am

    Isn’t “application/xml” or “application/json” a bit too generic?

    Wouldn’t it be better to use vendor specific media types like “application/vnd.mycompany.customers.v1+json” or “application/vnd.mycompany.customers+json;version=1”?

    You can put a lot of stuff in the ACCEPT header like the version or the charset which helps keeping your URIs clean (no version or file extension… after all, the U in URI stands for Unique, it shouldn’t change when you request another representation for the same resource).

    Reply
    • Admin says

      November 8, 2018 at 5:24 pm

      Yes, vendor specific media types are good idea and I see them in use in most projects. They work.

      U stands for Uniform (NOT Unique). Both have absolutely different meanings.

      Reply
  6. pramod sahni says

    August 4, 2018 at 12:23 pm

    how to produce different response for different client in rest api?

    Reply
    • Admin says

      August 8, 2018 at 6:53 am

      Why you want to do that? Please consider it twice before implementing.

      Anyway, If you still has a good reason to do this then I will suggest to use “optionality index” concept. In this approach, client will pass an extra request header with predetermined value.

      For each different optioanlity index, return a different response. e.g.

      X-COMPANY-OPTIONALITY-INDEX=10001   //for response 1
      
      X-COMPANY-OPTIONALITY-INDEX=20001   //for response 2
      
      Reply
    • steven c says

      December 13, 2019 at 10:38 pm

      are you sure about this?

      Reply
  7. Oscar says

    May 11, 2018 at 7:14 pm

    Negotiation via URI patterns is against REST resource naming best practices, isn’t it? I refer to “Consistency is the key” , where it’s advisable “Do not use file extentions”

    Reply
    • Admin says

      May 12, 2018 at 9:42 am

      It’s true that this pattern does not add any value, and not advisable. Still it’s mentioned here because it is a possible way of content negotiation and many people may find it useful for their API consumers.

      Reply
      • Oscar says

        May 14, 2018 at 2:13 pm

        Thanks for your reply!!

        Great tutorial 😉

        Reply
        • steven c says

          December 13, 2019 at 10:38 pm

          true that

          Reply
  8. Eugen says

    February 24, 2018 at 11:54 am

    If format is present via URI and Accept header what precedence should be in this case?
    My personal opinion is: use URI than fall back to Accept header.
    But I am not sure this is right. Is there some RFC or spec which define this priority?

    Reply
    • Admin says

      February 25, 2018 at 5:05 am

      I second your opinion. I have not heard of any RFC which talk about having format information in URI.

      Reply

Leave a Reply to Admin Cancel reply

Your email address will not be published. Required fields are marked *

Primary Sidebar

Search Tutorials

Learn REST

  • What is REST?
  • REST Constraints
  • REST Resource Naming Guide

Guides

  • Caching
  • Compression
  • Content Negotiation
  • HATEOAS
  • Idempotence
  • Security Essentials
  • Versioning
  • Statelessness in REST APIs

Tech – How To

  • REST API Design Tutorial
  • Create REST APIs with JAX-RS

FAQs

  • PUT vs POST
  • N+1 Problem
  • ‘q’ Parameter

Resources

  • What is an API?
  • Comparing SOAP vs REST APIs
  • HTTP Methods
  • Richardson Maturity Model
  • HTTP Response Codes
    • 200 (OK)
    • 201 (Created)
    • 202 (Accepted)
    • 204 (No Content)
    • 301 (Moved Permanently)

Footer

References

  • The dissertation by Roy Thomas Fielding
  • Uniform Resource Identifier (URI, URL, URN) [RFC 3986]
  • Internet MediaTypes
  • Web Application Description Language (WADL)

Meta Links

  • About
  • Contact Us
  • Privacy Policy

Blogs

  • How To Do In Java

Copyright © 2020 · restfulapi.net · All Rights Reserved. | Sitemap