dev-notes/DotNet/ASP.NET/REST API.md

118 lines
2.7 KiB
Markdown
Raw Normal View History

2021-01-31 11:05:37 +01:00
# ASP .NET REST API
## Data Transfer Objects (DTOs)
2021-09-20 19:35:32 +02:00
A **DTO** is an object that defines how the data will be sent and received over the network (usually as JSON).
Without a DTO the JSON response (or request) could contain irrelevant, wrong or unformatted data.
2021-01-31 11:05:37 +01:00
Moreover, by decoupling the JSON response from the actual data model, it's possible to change the latter without breaking the API.
DTOs must be mapped to the internal methods.
2021-05-21 19:23:10 +02:00
In `EntityDTO.cs`:
2021-01-31 11:05:37 +01:00
```cs
namespace <Namespace>.DTOs
{
2021-05-21 19:23:10 +02:00
// define the data to be serialized in JSON (differs from model)
public class EntityDTO
2021-01-31 11:05:37 +01:00
{
// only properties to be serialized
}
}
```
2021-05-21 19:23:10 +02:00
### DTO mapping with Automapper
Required NuGet Packages:
- `AutoMapper`
- `AutoMapper.Extensions.Microsoft.DependencyInjection`
A good way to organize mapping configurations is with *profiles*.
2021-01-31 11:05:37 +01:00
In `EntitiesProfile.cs`:
```cs
using AutoMapper;
using <Namespace>.DTOs;
using <Namespace>.Model;
namespace <Namespace>.Profiles
{
public class EntitiesProfile : Profile
{
public EntitiesProfile()
{
2021-05-21 19:23:10 +02:00
CreateMap<Entity, EntityDTO>(); // map entity to it's DTO
2021-01-31 11:05:37 +01:00
}
}
}
```
2021-09-19 12:10:20 +02:00
## Controller (No View)
2021-09-20 19:35:32 +02:00
Uses [Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection) to receive a suitable implementation of `IEntityRepo`,
2021-09-19 12:10:20 +02:00
### Service Lifetimes
- `AddSingleton`: same for every request
- `AddScoped`: created once per client
- `Transient`: new instance created every time
In `Startup.cs`:
2021-01-31 11:05:37 +01:00
```cs
2021-09-19 12:10:20 +02:00
// This method gets called by the runtime. Use this method to add services to the container.
2021-01-31 11:05:37 +01:00
public void ConfigureServices(IServiceCollection services)
{
2021-09-19 12:10:20 +02:00
services.AddControllers();
services.AddScoped<IEntityRepo, EntityRepo>(); // map the interface to its implementation, needed for dependency injection
2021-01-31 11:05:37 +01:00
}
```
2021-09-19 12:10:20 +02:00
### Request Mappings
2021-01-31 11:05:37 +01:00
```cs
using <App>.Model;
using <App>.Repo;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
namespace <App>.Controllers
{
[Route("api/endpoint")]
[ApiController]
public class EntitiesController : ControllerBase // MVC controller w/o view
{
2021-05-21 19:23:10 +02:00
// service or repo (DAL) injection
2021-01-31 11:05:37 +01:00
private readonly IMapper _mapper; // AutoMapper class
[HttpGet] // GET api/endpoint
2021-05-21 19:23:10 +02:00
public ActionResult<EntityDTO> SelectAllEntities()
2021-01-31 11:05:37 +01:00
{
2021-05-21 19:23:10 +02:00
...
2021-01-31 11:05:37 +01:00
2021-05-21 19:23:10 +02:00
return Ok(_mapper.Map<EntityDTO>(entity));
2021-01-31 11:05:37 +01:00
}
}
}
```
2021-05-21 19:23:10 +02:00
## Simple API Controller
2021-01-31 11:05:37 +01:00
```cs
2021-05-21 19:23:10 +02:00
[Route("api/endpoint")]
[ApiController]
public class EntitiesController : ControllerBase
2021-01-31 11:05:37 +01:00
{
2021-05-21 19:23:10 +02:00
// service or repo (DAL) injection
2021-01-31 11:05:37 +01:00
2021-05-21 19:23:10 +02:00
[HttpGet]
public ActionResult<TEntity> SelectAll()
{
...
return Ok(entity);
2021-01-31 11:05:37 +01:00
}
}
```