Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

On my current project I am responsible for the implementation of a service which involves the consumption of newly created RESTful APIs, documented as solely supporting JSON.

The client consistently makes requests with the accept header of 'application/json' and content-type of 'application/json'. However some endpoints send a response with a content-type of HTML, even a HTML body. To me this is clearly the wrong approach and can never be justified.

Throughout the project this same practice has been applied across two different vendors and two different services. I found myself having to justify why the services needed to be changed. The vendors stated that the client should cope with this and even my REST library of choice has been questioned (RestEasy) because it doesn't cope with this by default 'out the box'.

This has been a major point of frustration. I can't find many references to back up my argument, I assume this is because the point is mute as it's so obvious.

The question is am I missing something? I'm I being pedantic about this? Is it OK to have a JSON API that doesn't have a content-type of application/json in this scenario? References would be appreciated. How do you resolve this situation from a commercial point of view?

share|improve this question
1  
By context-type do you mean the content-type HTTP header? –  Marjan Venema Aug 10 '13 at 10:42
    
Yes I'm refering to the HTTP content-type header. Edited. –  phillip.darley Aug 10 '13 at 10:54

3 Answers 3

up vote 6 down vote accepted

When you are sending an accept header requesting a specific media type, the server should not send back something else, and most certainly not with a 200 OK status code

From Restpatterns.org:

If no Accept header field is present, then it is assumed that the client accepts all media types. If an Accept header field is present, and if the server cannot send a response which is acceptable according to the combined Accept field value, then the server SHOULD send a 406 (not acceptable) response.

(Emphasis mine)

Restpatterns.org takes this from the actual HTTP standard: Header field definitions - Accept

In short: you are not being pedantic. The services are not following the HTTP standard if they are returning HTML when the accept header specifically tells them to return application/json and nothing else.

share|improve this answer
    
+1. I agree with this answer, but sadly the word should is used repeatedly in the HTTP specifications. We have to start an online petition to have those words changed to must. –  Mathew Foscarini Aug 10 '13 at 12:14
    
@MathewFoscarini: Couldn't agree more. "Should" leaves too much stuff up for debate. –  Marjan Venema Aug 10 '13 at 12:56
1  
@MarjanVenema "should" is correct because in section 10 from the same rfc there's a note: "HTTP/1.1 servers are allowed to return responses which are not acceptable according to the accept headers sent in the request. In some cases, this may even be preferable to sending a 406 response." –  imel96 Aug 11 '13 at 2:27
    
@imel96: yes, but the point Mathew and I were making is that it is undesirable that servers should have this freedom. SHOULD should never have been in the standard and that it is continued to allow for an older version is even worse. –  Marjan Venema Aug 11 '13 at 9:13
2  
@DonalFellows: No, they would be better off being informed of what is actually the case. The server should not just send anything back that it thinks suitable, but send a 406 Not acceptable response as stated in the standard. Bear in mind that when the client specifically requests a media type and does not specify any fallbacks it probably has no way of processing any other media type. –  Marjan Venema Aug 11 '13 at 9:50

What do you mean by "RESTful JSON API" - I think the first issue here is that you are mixing up concepts (or possibly someone between you and your technical counterparts at your "suppliers").

A RESTful API (whether you're talking not at all rest really at level 1 or something at level 3 or above c.f. http://martinfowler.com/articles/richardsonMaturityModel.html ) is about the way you interact with the API not about the format of the content sent to or received from. Its not even about protocols or transport mechanisms...

Similarly a JSON API is an API that supports use of JSON as a data format - it may or may not be restful, it may or may not be implemented using HTTP and (and this is the key point) it may or may not support JSON exclusively.

A good API running over HTTP (its reasonable to assume that in context you're talking about an api exposed over HTTP) should allow you to request content in a variety of formats and those formats can (and possibly should) include HTML as well as JSON and XML. Why? Well it would make learning the API a lot easier, conceptually it provides an instant browser based UX for whatever purpose and so on...

The interesting question then becomes if my API, which supports a variety of content formats, is called without being told what format the client expects then what format should it return...? This tends towards a religious argument - but HTML gives the provider the option of including helpful information (like "remember to set the content accept header").

To answer the question an API, one that's restful and one that supports json should absolutely be able to return HTML if that's the requested content.

share|improve this answer
1  
I take both your points and have edited my question accordingly. The fact that the service is RESTful is not relevant and I've detailed that the client accepts 'application/json' in each request. –  phillip.darley Aug 10 '13 at 9:41

The client consistently makes requests with the accept header of 'application/json' and content-type of 'application/json'

Yes, this is the correct thing to do, but doesn't mean the vendor cares. While I totally understand your frustration, because I also think a JSON service should always give a JSON response but there are many examples where that's the not the case.

Throughout the project this same practice has been applied across two different vendors and two different services. I found myself having to justify why the services needed to be changed. The vendors stated that the client should cope with this and even my REST library of choice has been questioned (RestEasy) because it doesn't cope with this by default 'out the box'.

Well, I have to agree with the vendor. It's their service and as long as they document clearly the special cases for using it, then you can't really impose that they change it. It's a disadvantage for them as developers will be slow to adopt their API, and if they listened to what the developers need then they would change it, but sadly there is no rule that they must follow standards.

The question is am I missing something?

Request headers mean nothing unless they are interrupted correctly on the other end. I know that if I develop a web API using PHP, then to hell with the request headers. I can respond with whatever I want. Whereas, a service configured in IIS with C# offers much easier handling of request headers, their type and handling the response type. It has a lot to do with the tools the vendor used to build the API.

I'm I being pedantic about this?

Yes and No. I have developer friends who would be unable to move past this. They would become so fixated by the problem and unable to proceed with other tasks until the API works the way they expect it to work. Now that's being pedantic.

It's a problem because the vendor has created "more work" to complete your tasks. Anyone would be frustrated by that. I know I would be.

Is it OK to have a JSON API that doesn't have a content-type of application/json in this scenario?

Absolutely, but it's not a good practice.

A client can only tell the server what the context-type of a request is. It has no ability to enforce a content-type for the response. The client can only inform the server that it will accept a collection of possible content-types.

Header Field Definitions

The Accept request-header field can be used to specify certain media types which are acceptable for the response. Accept headers can be used to indicate that the request is specifically limited to a small set of desired types, as in the case of a request for an in-line image.

It's possible for a client to request an image of image/jpeg, but the server responses with text/html and a status code of 404 if the image was not found. Servers can also respond incorrectly. There are many Wordpress websites out there that respond with text/html and status code 200 for files not found pages.

Now that is all BAD practice on the part of the server. What I'm trying to tell you is that it's absolutely possible, and happens often. People don't know what they are doing when they configure these things.

References would be appreciated. How do you resolve this situation from a commercial point of view?

I've run into this problem on a few projects. You post JSON data to the server and it gives back either a JSON or HTML response.

It really isn't a big deal to know which type was in the response. If the first character is { or [ you can assume JSON. If it's < you can assume HTML. That's how I've handled it in the past. Sometimes the programmer who wrote the API knows jack all about HTTP headers. Everything comes back as text/html responses. If you are lucky they have Apache configured to default to text/plain which can sometimes help.

These problems exist and will continue to exist far into the future. Server to server communication is by far an unregulated activity. There is no governing body that will kick out a vendor from a union for a server that gives bad HTTP responses.

share|improve this answer
    
This is inline with @Marjan Venema's answer but another key point you raise is documentation of this behavior. To add to my frustration the vendor has not documented this behavior. The content-type varies depending on session state, yet only the JSON response is documented. –  phillip.darley Aug 11 '13 at 23:19

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.