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:
Sponsor: Do you build complex software systems? See how NServiceBus makes it easier to design, build, and manage software systems that use message queues to achieve loose coupling. Get started for free.
SirenI 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.
LibrariesThere are a few projects/libraries that help with generating a output that follows the siren spec.
- FluentSiren: Fluent API to build specification enforced siren entities.
- SirenDotNet: Hard-coded classes and example code to implement the hypermedia format.
- Web Api Hypermedia Extensions: Extensions for ASP.NET Core projects
- Migrap.AspNetCore.Hateoas: Hypermedia as the Engine of Application State) framework for ASP.NET Core.
- Nancy.Siren: Siren hypermedia payloads when using the correct Accept header in your Nancy application.
Nancy.SirenI 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.HateoasThis is a project I found on GitHub that takes the same approach as Nancy.Siren by handling requests that accept
application/vnd.siren+jsonby 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.
TodoSo 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
Relation and ActionsWhat’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.
StateConverterIn 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.
NextAll 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.
- Building a Self Descriptive HTTP API in ASP.NET Core
- Object as Resource
- Hypermedia Clients
5 thoughts to “Self Descriptive HTTP API in ASP.NET Core: Siren”
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.
GraphQL isn’t really REST though, right?
REST is an architectural guideline, GraphQL is just a query syntax. In theory I think you could combine both. Some interesting links I read after your question: