Fluent validations. A hands-on introduction.
Tell your clients what they are doing wrong :)
TL;DR
No time to lose? Check out this repository😊!
Introduction
Straight to the point! 😄
Let’s imaging we need to develop and REST-API. For the sake of the example, we will build the API using Asp.Net core with C#.
This API will have one endpoint that will:
- Receive a parameter from a header named header-name.
- Receive a parameter from the query named query-property-name.
- Receive two dates from the request body named pastDate and futureDate.
Basically, a curl request to this endpoint would look something like this:
curl --location --request GET 'https://localhost:5001/fv?query-prop-name=10' \
--header 'header-prop-name: header-value' \
--header 'Content-Type: application/json' \
--data-raw '{
"Date1": 1,
"Date2": 2
}'
Validations
Because we want to see how well FluentValidations work, let’s say we have the following rules our request must follow:
- The body must be informed.
- The futureDate must be larger than the pastDate.
- The pastDate must be larger than or equal to 1.
- The header must be informed and can not be empty.
- The query parameter must be informed, can not be empty, and must be greater than or equal to 0.
To do so, create the endpoint in C# as follows:
[ApiController]
[Route("[controller]")]
public class FVController : ControllerBase
{
public FVController()
{
}
[HttpGet]
public IActionResult Get([FromQuery] RequestToValidate request)
{
return Ok();
}
}
where the RequestToValidate.cs class is:
public class RequestToValidate
{
[FromHeader(Name = ApiConstants.HeaderName)]
public string PropertyFromHeader { get; set; } [FromQuery(Name = ApiConstants.QueryPropertyName)]
public int? PropertyFromQuery { get; set; } [FromBody]
public RequestBody Body { get; set; } public class RequestBody
{
public int PastDate { get; set; }
public int FutureDate { get; set; }
}
}
Then, inject in the DI container the following class by adding this to your startup.cs class:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(); services.AddMvc().AddFluentValidation();
services.AddTransient<IValidator<RequestToValidate>, RequestToValidateValidator>();
}
Run the API by pressing F5 and call the GET endpoint. You will receive a response like this one:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|cd6c6f05-4f8c3911f4c0410d.",
"errors": {
"header-name": [
"header-name must be informed as a header"
],
"query-property-name": [
"query-property-name must be informed as a query parameter"
],
"body.PastDate": [
"PastDate must be larger or equal to 1.",
"FutureDate must be after PastDate"
]
}
}
And that is all😊❗ Easy, right?