Repository navigation
Examples
This page collects some examples of profile negotiation. They are written in several different ways so as to make the implications of each solution better visible.
A client requests an XML document conforming to a specific profile. The profile is identified by urn:example:schema:e-commerce-payment.
Request:
GET /some-resource HTTP/1.1
Accept: application/xml
Accept-Profile: <urn:example:schema:e-commerce-payment>
Response:
HTTP/1.1 200 OK
Content-Type: application/xml
Profile: <urn:example:schema:e-commerce-payment>
Link: rel="self";
type="application/xml";
profile="<urn:example:schema:e-commerce-payment>",
rel="alternate";
type="application/xml";
profile="<urn:example:schema:e-commerce-accounting>"
Request:
GET /some-resource HTTP/1.1
Accept: application/xml
Prefer: profile=<urn:example:schema:e-commerce-payment>
Response:
HTTP/1.1 200 OK
Content-Type: application/xml
Vary: Prefer
Preference-Applied: profile=<urn:example:schema:e-commerce-payment>
Link: rel="self";
type="application/xml";
profile="<urn:example:schema:e-commerce-payment>",
rel="alternate";
type="application/xml";
profile="<urn:example:schema:e-commerce-accounting>"
Request:
GET /some-resource HTTP/1.1
Accept: application/e-commerce-payment+xml
Response:
HTTP/1.1 200 OK
Content-Type: application/e-commerce-payment+xml
Link: rel="self";
type="application/e-commerce-payment+xml",
rel="alternate";
type="application/e-commerce-accounting+xml"
Request:
GET /some-resource HTTP/1.1
Accept: application/xml
Accept-Features: profile=<urn:example:schema:e-commerce-payment>
Negotiate: guess-small
Response:
HTTP/1.1 200 OK
Content-Type: application/xml
TCN: choice
Vary: negotiate
Alternates: {profile=<urn:example:schema:e-commerce-accounting>}
Link: rel="self";
type="application/xml";
profile="<urn:example:schema:e-commerce-payment>",
rel="alternate";
type="application/xml";
profile="<urn:example:schema:e-commerce-accounting>"
Example 2: Client can handle several profiles and uses q-values to specify preference for one of them
A client requests an RDF/XML document conforming to one of two profiles (http://example.com/profiles/profile-1 or http://example.com/profiles/profile-2). It uses q-values to express a preference for profile-1, the server, however, decides to deliver in profile-2.
Request:
GET /some-resource HTTP/1.1
Accept: application/rdf+xml
Accept-Profile: <http://example.com/profiles/profile-1>; q=0.8,
<http://example.com/profiles/profile-2>; q=0.5
Response:
HTTP/1.1 200 OK
Content-Type: application/rdf+xml
Profile: <http://example.com/profiles/profile-2>
Link: rel="self";
type="application/rdf+xml";
profile="<http://example.com/profile/profile-2>",
rel="alternate";
type="application/rdf+xml";
profile="<http://example.com/profile/profile-1>"
Not possible, since preferences SHOULD NOT appear multiple times:
To avoid any possible ambiguity, individual preference tokens SHOULD NOT appear multiple times within a single request. If any preference is specified more than once, only the first instance is to be considered. All subsequent occurrences SHOULD be ignored without signaling an error or otherwise altering the processing of the request. This is the only case in which the ordering of preferences within a request is considered to be significant.
Request:
GET /some-resource HTTP/1.1
Accept: application/profile-1-rdf+xml; q=0.8,
application/profile-2-rdf+xml; q=0.5
Response:
HTTP/1.1 200 OK
Content-Type: application/profile-2-rdf+xml
Link: rel="self";
type="application/profile-1-rdf+xml";
rel="alternate";
type="application/profile-2-rdf+xml";
In this scenario the negotiation is done on the client side
Request:
GET /some-resource HTTP/1.1
Accept: application/xml
Accept-Features: profile=<urn:example:e-commerce-payment>
Negotiate: guess-small
Response:
HTTP/1.1 300 Multiple choices
Content-Type: text/html
TCN: choice
Vary: negotiate
Profile: <urn:example:schema:e-commerce-payment>
Alternates: {"some-resource-accounting" 0.9 {type application/xml} {profile <urn:example:e-commerce-accounting>}}
{"some-resource-payment" 0.8 {type application/xml} {profile <urn:example:e-commerce-payment}}
Link: rel="self";
type="application/xml";
profile="<urn:example:schema:e-commerce-payment>",
rel="alternate";
type="application/xml";
profile="<urn:example:schema:e-commerce-accounting>"
(client performs local content negotiation and decides which representation to ask for) Request:
GET /some-resource-accounting HTTP/1.1
Accept: application/xml
Response
HTTP/1.1 200 OK
Content-Type: application/xml
Example 3: Client tries to PUT data using one profile, server answers it can only process another profile
A client PUTs a turtle document conforming to the Profile http://example.com/profiles/profile-1. The server answers that it can only process documents conforming to http://example.com/profiles/profile-2.
Request:
PUT /some-resource HTTP/1.1
Content-Type: text/turtle
Profile: <http://example.com/profiles/profile-1>
Response:
HTTP/1.1 406 Not acceptable
Content-Type: application/xhtml+xml
Accept-Profile: <http://example.com/profiles/profile-2>
Link: rel="alternate";
type="application/rdf+xml";
profile="<http://example.com/profile/profile-1>"
Since Preferis a request-only field, the client cannot supply any information on the profile used so the server must use heuristics to figure out if it can process the data or not. Then it can answer 406 and supply a list of supported profiles through the Link header. The relation "alternate" is probably not the right one to use, though...
Request:
PUT /some-resource HTTP/1.1
Content-Type: application/xml
Response:
HTTP/1.1 406 Not acceptable
Content-Type: application/xhtml+xml
Link: rel="alternate";
type="application/rdf+xml";
profile="<http://example.com/profile/profile-1>"
I don't know how the server can tell the client what media types it can handle, here I use the Link-header
Request
PUT /some-resource HTTP/1.1
Content-Type: application/profile1+xml
Response
HTTP/1.1 406 Not acceptable
Link: rel="alternate";
type=application/profile2+xml
RFC 2295 §12.2 explicitly says that transparent content negotiation is only defined for GET and HEAD, so we would need to extend that concept to use it here.
Is this example relevant as it is currently written? XML namespaces are not profiles...
A client requests an XML document where the elements in namespace urn:example:namespaces:ns1 must conform to XML schema http://example.com/schema/schema-1 and the elements in namespace urn:example:namespaces:ns2 must conform to XML schema http://example.com/schema/schema-2. The server answers that it can supply the document as requested.
Request:
GET /some-resource HTTP/1.1
Accept-Profile: <urn:example:namespaces:ns1
http://example.com/schema/schema-1
urn:example:namespaces:ns2
http://example.com/schema/schema-2>
Response:
HTTP/1.1 200 OK
Content-Type: application/xml
Profile: <urn:example:namespaces:ns1
http://example.com/schema/schema-1
urn:example:namespaces:ns2
http://example.com/schema/schema-2>
Request
GET /some-resource HTTP/1.1
Prefer: profile="<urn:example:namespaces:ns1
http://example.com/schema/schema-1
urn:example:namespaces:ns2
http://example.com/schema/schema-2>"
Accept: application/xml
Response
HTTP/1.1 200 OK
Preference-applied: profile="<urn:example:namespaces:ns1
http://example.com/schema/schema-1
urn:example:namespaces:ns2
http://example.com/schema/schema-2>"
Vary: Prefer
Content-type: application/xml
Link: rel="self";
type="application/xml";
profile="<urn:example:namespaces:ns1
http://example.com/schema/schema-1
urn:example:namespaces:ns2
http://example.com/schema/schema-2>",
rel="alternate";
type="application/xml";
profile="<urn:example:namespaces:ns1
http://example.com/schema/schema-3
urn:example:namespaces:ns2
http://example.com/schema/schema-4>"
Here we use the media type myVerySpecificMediaType+xml to say that we want XML elements from urn:example:namespaces:ns1 to conform to http://example.com/schema/schema-1 and elements from urn:example:namespaces:ns2 to conform to http://example.com/schema/schema-2.
Question: how do we nicely degrade?
Request
HEAD /some-resource HTTP/1.1
Accept: application/myVerySpecificMediaType+xml
Response
HTTP/1.1 200 OK
Content-Type: application/myVerySpecificMediaType+xml
Link: rel="self";
type="application/xml";
profile="<urn:example:namespaces:ns1
http://example.com/schema/schema-1
urn:example:namespaces:ns2
http://example.com/schema/schema-2>",
rel="alternate";
type="application/xml";
profile="<urn:example:namespaces:ns1
http://example.com/schema/schema-3
urn:example:namespaces:ns2
http://example.com/schema/schema-4>"
Request
HEAD /some-resource HTTP/1.1
Accept: application/xml
Accept-Features: {profile=<urn:example:namespaces:ns1
http://example.com/schema/schema-1
urn:example:namespaces:ns2
http://example.com/schema/schema-2>}
Negotiate: guess-small
Response:
HTTP/1.1 200 OK
Content-Type: application/xml
TCN: choice
Vary: negotiate
Alternates: {{profile "<urn:example:namespaces:ns1
http://example.com/schema/schema-3
urn:example:namespaces:ns2
http://example.com/schema/schema-4>"}
{type application/xml}}
Link: rel="self";
type="application/xml";
profile="<urn:example:namespaces:ns1
http://example.com/schema/schema-3
urn:example:namespaces:ns2
http://example.com/schema/schema-4>",
rel="alternate";
type="application/xml";
profile="<urn:example:namespaces:ns1
http://example.com/schema/schema-3
urn:example:namespaces:ns2
http://example.com/schema/schema-4>"