oEmbed

oEmbed "is a format for allowing an embedded representation of a URL on third party sites."

You provide a resource URL (and optionally some parameters) to a service URL, and the service URL returns XML, JSON or HTML which you can use to render an embedded representation of that resource.

What's wrong with just using HTTP's existing mechanisms for this? Why invent something new?

Here's how the default oEmbed example (no parameters, returning the JSON default) could work using stock HTTP:

oEmbed

HTTP/1.1

Resource URL

http://www.flickr.com/photos/bees/2341623661/

http://www.flickr.com/photos/bees/2341623661/

Service URL

http://www.flickr.com/services/oembed/?url=
 http%3A//www.flickr.com/photos/bees/2341623661/

http://www.flickr.com/photos/bees/2341623661/

Actual request

GET /services/oembed/?url=
 http%3A//www.flickr.com/photos/bees/2341623661/ HTTP/1.1
Host: www.flickr.com

GET /photos/bees/2341623661/ HTTP/1.1
Host: www.flickr.com
Accept: application/json;oEmbed

Server response

{
     version: '1.0',
     type: 'photo',
     width: 240,
     height: 160,
     title: 'ZB8T0193',
     url:
      'http://farm4.static.flickr.com/3123/
       2341623661_7c99f48bbf_m.jpg',
     author_name: 'Bees',
     author_url: 'http://www.flickr.com/photos/bees/',
     provider_name: 'Flickr',
     provider_url: 'http://www.flickr.com/',

{
     version: '1.0',
     type: 'photo',
     width: 240,
     height: 160,
     title: 'ZB8T0193',
     url:
      'http://farm4.static.flickr.com/3123/
       2341623661_7c99f48bbf_m.jpg',
     author_name: 'Bees',
     author_url: 'http://www.flickr.com/photos/bees/',
     provider_name: 'Flickr',
     provider_url: 'http://www.flickr.com/',

Accept headers are designed to request specific representations of resources. Provide an IANA content type and any parameters separated by semicolons. We use the oEmbed parameter, since without it we might get a JSON representation of the page, instead of a JSON representation of the embedded version. That request is 100% unambiguous for a server that understands it, and anything else should return 406 Not Acceptable.

Valid responses work the same. The only difference is optimized requests and no need for a separate service handler. You could even specify the version number along with the oEmbed parameter.

oEmbed

HTTP/1.1

With optional parameters

GET /services/oembed/?url=
 http%3A//www.flickr.com/photos/bees/2362225867/
 &maxwidth=300&maxheight=400&format=json HTTP/1.1
Host: www.flickr.com

GET /photos/bees/2362225867/ HTTP/1.1
Host: www.flickr.com
Accept: application/json;oEmbed=1.0;maxwidth=300;maxheight=400

Different content type

GET /oembed/?url=
 http%3A//www.iamcal.com/linklog/1206113631/
 &format=xml HTTP/1.1
Host: iamcal.com

GET /linklog/1206113631/ HTTP/1.1
Host: iamcal.com
Accept: text/xml;oEmbed=1.0

oEmbed specifies an optional cache_age response item. Why? HTTP already has Expires.

Service discovery could be improved if, instead of creating something new, you resurrect older HTTP headers from previous or experimental RFCs. RFC 2068 (the first HTTP/1.1 RFC) provided for alternate representation descriptions at the header level, saving you from HTML-based autodiscovery. While left out of RFC 2616, the Alternates header was not explicitly deprecated (although URI was), and experimental RFC 2295 provides a syntax for it. Instead of publishing service URLs, you could just make a HEAD request against the desired resource and receive something like:

Autodiscovery request

HEAD /photos/bees/2341623661/ HTTP/1.1
Host: www.flickr.com

Server response

HTTP/1.x 200 OK
Alternates: {"" 0.0 {type application/json} {features oEmbed}},
            {"" 0.0 {type text/xml} {features oEmbed}} 

The empty string is a valid relative URI representing the current URI. 0.0 is the quality of the representation: specifying an essentially useless quality ensures it will not be accidentally or automatically selected by a user-agent. The content type follows, either JSON or XML, per the oEmbed specification. Finally, the features tag list specifies the oEmbed nature of the alternate resource (the features tag list is used to define a property or explain the quality of the variant). We could also use an extension attribute instead:

Server response

HTTP/1.x 200 OK
Alternates: {"" 0.0 {type application/json} {x-oEmbed 1.0}},
            {"" 0.0 {type text/xml} {x-oEmbed 1.0}} 

The x- prefix denotes an experimental extension; this would not necessarily be necessary in this case of a proper extension. The version number token could provide the client with complete understanding of the server's response, particularly in the case of future oEmbed versions.

Differential GET

Differential GET requests are a simple extension to traditional HTTP/1.1 GET requests. Existing methods for determining if resources have changed are maintained: ETags are preferred, but modification dates are usable.

The difference is an additional Accept-Encoding being supplied by the client: gdiff. If the server determines that the client is out of date and it is capable of computing a difference between the client's version and the current version, it may respond with a Content-Encoding of gdiff and provide a binary difference, which the client can apply.

Content-Length and Content-MD5 headers can be used to ensure the gdiff is received intact; these apply to the gdiff, not to the final reconstructed file. The modification date, content type and etag do apply to the reconstructed file.

The application of differences to content ranges is undefined, but is likely mutually exclusive.

Rationally, this would be a 206 Partial Content response, with the range being the entire file, as that is what is affected by the diff, e.g. Content-Range: bytes 0-8191/8192 for an 8K file.

This is basically a partial reimplementation of the recommendations provided by Digital and AT&T in 1997: http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-97-4.html

JustUseHTTP (last edited 2008-05-10 04:25:12 by Vitorio Miliano)