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.
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.- 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.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 acceptapplication/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
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:
https://philsturgeon.uk/api/2017/01/24/graphql-vs-rest-overview/
https://medium.freecodecamp.com/give-it-a-rest-use-graphql-for-your-apis-40a2761e6336
https://medium.com/@ottovw/rest-api-downfalls-and-dawn-of-graphql-dd00991a0eb8