4 ms·
It's yet another implementation detail that drags the reality of RESTful web service development farther away from the principle that it's easy because it's bas
by RyanMcGreal 15y ago
It's yet another implementation detail that drags the reality of RESTful web service development farther away from the principle that it's easy because it's based on HTTP and we already know HTTP.
I'm not writing this to dump on REST. I still think it's the right approach to build a web service over HTTP, but I'm also conscious of the diminishing returns on each incremental step toward pure RESTfulness. I'm just trying to make a web service, and suddenly I'm defining new content-types?
For a client, is it worth the trouble to learn a new content-type to determine what's a hyperlink in my JSON response, when they can just look at the response and see something like the following?
GET /articles HTTP/1.1
{
"articles": [
{
"url": "/articles/1",
"title": "This is my first article",
"pubDate": "2012-01-05T08:39:47.625000
},
{
"url": "/articles/2",
"title": "This is my second article",
"pubDate": "2012-01-13T11:07:35.219000
}
]
}
After a while it starts to feel like the HTML v. XHTML debate.
- arethuza 15y agoMaybe I'm missing something, but why the resistance to returning a "meaningful" content type in a response? It's just a name for the structure you have outlined there.
- RyanMcGreal 15y agoI'm happy to change a server's content-type from application/json to application/vnd.my-adhoc-service+json, but that won't change the client's need to read my documentation and play with the service before they can figure out how to use it. That's true even if I move the documentation out to an RFC. One real advantage I can see is to use the media type for versioning, but even that doesn't remove the need for a client to intervene if they want to upgrade their code to work with the newer API version. So it's not really clear to me that a custom media type is significantly more useful for the client, even if it is more 'proper'. When a constraint feels ceremonial, I become suspicious that it exists to drive purity-for-its-own-sake rather than a real benefit.
- waitwhat 15y agoTwo reasons that I can see... If the server generates custom mimetypes, clients have to ensure they "Accept:" the correct mimetype for every request. And if you have multiple data types (and you will have multiple data types), then this "Accept:" header will vary for every request. Getting this right is an irritant to client developers with no actual benefit to them, and a great potential source of bugs. Much easier is if the client can just send "Accept: application/json" or "Accept: application/xml" for every request. If the server generates custom mimetypes, and you update your API to v2 which produces an article listing in an incompatible format, you either have to introduce a version number into your mimetype (which seems messy and pointless busywork), or stick with the same mimetype and accept that your custom mimetypes aren't actually particularly meaningful as their meaning can change substantially over time (so why did you have them in the first place?) Much easier is if the server had just used "Content-Type: application/json" or "Content-Type: application/xml" which will always be correct.
- arethuza 15y agoSo if you don't communicate that the version of the structure of your response has changed through the Content-Type, where would you do it?
- icebraining 15y agoIf the server generates custom mimetypes, clients have to ensure they "Accept:" the correct mimetype for every request. No, he doesn't. First, the server can send whatever it wants - nothing breaks if you reply with your custom media type to a generic "application/json" request. Second, even if you want to be correct, that's what wildcards are for: the client can simply send always the same header: Accept: application/*+json If the server generates custom mimetypes, and you update your API to v2 which produces an article listing in an incompatible format, you either have to introduce a version number into your mimetype (which seems messy and pointless busywork), I still don't get what's the problem with changing a string. I think you're using a bad framework.
- waitwhat 15y agoI doubt that sending a mimetype which the client has said it can't accept would be on anyone's list of best practices. This is a good point, though, not sure why it escaped me: Accept: application/*+json I think you're using a bad framework. Probably. This isn't why, though.
- icebraining 15y agoWhat trouble? Are you not documenting what you return anyway? What's the cost of just changing the mediatype to some different string? For a client, is it worth the trouble to learn a new content-type to determine what's a hyperlink in my JSON response, when they can just look at the response and see something like the following? Personally, I think that mindset will hold us back. People still think of RESTful services as closed silos instead of open, truly uniform interfaces, and that will prevent us from growing, in my opinion. Your view is of a developer painstakingly coding against each API (s)he wants to use, manually prodding and poking it and writing a custom library that doesn't work with any other service. My view is of generic, easily adaptable clients, using machine-readable specification of formats¹ and providing graphical UIs where even non-programmers can input the single endpoints of various services and easily combine the data and functionality to create applications that cater to their specific needs. I see a service like IFTTT[1], but more flexible and where the services are not hardcoded but imported dynamically by the user and then strung together to fit their needs. Using mediatypes, even if custom, is a step towards that integration and standardization that makes this possible. ¹ RDF seems like the best bet to me - possibly encoded as JSON [1]: http://ifttt.com/ http://ifttt.com/
- RyanMcGreal 15y agoWhat I'm trying to suggest is that the point at which a schema is powerful and generic enough to work as a general-purpose web service API for an arbitrary use case, it has become more difficult and complicated to learn, configure and use than a much simpler, discoverable ad-hoc schema that closely matches the functionality of your web service. In general, REST principles give more than they take, which is why I try to follow them; but you're always going to have to find the sweet spot of abstraction that provides the right amount of power and flexibility combined with the right amount of discoverability and predictability. > What's the cost of just changing the mediatype to some different string? I'm happy to change a server's content-type from application/json to application/vnd.my-adhoc-service+json, but that won't change the client's need to read my documentation and play with the service before they can figure out how to use it. That's true even if I move the documentation out to an RFC. One real advantage I can see is to use the media type for versioning, but even that doesn't remove the need for a client to intervene if they want to upgrade their code to work with the newer API version. So it's not really clear to me that a custom media type is significantly more useful for the client, even if it is more 'proper'. When a constraint feels ceremonial, I become suspicious that it exists to drive purity-for-its-own-sake rather than a real benefit.