On Mon, Apr 14, 2014 at 8:52 PM, Alexander Klimetschek <aklim...@adobe.com> wrote: > Thanks Roy for clarifying things. > > I think what it boils down to is that the only real thing that you'd want to > move from the sling url (path info) to an accept header would be the > extension = mimetype, in case you support multiple variants (say html, json, > xml, ...). The selector part is highly server-specific, and should be > transparent to the client, so one should rather send out the right hyperlinks > to the clients with the right annotations so that the client can make the > choice what URL to use, but not have it build the URL or build the right > accept header. > > So what about automatically handling the accept header in Sling wrt to > extensions, based on a configurable mime type mapping? > > Plain example: > - resource /content/foo > - resource type for foo has "json.jsp", "html.jsp" and "xml.jsp" > - valid requests so far: /content/foo.json, /content/foo.html, > /content/foo.xml > - new: requesting /content/foo with accept header > - if mimetype in accept header ("application/json") has a mapping to say > "json" extension, it would resolve to the "json.jsp" > - and maybe it's a good idea to use a redirect to /content/foo.json instead > of rendering it right away > > Selector example is more tricky: > - resource /content/foo > - resource type for foo has "one.json.jsp", "two.json.jsp" > - valid requests so far: /content/foo.one.json, /content/foo.two.json > - should we / can we support a request with /content/foo.one plus accept > header application/json?
I think we should, for consistency with the plain example above. > - or should we allow negotiation on the final URL /content/foo.two.json with > accept = text/html would redirect to /content/foo.two.html ? I think we should send a 406 not acceptable response here, since we can't be sure what the client intended. Robert > > With suffix it gets even more tricky, as it comes after and thus requires the > extension in the URL: > - /content/foo.json/mysuffix > - could allow the same redirect on the final URL > > Anything else, say "selector" and "suffix" don't really have a match in the > accept header and are server-specific semantics, which a generic HTTP client > does not know about. You'd need to transport this information together with > the links in your responses in a semantical format (say html with rel= > annoations), and the client has logic following the semantics of this media > type to choose the right link. But if it has chosen, there is no advantage of > encoding this in an extra header; it's actually more complicated than just a > full string. > > The support would only come in once there is the right resource chosen, but > it's just a matter of supporting different output formats for different > clients, without having to encode this in the URLs up front. I.e. you can > already send out /content/foo links to your clients and then later add > support for a new media type without having to touch any URLs. > > Cheers, > Alex > > On 13.04.2014, at 23:24, Roy T. Fielding <field...@gbiv.com> wrote: > >> On Apr 7, 2014, at 12:24 AM, Felix Meschberger wrote: >> >>> TL;DR: Use Accept header to set request's selectors and extension. So an >>> example Accept content type of "application/x-players+json" would set the >>> selector string to "players" and the extension to "json". >>> >>> We always touted Sling to be a platform for REST-ful web applications. But >>> we cheated a bit in that we "invented" request selectors and extensions for >>> content negotiation instead of using the HTTP Accept header. The reason for >>> this cheating was pure pragmatism since in Browsers the easy way to >>> influence requests is basically just URLs and request parameters. >>> >>> Hence we built all request processing, prominently script/servlet selection >>> on these selectors and extensions. And this proved highly effective. >>> >>> Still, trying to define "pure" REST-ful APIs we can assume applications to >>> be able to set the HTTP Accept header and to be able to define clean URLs >>> without selectors and extensions. >> >> I think this is confusing REST with several other concepts. >> For example, "Cool URIs don't change" is a principle that TimBL >> often talks about, but it is orthogonal to REST. It is important >> for bookmarks, home pages, and reference longevity. >> >> REST requires that all important resources be identified; >> it doesn't say one kind of URI is better than another. >> It certainly doesn't say that proactive content negotiation is better >> than non-negotiated resources, since the latter is far superior for >> caching. What it does say is that a negotiated resource is not >> the same resource as a non-negotiated resource, since they >> do not have the same expectations. >> >> And there is no such thing as an impure RESTful API. >> An application is either designed according to REST or it isn't, >> and an API either supports that or it doesn't. >> >>> So for a browser we want to support something like: >>> >>>> GET /teams/fcbasel.html HTTP/1.0 >>>> Host: soccer.example.com >>> >>> while for REST-ful APIs more something like: >>> >>>> GET /teams/fcbasel HTTP/1.0 >>>> Host: soccer.example.com >>>> Accept: application/x-players+json >> >> You might want to support that for the sake of having >> a content negotiated identifier, but it isn't any more >> RESTful than the first example. >> >> In general, x- is not an appropriate prefix for media types. >> Sling should not encourage their use. >> >>> What if Sling would convert the Accept content type >>> "application/x-players+json" into >>> >>>> selectors = [ "players" ] >>>> selectorString = "players" >>>> extension = "json" >>> >>> This could be done in the Sling Engine's SlingRequestPathInfo constructor >>> under the following conditions: >>> >>> * Extension (and optional selectors) have not derived from the URL yet >>> * Accept header has a single content type (Browsers generally send a list >>> of supported types) >>> * Accept header is an application type >>> * The sub type is converted to selector and extensions, where "+" is used >>> as the separator >>> >>> WDYT ? >> >> I think being able to route requests to resources based on negotiation >> header fields (or any request header field) is useful, but beware of >> how this impacts access control by location. It is important that >> the server not lose track of the fact that it received "/teams/fcbasel" >> as the request target, which might have different access controls >> than "/teams/fcbasel.players.json". This can be a problem in deployments >> where an external server (gateway) performs security checks based on >> the request target if that server is unaware that the application server >> will reinterpret the request based on the Accept field's value. >> >> For example, consider when the origin server has >> >> /teams/fcbasel.players.json >> /teams/fcbasel.private.json >> >> and they have different authentication requirements (outside Sling). >> We don't want the client (attacker) to be able to bypass access >> controls by manipulating the (typically uncontrolled) Accept >> field value. >> >> Note that this kind of resource resolution also requires that >> a Vary header field be set in the response. >> >> What httpd does is allow a URI (or directory) to have an option set >> for multiviews (or some other negotiation mechanism), which is invoked >> only if the request target is not found. This allows negotiated and >> non-negotiated resources to exist in the same place with the >> non-negotiated resource winning any request that might be ambiguous. >> >> Regardless, please note that the notion of RESTful systems preferring >> proactive content negotiation is a myth. If anything, RESTful systems >> prefer reactive negotiation, client-side scripting (code on demand), or >> specific relationship names as a means of selecting from multiple >> variant URIs. In other words, more links, with the client choosing >> the one that best fits their purpose/understanding/version. >> >> >> Cheers, >> >> Roy T. Fielding <http://roy.gbiv.com/> >> Senior Principal Scientist, Adobe <http://www.adobe.com/> >> > -- Sent from my (old) computer