HATEOAS for ASP.NET Core MVC
This adds simple HATEOAS with JSON support for ASP.NET Core MVC applications.
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": "[email protected]"
}
},
{
"_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": "[email protected]"
}
},
{
"_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": "[email protected]"
}
}
]
}