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.


  • There are so many HATEOAS formats out there, it’s hard to choose just one. Siren is one that I’ve seen less often and I don’t like how it interferes with my JSON object but I hear the argument that it supports actions which HAL doesn’t. JSON-LD/Hydra seem standards driven and my JSON stays the same with some metadata at the top but it’s more complicated and requires deep thinking for every entity. It would be nice if we could all agree on one or two standards…

    • Excellent comment. Thank you.

      I agree with you in regards to Siren. I’m not completely in love with it, nor really any media type. The fact that it supports actions is the bonus for me. Every media type that I’ve found seems to be missing something on how I interpret or feel like it should work.

      • Agreed. Right now, I feel like HAL is good for simple scenarios (It’s what I’ve been using) and Hydra for more complex (Only looked into it). There is also GraphQL which is more popular in the Java world but less so in .NET.