Representation specific URIs are helpful for the developer playing
around use case, but they are actively harmful for users who actually
want to accomplish something.
Can you explain with specifics how links are actively harmful for users? And how users even recognize this alleged harm?
The are also harmful for developers who
want to develop an easily evolvable and maintainable system.
Same question for developers.
Can you explain with specifics how links are actively harmful for users?
And how users even recognize this alleged harm?
Well, if i have the URI for a xml version of a resource but i really
want the html version i am pretty much screwed. As developer i might
be able to guess the needed transformation but how are civilians
suppose to figure that out?
Simple, replace extension "xml" with "html"; I've done this countless times on site's I'm surfing although for me it's usually "xml" vs. "json":
Same question for developers.
The answer is basically the same. As a human and developer you might
be able to guess how to transform a URI for the xml representation of
an entity into the URI of the json representation of that entity but
building user agents with that level of pattern matching and intuition
is difficult. In the face of representation specific URIs user agents
require more complex implementations and more maintenance/human
intervention than they would if resources supported content
negotiation.
Now I will agree the client needs to know what translations the server supports, but if we are talking about an API client that is going to do something less trivial then simply browsing and downloading representations then the client will need some out-of-band information anyway. The following would be one simple way to provide that information via HTML pages on the site:$new_url = preg_replace( '#\.(xml|html|json)(\?.*)?$#', '.json', $url );
<meta name="media-types" content="xml=application/xml&json=application/json&html=text/html" />
<link rel="media-types" href="/media-types.json" />
[
"xml": "application/xml",
"json": "application/json",
"html": "text/html"
]
And yes, none of this is standard. But the alternates are not standard either, so why not advocate for this as a simple standard that IMO works extremely well for users and could be a great standard for developers (and by "this" I mean URL extensions mapping to media types, not the specifics of my mapping examples; mine were just quick and unvetted examples.)
That is easy for you or i but i don't think my mom would know how to
do that. Are you actually suggesting it is an ok user experience for
users to *ever* have reconstruct URIs?
I'm saying it's a bad user experience NOT to allow URI construction, especially for sites that a person uses frequently.Your mom is part of a shrinking demographic; the growing demographic doesn't have the issues with technology.The effort to hide certain technical concepts from users is counter productive; it simply makes them ignorant of important concepts. The concept of a URL transcends technology, it's is a universal identifier for resources and efforts to hide them vs. present them in a manner people become familiar with do more harm than good, IMO.Remember most users are familiar with file extension from their local computers. Most users understand that if they see whitepaper.pdf on their local computer that it is an PDF document; it's similarly familiar for them to download a PDF from http://example.com/whitepaper.pdf whereas downloading a PDF from http://example.com/whitepaper is just weird and confusing.
User are resilient. Their strategy for recovering from a failure of
this sort is usually to find a competitor whose URIs just work.
Assuming there is a competitor sitting there with an alternate based on the URL problem. But your comment is an abstract strawman because you haven't explained how it your vision would improve things for the user. How is a user better off with conneg? Instead of potentially know how to hack to URL with conneg they are simple given no option to get what they want.
Users have absolutely zero interest in this sort of thing.
Funny, I've talked with many users whose opinion would invalidate that statement. SOME users have no interest in this, but OTHERS care about it greatly.
They just give the uri to a user agent (usually by clicking it) and the user
agent handles all that administrivia. The application GETing (etc) the
uri is the thing that should decide what format is needed, not the
user.
Are you saying that if as a user I want an HTML page that the application should be in control so it could give me a PDF instead? Not if I can help it.
The list of all known file extensions is long a growing. Do you really
want to maintain that regexp?
You don't need the full list, you only need the list the client supports. I doubt most clients are going to process more than a few media types, and for those that process a lot, they can use a switch instead. Looking at the IANA list of media types[1] we're still talking about an insignificant number of bytes to download once and cache. Smaller than all but the smallest of GIF images.
And that pattern ignores the servers the
don't use file extension but use a `?format=...` query string, or that
use an api version id in the uri, etc.
Since I argue against the ?format= pattern too, I ignored on purpose.
The alternate link rel is standardized[1], btw. If you are going to do
hyper media driven content negotiation please, please, please use
rel=alternate link headers. At least then i will not have to
find/write a parser for all the different formats that could be
returned and understand some custom reinvention of the wheel.
Did you miss the part where I said " mine were just quick and unvetted examples of URL extensions mapping to media types?" The key argument was for the value of extensions to denote media types, now how they get mapped. But it we are going to create a standard why not standardize mapping?
Even it you do use standard alternate links the client is going to be
more complicated. It is also going to have to, potentially at least,
make more requests against the server.
Sounds like are you arguing for what makes it easier for how you currently develop, and easier not for users nor for developers in general.I've already explained why IMO it's better for the user. For developers writing a simple API client for a simple (and mostly) RESTful web service it's much easier to specify JSON in the extension than to have to pass a header. The following code in PHP can give a products list, but to pass headers I have to do pull out ~20 lines of CURL:$products = file_get_contents( "http://www.example.com/products.json" );If OTOH you are building an advanced fully hypermedia driven API then you've got a lot more skill than many developers and you've got the skill to do a little extra work to get the information you need. And since you know what you are doing, you can use HTTP caching to minimize requests.
Having exactly one representation for every resource may be simple but
it is far from elegant. It increases the number of requests clients
must make (clients must sometimes remake requests based on alternate
links).
Rather than advocate against having extensions designating media types, which some people prefer more than conneg, why not just advocate both styles for an API:
http://www.example.com/products.{type} => returns {media type} mapped to {extension}.http://www.example.com/products => Uses content type negotiation for HTTP header.
It makes identity harder to establish (is
"api.example.com/order/42.xml" the same order as
"example.com/order/42" or not?).
Why does that matter? If it matters, provide a link to the canonical resource in each representation.
It makes it harder to evolve clients
to new formats (if a client wants to move from some custom xml to
json-ld and it has a bunch of urls for xml representations bookmarked,
it must transform those URIs or support both xml and json-ld).
What I already described makes this migration trivial. I don't see your issue. Note that the server must define the rules, but once the server has define the rules this is really not hard to deal with.
It is also harder on the server side because you have to be very disciplined
about providing the alternate links everywhere or clients are
potentially dead in the water.
Why? The root of the API url for the API can provide the info. Call it once, cache it and you are done.
-MikeThis feels like it's a case of not wanting URL extensions to be used. If you don't want to use them you can always find reasons to advocate against them. Me, I want APIs to use extensions so it simplifies API use OTOH I don't have an issue if API also off conneg URIs too. Thus far I don't see significant issues with using extensions to map to media types; nothing you've explained appears to be an issue to me. Maybe I'm still missing something, I'll admit that, but thus far I don't see any real downside, only upside.
Just because content type specific URIs are sometimes useful does not
mean we should use them for everything. Using the accept header field
for content negotiation results in a better experience for developers
(both server side and client side)
Not clear if you are saying that URLs should only support content negotiation, or if you agree supporting both extensions and conneg make sense?
and users because it results in a
combined system that is -- on the whole -- simpler, requires less
manual human intervention and is more resilient to change.
As a user I find content negotiation very frustrating. If I want to read the French version of a document I don't want my browser deciding that because my default language is English that I should only get to view English, for example.
On Sep 14, 2012, at 11:00 AM, Peter Williams <pe...@barelyenough.org> wrote:
Just because content type specific URIs are sometimes useful does not
mean we should use them for everything. Using the accept header field
for content negotiation results in a better experience for developers
(both server side and client side) <-- absurd, absolute, and without supporting example. Do u work for fox news?
Not clear if you are saying that URLs should only support content negotiation, or if you agree supporting both extensions and conneg make sense?
and users because it results in a
combined system that is -- on the whole -- simpler, requires less
manual human intervention and is more resilient to change. <-- again, absolutist, unsupported claim.
As a user I find content negotiation very frustrating. If I want to read the French version of a document I don't want my browser deciding that because my default language is English that I should only get to view English, for example.-Mike
--
http://tools.ietf.org/html/draft-ietf-httpbis-p3-payload-18#section-6.1
A request without any Accept header field implies that the user agent will accept any media type in response. If an Accept header field is present in a request and none of the available representations for the response have a media type that is listed as acceptable, the origin server MAY either honor the Accept header field by sending a 406 (Not Acceptable) response or disregard the Accept header field by treating the response as if it is not subject to content negotiation.
http://www.w3.org/TR/html5/links.html#rel-alternate
The alternate keyword is used with the type attribute
Now it's another question that we're talking about APIs here whose "customers" are programmers. And it's the apps that are used by real end-users.
+1 Gabor
#3 sharing linksSharing a link gives absolutely no guarantee that the recipient will retrieve the exact same message - both in terms of content and format - as the sender. It's a false premise to assume so. I go to "example.com" from Sweden (with Accept-Language sv-se), I see it in Swedish, you visit it from the US (en-us), you see it in English.
Without re-reading the specs in detail, I'm going to assume you are correct as per spec.But, with caveats, that doesn't mean it is generally a good idea to serve something different when the same URL is requested at different times or by similar clients on different machines. I'm not talking about specs but instead user-experience and what might arguably be considered a best practice that goes beyond what the specs require. If I visit example.com and it's in English, if I send a link to a friend I would be surprised if he viewed it in Swedish.Anecdotally I've noticed that many sites that want to provide multi-language content do so by seeing the request and either asking what language the user wants, or guessing from the headers and/or lookup of the location of the attached IP address and then they redirect to an appropriate URL, i.e. http://example.com/en-us/ or http://example.com/sv-se/. If I then send the link http://example.com/en-us/a-great-story/ to a friend it would be particularly bizarre is the friend loaded it and found it in Sweden.Here's a post published on this very subject:
http://h3h.net/technology/designing-urls-for-multilingual-websites
In summary, I think best practices should be based on the principle of least surprise for the targeted user; if it would confuse a reasonable user then it's a bad idea; if it would make reasonable sense to a user it would be a good idea. URLs are identifiers for resources and when dereferenced return representations; if those reputations are not what the targeted user would expect, then taking the liberties that the specs allows but that violates Jakob's Law of User Experience is just a bad idea. IMO.
You give me a link from Chrome, while you see the resource it points to as text/html _representation_, but that link in my Lynx is shown via the resource's text/plain representation.
I'm pretty sure a reasonable user would understand that a client that cannot present a representation of the form that another client can would not display the more complex representation. So that example is effectively a red herring.
#4 an API is not for humansSoftware does not care if you put "json" as variable A (URI) or variable B (Accept header). But software does care about how to treat variable A (known format, opaque meaning) and to treat variable B (known format, equal to the list of media-types that it can process, etc).It's not more complex to say "please" when you ask for something. It's indeed more energy-consuming, time-consuming, but it has great benefits. So use the Accept headers, and not the URI, please!
I've heard this argument numerous times, but it ignores the perspective that software is written *by* humans and the opinions of some that being easier for human developers to work will make it easier to build functional and robust client software. I do understand that reasonable people will differ on what they value so we will likely have to agree to disagree and just hope we don't respectively have to write clients for APIs designed by the other. :)
Now back to the primary topic.URIs are opaque, both for the client and for the server. Yes, URIs have a protocol, a host, a path, a query, so they have a format, but they are still opaque. At most, you (server) look at the path in order to decide which "controller" to take the HTTP request.
What you are saying about URLs being opaque is only true from certain perspectives and without explanation can lead people to believe that URLs MUST be opaque in all cases, which is not true. Yes, a client or an intermediary cannot make assumptions about a URL according to the HTTP spec, but a server CAN publish additional logic about it's URLs and if so a client CAN treat it's URLs as less than opaque given the published documentation.So if we publish an API and in the docs we write that a URL with a ".json" extension will return data of "application/json" media type and ".xml" will return "application/xml", then the URL extension is NOT opaque regarding extensions to any client that wants to use that information to assemble it's URLs. It might be out-of-ban information, yes, but it's still a valid approach (although not fully RESTful as per Fielding.) Again, we are talking reasonable conventions for the target user, i.e the API developer in this case.It comes down to what the server API architect wants to do. If they want to use extensions to indicate media type, they can (and I hope they do for any APIs I'll need to write clients for.)
Having said that, a browser is a browser. A browser is not an API debugging environment.
Correct, it's not. But to the extent it can be, it makes a developer's day much nicer. At least this developer thinks so.
PS: scratch the above fully, if your API is made up of 10 resources, won't change so much over time, etc, etc. Just stating the obvious: if you're small, if you just need to move from your home to the supermarket, if you think your product is rather ephemeral.. don't try designing a BMW - a carriage works just as well. But then let's not argue that a carriage is as good as a BMW, or that it defines or should define the car industry, just because it does the job, or because it was easier to build and debug (understand, explain).
-MikeTo that I agree 100%.To create a complex hypermedia API is a significant undertaking in terms of cost and timeline. If the cost and time to market is worth it to the API owner (to build a BMW) and the API client (to finance and then maintain a BMW) then by all means that's how it should be done. But if the API is simple, OR if the API is going to be programmed by people with small budgets and/or little programming skill then making it as easy as possible to interface with is, to me, a really good idea.
Séneca
--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
1. Some client developers don't pay much attention to the media type. They do care about the serialization format, and so far only three exist in common usage: XML, HTML, and JSON. It's safe to say that content-type renegotiation will not lead to a successful exchange; if my client expects JSON but receives XML, their app will break. technically it doesn't have to, but in reality the client will not go to the trouble of creating a different thunker to deal with the format change. Instead they will file a bug, or yell at the server dev on a group or abandon the API altogether.
2. API developers do not develop clients. At least not nearly enough. If they did, they would realize how hard it is to actually consume the errors and headers. They would consider Postel's Principal and offer multiple ways for the client to communicate their intent via accept headers or file extensions.
Matt
On Sep 21, 2012 10:09 AM, "Matthew Bishop" <ma...@thebishops.org> wrote:
>
> 2. API developers do not develop clients.
You are letting your prejudices show.
> At least
> not nearly enough. If they did, they would realize
> how hard it is to actually consume the errors and
> headers.
Ime, it is just false that client tool chains make it difficult to use headers. If the tools you use make it hard to do basic things like use headers then I suggest improving or replacing them. That level of incapability is no longer the norm.
> They would consider Postel's Principal and offer
> multiple ways for the client to communicate their
> intent via accept headers or file extensions.
Postel's principal does not call for documenting, publishing, and forever supporting all the weird, but suboptimal, ways one might, through the grace and skill of the api programmer, successfully use an api. Rather it calls for doing the best you can with what you get, regardless of whether you are on the client or server side.
Peter
barelyenough.org