Condividi tramite


Advertising support for OData in web pages

Most browsers today will automatically enable their RSS/Atom reader option when you're on a page that has a feed in it. This is because the page has one or more <link> elements pointing to RSS/Atom endpoints, for example:

<link rel="alternate" type="application/rss+xml" title="Pablo Castro&#39;s blog (RSS 2.0)" href="https://blogs.msdn.com/b/pablo/rss.aspx" />

It would be great if all OData clients could automatically discover the location of the data feed that has the data represented by the current web page, or more in general, by the document fetched through some arbitrary URL. We had this discussion with Scott some time ago and he rolled the results in the NerdDinner.com site, but I failed to post this so it stays documented somewhere and others can follow, so here it goes.

Servers can advertise the OData endpoints that correspond to a resource using two mechanisms. Ideally servers would implement both, but sometimes limitations in the hosting environment and such may make it hard to support the header-based approach.

Using <link> elements

The first mechanism consists of adding one or more <link> headers to any HTML web page that shows data where that data can also be accessed as an OData feed using some other URL. There are two kinds of links for OData, those that direct clients to the service root (usually where the service document lives)and those that point at the specific dataset that corresponds to the data displayed in the page (e.g. point to a specific collection and includes whatever filters and sort order is used for display). Taking the example from the home page of NerdDinner.com:

<link rel="odata.service" title="NerdDinner.com OData Service" href="/Services/OData.svc" />
<link rel="odata.feed" title="NerdDinner.com OData Service - Dinners" href="/Services/OData.svc/Dinners" />

In this example the relation "odata.service" indicates that the href has a URL pointing to the root of a service and the relation "odata.feed" specifies the URL to the specific dataset for the page (dinners in this case). Note that it's perfectly fine to have multiple of each, although I would expect that the common thing to do would be go have one "odata.service" and zero or more "odata.feed", depending on the specific page you're looking at.

If your web page has the typical syndication icon to indicate that it has feeds in it, and you'd like to indicate visually that it also has links to OData feeds you can use the OData icon like NerdDinner.com does (next to the syndication icon on the right in the screenshot):

image

Using links in response headers

There is a proposal currently in-flight to standardize how servers can send links to related resources of a given resource using response headers instead of including them as part of the content of the response body. This is great because it means you don't have to know how to parse the content-type of the body (e.g. HTML) in order to obtain a link. In our context, your OData client wouldn't need to do any HTML parsing to obtain the OData feed related to a web page or some other random resource obtained through a user-provided URL.

The "Web Linking" proposal is described in the current draft in the IETF web site:

https://datatracker.ietf.org/doc/draft-nottingham-http-link-header/

As for the specifics for OData we would define two relations, "https://odata.org/link/service" and "https://odata.org/link/feed", corresponding to the "odata.service" and "odata.feed" relations used in the <link> element above. So for NerdDinner.com these would look like this in the response header section:

Link: </Services/OData.svc/>; rel="https://odata.org/link/service"; title="NerdDinner.com OData Service"
Link: </Services/OData.svc/Dinners/>; rel="https://odata.org/link/feed"; title="NerdDinner.com OData Service - Dinners"

For all folks hosting OData services, please consider adding one or if possible both of these to advertise your services. For anybody writing a client, this is the best way to discover services given an arbitrary URL that may point to a web page or something like that, and you can still make it nicely redirect to the right location and things will "just work" for your users.

-pablo

Comments