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. This specific posts covers hypermedia clients. 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.Hypermedia Clients
My perception is that most people new to hypermedia driven APIs think that consuming hypermedia happens via a magic library. Or via some code generation that ultimately gives you a client library that understands every endpoint. I’m not sure why this is, possibly the client code gen libraries behind SOAP/WSDL or Swagger/OpenAPI. In my experience developing and consuming a hypermedia driven API, there is no magic. Your consuming client needs to understand the content beyond just the media type for a given URI. In a custom application, you likely want to show the user specific actions within the UI depending on if the link or action is returned in the API payload. In our Todo application from my HATEOAS post, the action of marking a Todo item as complete was conditional. It wasn’t available on every Todo item. My UI would likely reflect that. The same goes with links to other resources, they may or may not be in the payload.Siren Browsers
However, you can make a generic UI if you use a defined media type. Since I’ve been using Siren in my previous examples, we will keep with that for a client examples. These Siren browsers are no different then HTML browsers. They understand the media type and render UI. What this shows is the ability for you to create re-usable components based on the specifics of the payload your server is returning. In my Todo example, I could create a specific UI component that is used when retrieving a Todo item from the API.Siren Client Helper Libraries
You technically don’t need any libraries to start consuming a siren payload. As long as you understand what content inside the siren schema is going to be returned you should be able to deserialize the JSON into your own type and do what you want. Super Siren is a pretty good example of a Javascript helper library. It has helpers for making HTTP requests and then performing navigation and actions.Next
Looking ahead I will start to develop our ASP.NET Core client. As well as discuss why why URLs become opaque. Meaning there is no difference betweenhttp://domain/api/todo/123and
http://domain/cf2b6d63-9a7f-4dc6-9989-f12bb8af7715If anyone has any other suggestions or recommendations about this series, please leave comment or let me know on twitter.
One thing to note in the last example is that the client “knows” there is an action called “complete”! How does it know that 🙂
Yes. As the developer writing the client, you must understand the actions that may be available for a given resource. Meaning you must either understand the endpoint based on how you got there or you understand “class” of the siren payload. But ultimately there is no magic, you have to write the code based on some understanding.
So your question, if I got the gist correctly is, how as I as a developer understand the endpoints/classes and actions that maybe returned? Good question. The easy answer is some formalized documentation about resources and workflow. In real world application that we create both client and server, we simply use the payload themselves when developing the client to understand both.
I’d be curious if there was a way to generate a swagger/open api’ish way but not being dependent on URIs (since they mean nothing) but rather resource names and the associated relations and actions?
Yup I’m not sure of anything Swagger related, @mcintyre321 proposed a /glossary type endpoint in your api so that the client could get the rels/actions up front etc so that might work or as you say documentation of the actions on the API you are consuming would be another route but if you end up documenting the actions and the fields etc they require half of me thinks sod it might as well just use swagger.
Ya a glossary is good way to explain it. It would describe the rels and actions that may be available in the payload. I say may because the server ultimately deciding if they get returned based of state and other things.
The issue with documenting endpoints (ala swagger) is that you are saying what the actual URI is and the client then hardcodes that URI. Also there is no describing the workflow. That’s exactly what I get out of hypermedia. The URIs are opaque and the server decides the workflow that the client would follow.
Very true. I’m just underwhelmed and disappointed with hypermedia clients so am keen to see what you suggest for C# and would also like to see more on how the client knows what to do with an action eg.fields to include etc 🙂
Good, Here APIs think that consuming hypermedia happens via a magic library. like this by illinoismedicalimmigration.com