A dead simple HATEOAS provider for ASP.NET Core
While doing some research on Hypermedia As The Engine Of Application State (HATEOAS), I came across some great HATEOAS providers for ASP.NET Web API and ASP.NET Core MVC, but they didn't quite fit my need, so I created my own one.
Grab the source code from my GitHub repo here: https://github.com/faniereynders/aspnetcore-hateoas
Getting started
The JSON HATEOAS provider extends the IMvcBuilder
and is used like the following:
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvc()
.AddHateoas(...);
//other services
}
Making a request to one of the APIs in your application with Accept
header set as application/json+hateoas
, will return the HATEOAS payload containing the expected resource(s).
Example
Given the following DTO in your application:
public class PersonDto
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
With the following Controller:
[Route("api/[controller]")]
public class PeopleController : Controller
{
[HttpGet(Name = "get-people")]
public IActionResult Get() {...}
[HttpGet("{id}", Name = "get-person")]
public IActionResult Get(int id) {...}
[HttpPost(Name = "create-person")]
public IActionResult Post([FromBody]PersonDto person) {...}
[HttpPut("{id}", Name = "update-person")]
public IActionResult Put(int id, [FromBody]PersonDto person) {...}
[HttpDelete("{id}", Name = "delete-person")]
public IActionResult Delete(int id) {...}
}
Wire up HATEOAS with the particular links:
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvc()
.AddHateoas(options =>
{
options
.AddLink<PersonDto>("get-person", p => new { id = p.Id })
.AddLink<List<PersonDto>>("create-person")
.AddLink<PersonDto>("update-person", p => new { id = p.Id })
.AddLink<PersonDto>("delete-person", p => new { id = p.Id });
});
//other services
}
And executing this request:
GET /api/people HTTP/1.1
Accept: application/json+hateoas
Will result in the following response:
{
"_links": [
{
"href": "http://localhost:52691/api/people",
"rel": "create-person",
"method": "POST"
}
],
"items": [
{
"_links": [
{
"href": "http://localhost:52691/api/people/1",
"rel": "get-person",
"method": "GET"
},
{
"href": "http://localhost:52691/api/people/1",
"rel": "update-person",
"method": "PUT"
},
{
"href": "http://localhost:52691/api/people/1",
"rel": "delete-person",
"method": "DELETE"
}
],
"data": {
"id": 1,
"name": "Fanie",
"email": "fanie@mail.com"
}
},
{
"_links": [
{
"href": "http://localhost:52691/api/people/2",
"rel": "get-person",
"method": "GET"
},
{
"href": "http://localhost:52691/api/people/2",
"rel": "update-person",
"method": "PUT"
},
{
"href": "http://localhost:52691/api/people/2",
"rel": "delete-person",
"method": "DELETE"
}
],
"data": {
"id": 2,
"name": "Maarten",
"email": "maarten@example.com"
}
},
{
"_links": [
{
"href": "http://localhost:52691/api/people/2",
"rel": "get-person",
"method": "GET"
},
{
"href": "http://localhost:52691/api/people/2",
"rel": "update-person",
"method": "PUT"
},
{
"href": "http://localhost:52691/api/people/2",
"rel": "delete-person",
"method": "DELETE"
}
],
"data": {
"id": 2,
"name": "Marcel",
"email": "marcel@example.com"
}
}
]
}
Grab the source code from my GitHub repo here: https://github.com/faniereynders/aspnetcore-hateoas
This project will make its way to NuGet soon.
It cannot get any simpler. Comments and feedback welcome!