Self Descriptive HTTP API in ASP.NET Core: HATEOAS

This post is in my Self Descriptive HTTP API in ASP.NET Core series. It demonstrates how to design an HTTP API like a regular HTML website. Bringing the concepts of links and actions to your API allows your clients to consume it with ease.

If you’re new to this series, here are earlier posts to get up to speed:

If you have any questions, please follow me on Twitter.


Actions

In my last post I covered outputting a siren hypermedia payload from our ASP.NET Core MVC application.  Specifically I showed linking to each Todo item within the collection.

One aspect of Siren that I mentioned I like is it’s ability to specify actions.  This is important for me because it’s what I first started thinking about when working on my most recent HTTP API a couple years ago.

I needed to the ability to tell the consuming client (Angular) about subsequent actions it could take.

Workflow

Wanting to describe actions in our API responses revolved around permissions and workflow.

For example, if the requesting user didn’t have permissions to perform a specific action, I wanted them to know it. Having this information within the content of your response, we could make the client show or hide certain aspects of the UI depending on the response it received.

Same goes with workflow.  Depending on the state of the system, we could conditionally send down links and actions (commands and queries) through our responses to the client.

Dumb Clients

This made our consuming clients really dumb about workflow.  The knowledge about when an action can be performed based off the state of the system was determined by the server.

This is my biggest issue without using hypermedia.  Is that the client must understand when it can make calls to particular resources.  Meaning it must understand workflow.  For me this was incredibly problematic as some of the workflow is non trivial.

This logic already existed on the server for validating if a command/request could be executed based on the current state of the system.

Demo

I realize this is a trivial demo, but I hope it gets the very simple idea of the server defining the workflow.

We are going to create another converter for a single Todo.  We will provide Actions which allow the client to delete or mark a Todo as complete.

Once a Todo is complete, that action is no longer relevant.

When we access the resource for an individual Todo item, we end up with the following siren payload.

HATEOAS

If our client were to then make a call to the complete action, its response, along with any additional call to the previous GET endpoint results in the complete action no longer being returned in the payload.

HATEOAS

Hypermedia as the Engine of Application State

This is really what links and actions are all about.  Guiding the client to various resources in your API based on the state of the system.

You may of also heard of this with the horrific acronym of HATEOAS.

Regardless, I find the concept incredibly powerful for guiding clients down a path based on the state of your system.

Source

All the source code for my demo is available on GitHub.

Looking ahead we will dig into developing clients consuming our API and the (not) versioning.

If anyone has any other suggestions or recommendations about this series, please leave comment or let me know on twitter.


Self Descriptive HTTP API in ASP.NET Core: Siren

This post is in my Self Descriptive HTTP API in ASP.NET Core series. It demonstrates how to design an HTTP API like a regular HTML website. Bringing the concepts of links and actions to your API allows your clients to consume it with ease.

If you’re new to this series, here are earlier posts to get up to speed:

If you have any questions, please follow me on Twitter.


Siren

I mentioned that Siren was one media type that appeals to me because it supports both links and actions.  This is important because I generally build core parts of an application following CQRS by implementing commands that change the state of my system or queries that return state.

Libraries

There are a few projects/libraries that help with generating a output that follows the siren spec.

With all these libraries, the number of downloads on NuGet is really low. However, I think they all have value in at least looking at the source to get some ideas if you aren’t comfortable with taking a dependency on them.

Nancy.Siren

I discovered Jonathan Channon’s Nancy.Siren a couple months ago and really liked the idea of having your endpoints return your usual DTO and having a response processor mutate your DTO into a Siren payload.

If you use Nancy (as I do) this is worth looking at.  I plan on digging into this a bit more for all you NancyFX fans.

Migrap.AspNetCore.Hateoas

This is a project I found on GitHub that takes the same approach as Nancy.Siren by handling requests that accept application/vnd.siren+json by transforming them to a siren payload.

I’ve forked this and have added a ASP.NET Core MVC application to it to build a Todo demo.

All the source code you will find below through the rest of this post is available on GitHub.

Note: I’m intentionally leaving some snippets of setup code out of this blog post.  The demo source code in its entirety is pretty easy to follow.

Todo

