DPS907 notes – Mon Oct 5

Link relations.

.

Hypermedia-driven web API

Modern web APIs must be hypermedia-driven.

This means that the response will include:

  • the data that you expect, and
  • links that enable you – the requestor – to determine what to do next.

The web API author should not have to provide out-of-band documentation or knowledge to the user of the web API.

This concept was identified in the hypermedia constraint section of Roy Fielding’s PhD thesis, “Architectural Styles and
the Design of Network-based Software Architectures”.

Please read the following:

Architectural Styles… thesis, by Roy Fielding; “representational state transfer” – REST – is discussed in Section 5.

“…multiple architectural constraints are needed to guide the behavior of components. REST is defined by four interface constraints: identification of resources; manipulation of resources through representations; self-descriptive messages; and, hypermedia as the engine of application state. These constraints will be discussed in Section 5.2.”

REST APIs must be hypertext-driven, in which Roy reminds us about some design principles.

.

How can I understand this concept?

Study the following screen capture. (Click to open it full-size in a new tab/window.)

web-page-1

.

How do you use this page? What is its purpose? What can you do next?

Next, study the following screen capture. (Click to open it full-size in a new tab/window.)

web-page-2

.

How do you use this page? What are its purposes? What can you do next?

Finally, study the following screen capture. (Click to open it full-size in a new tab/window.)

web-page-3

.

How do you use this page? What are its purposes? What can you do next?

With all three pages – any ANY page you view in a web browser – you innately know what you can do next. You can view the content. You can click links (including the browser’s “back” link). You can enter some data and process that data.

How can you implement this – what can you do next? – in a web service? With link relations.

.

Data and metadata available to the web API designer and user

The following list is a brief reminder of the list of data items and metadata that are available to web service designers and users:

  • HTTP method
  • URI
  • Request headers
  • Response headers
  • Message body, in general
  • Representation (of a resource)

Today, you will learn something about these:

  • Link relations
  • The HTTP OPTIONS method
  • Representations that enable a user/requestor to learn about the data that’s needed to add a new resource

.

A brief discussion of ‘links’…

Web client programmers are familiar with HTML ‘link’ elements:

  • a
  • img
  • link

You also know that the “HT” part of HTML expands to “hypertext”.

What kind of data is at the other end of a link in HTML?

Text?

Always?

Or can it be an image, a video, or some other media?

Yes, certainly the data could be any kind of internet media type.

Therefore, to help you make progress learning this topic, simply change your understanding (of a link target’s data type) a bit, so that you begin to think of a link as a ‘hypermedia‘ link, and not just as a hypertext link.

.

How do we use links in a web API?

In a web API, links are used to tell the requestor about state transitions.

In other words, they tell the requestor what can be done next.

For example, assume that a requestor asks for a single-item resource (e.g. a product). The web service returns a representation (the data) for that resource. It would be nice to include data and/or metadata that would tell the requestor whether that resource could be modified, or deleted. Or whether it was possible to add a new resource to the resource’s parent/collection.

.

Link relations

The solution is to use link relations. Using this solution, the response includes links that can guide the user through state transitions.

This is what Roy Fielding means when he writes that “hypermedia [is] the engine of application state”.

A link is a data object, delivered in-band, with the representation. When you define a link in a web service, you must also define its relationship to the current object.

For example, by convention, a single object must include a link to itself:

  • The value of the URI (aka href) will be the item’s URI
  • The value of the relationship (aka rel) will be ‘self’

If the single object is part of a collection, it must also include a link to its parent/collection:

  • The value of the URI (aka href) will be the item’s parent/collection
  • The value of the relationship (aka rel) will be ‘collection’

This design ensures that the responses from your web service are self-describing.

The IANA has published a list of standardized link relations. You can create your own, but use the standard link relations until you gain more experience.

.

Code example for today’s topics

From the code example repository, look at LinkRelationsIntro.

.

Preview of our design and coding plan

In general, we will follow these steps:

  1. Start with an existing project that works well.
  2. Add new resource model classes that support and enable link relations.
  3. For an entity, add new resource model classes that include link relations. Add new AutoMapper definition(s).
  4. Update controller code. Wrap the fetch result(s) in a resource model class that includes link relations, and configure the links.
  5. Add support for the HTTP OPTIONS method.
  6. Configure an entry point URI for the web service.

.

Are there standards (for expressing link relations) that we must follow?

No.

In today’s example, we create our own representations.

In the future, we may look at HAL and/or Collection+JSON. It’s possible that you may use one of those in the future (or design your own). Mike Amundsen is very interested in hypermedia representations, and has much to offer in this topic area.

Let’s get started on the steps listed above…

.

Start with an existing project that works well

You will learn this topic more effectively if you use an existing project that works well.

.

Add new resource model classes that support and enable link relations

Create a new source code file – perhaps named Links_vm – to the Controllers folder.

It will hold classes that support and enable link relations.

.

Overview of the design

There will be two versions of our design that supports link relations:

  1. a class for one item, and
  2. a class for a collection of items.

object-item-jsonFor one item (click the image to see it full-size in a new tab/window):

  • The class has two properties, ‘Links’ and ‘Item’
  • ‘Links’ is a collection of one or more Link objects
  • One Link is to ‘self’
  • Another Link is to its parent ‘collection’
  • ‘Item’ is the actual fetched result
  • The ‘Item’ also includes a Link to ‘self’

object-collection-jsonFor a collection of items (click the image to see it full-size):

  • The class has two properties, ‘Links’ and ‘Collection’
  • ‘Links’ is a collection of one or more Link objects
  • One Link is to ‘self’
  • ‘Collection’ is the actual fetched results
  • Each ‘Item’ in the collection includes a Link to ‘item’

.

Write the classes

We will need a Link class to model a hyperlink. At a minimum, it will need href and rel properties.

If you wished, in a future project, you could consider adding other properties, such as titlemethod, and content type.

.

Abstract class for the linked item

An abstract class will reduce the amount of code we write for resource models, if we also take advantage of generics and type injection. So, let’s do that: Write an abstract class, for a single item, that includes a T (type) parameter, as shown below:

abstract-class-structure

.

Do the same to create an abstract class for a collection of items.

.

For an entity, add new resource model classes that include link relations
Add new AutoMapper definition(s)

Our goal is to add a Link property to a suitable resource model class. That’s easy.

Then, remember to go the Global.asax.cs source code file and add an appropriate AutoMapper definition.

.

Update the object constructors
Wrap the fetch result(s) in a resource model class that includes link relations,
and configure the links

Our goal is to ‘wrap’ the result(s) in the new resource model class that includes link relations.

Based on what you’ve learned earlier, the code in the method does the following:

  1. Create an object (item or collection) that supports link relations
  2. Add a Link to ‘self’
  3. If you’re configuring an ‘Item’, add a Link to the ‘collection’
  4. Set its ‘Item’ or ‘Collection’ property to the fetched result(s)
  5. If you’re configuring a ‘Collection’, add a Link to ‘item’ to each item
  6. Return the now-full-configured object

.

Study the LinkRelationsIntro code example.

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Advertisements
%d bloggers like this: