Domanda

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 moot as it's so obvious.

The question is, am I missing something? am 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?

È stato utile?

Soluzione

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.

Altri suggerimenti

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.

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
scroll top