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)
A **DTO** is an object that defines how the data will be sent and recieved over the network (usually as JSON).
Without a DTO the JSON response (or reqest) could contain irrilevant, wrong or unformatted data.
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)
Uses [Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection) to recieve a suitable implementation of `IEntityRepo`,
### 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
}
}
```