So for some context about this Todo application.  I’ve got a simple model to represent a todo item.

I’ve setup a simple Controller that provides endpoints for performing the following:

  • Get all the Todo’s
  • Get an individual Todo
  • Add a Todo
  • Delete a Todo
  • Mark a Todo as complete

This should look at pretty familiar and straight forward.  Here’s a result in postman when getting the list of our Todo’s.

 

Relation and Actions

What’s missing from that payload are the related URIs or actions I could perform related to this resource or others.  As mentioned in my prior blog post about Hypermedia, is that where media types like Siren provide the ability to give your consuming clients this information.

StateConverter

In order to transform our collection of TodoModel’s into a siren payload we need to create an implementation of the IStateConverter.  We will return a Document that will describe the properties and entities (Todo’s) for this resource.  For each Todo we will also provide the URI of how to access it specifically.

 

Once we do this, if we make our HTTP call but this time specifying an Accept header of application/vnd.siren+json, we will get our siren payload.

 

Next

All the source code for my demo is available on GitHub.

In the next few posts we will start digging in more by adding actions and workflow based on application state.

If anyone has any other suggestions or recommendations about this series, please leave comment or let me know on twitter.


Self Descriptive HTTP API in ASP.NET Core: Hypermedia

This post is in my Self Descriptive HTTP API in ASP.NET Core series. It demonstrates how to design an HTTP API like a regular HTML website. Bringing the concepts of links and actions to your API allows your clients to consume it with ease.

If you’re new to this series, here are earlier posts to get up to speed:

Hypermedia

You probably have already heard the term hypermedia before.  Hypermedia and Hypertext are nothing new.  They were both coined in the 60’s by Ted Nelson.

You’ve definitely used hypermedia in the form of HTML.

HTML has a great set of tags that represent hypermedia.

When you are writing HTML and using <a>  <forms> <img>  <link> <script> tags you are proving information to the client about other navigation or actions they can perform.

Your browser is nothing more then a hypermedia client that understands HTML.  In the case of <a> or <form> the end user behind the browser ultimately decides if they are going to follow those links or submit the form.  You generally hit a a website either by navigating from another site, or manually enter the URI in your browsers address bar.  You then navigate the site via links and forms.  I generally don’t see people typing in every URI in there browser address bar 🙂

Googlebot (web crawler) is another great example of a hypermedia client that understands HTML.  It follows <a> tags through your site to crawl all the exposed pages.  Googlebot doesn’t know how to craw a random URI on your site unless you tell it.

It’s not magic.  It’s about returning a media type (content-type) and payload the client can understand.

APIs

What I find really interesting is even with how successful HTML is the popularity of using hypermedia in our HTTP API’s seems really low.

It’s not because of lack of media types.  HAL (Hypertext Application Language) was the first media type I discovered when starting thinking about the idea of linking one URI to another in my HTTP API.

I was late to the party since these ideas started coming to me several years after HAL was created in 2011.

Since then have been other media types that have gained some traction:

Actions

Following CQRS, I expose commands and queries and URIs.   Some media types like HAL don’t really give me the ability to specify how to perform various actions (commands) with payloads a user can invoke in the system.

However, a media type like Siren does.  The general idea can really be related to an HTML <form>

Here is a basic HTML form.  If you were creating an client that understood HTML you would be able to easily create a HTTP request to perform the action.

The above form describes an action.   If we wanted to create an HTTP request to submit this action, we have all the information in the form to build the request.

  • The URI is by action=”/books/add”
  • The HTTP verb used whith the method=”post”
  • The body of our request is defined by the <input> and <select> elements
  • The select <option>’s define valid valid for the price

Because we understand HTML specification, we can easily create the HTTP request as:

Self Descriptive

By using a media type like Siren we can start to develop HTTP APIs that are self descriptive.

It’s a combination of the content type and the message body that makes our API self descriptive.  You cannot just return arbitrary JSON and expect your clients to understand how to use it.  They must understand what the content is.

 

Next

To the code!  In my next post I’m going to start providing some sample code for creating an HTTP API in ASP.NET Core using Hypermedia.

If anyone has any other suggestions or recommendations about this series, please leave comment or let me know on twitter.