diff --git a/PhonebookService.Api/Controllers/PhonebookController.cs b/PhonebookService.Api/Controllers/PhonebookController.cs new file mode 100644 index 0000000..c7d0bd0 --- /dev/null +++ b/PhonebookService.Api/Controllers/PhonebookController.cs @@ -0,0 +1,103 @@ +using FluentValidation; +using FluentValidation.Results; +using Microsoft.AspNetCore.Mvc; +using PhonebookService.Domain.Models; +using PhonebookService.Domain.Queries; +using PhonebookService.Domain.Repositories; + +namespace PhonebookService.Api.Controllers; + +[ApiController] +[Route("api/v1/[controller]")] +public class PhonebookController : Controller +{ + private readonly ILogger _logger; + private readonly IPhonebookRepository _book; + private readonly IValidator _validator; + + public PhonebookController(ILogger logger, IPhonebookRepository book, IValidator validator) + { + _logger = logger; + _book = book; + _validator = validator; + } + + [HttpGet(Name = "Get")] + [ProducesResponseType(StatusCodes.Status200OK)] + public async Task GetAsync([FromQuery]PhonebookFilterQuery? query) + { + ICollection data = await _book.GetItemsAsync(query ?? new()); + + return Json(data); + } + + [HttpGet("{id}", Name = "GetOne")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetItemAsync(int id) + { + PhonebookRecord? record = await _book.GetItemByIdAsync(id); + + if (record is null) + return NotFound(); + + return Json(record); + } + + [HttpPost(Name = "Create")] + [ProducesResponseType(StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public async Task CreateItemAsync([FromBody]PhonebookRecord item) + { + ValidationResult result = await _validator.ValidateAsync(item); + + if (!result.IsValid) + { + foreach (var i in result.Errors) + ModelState.AddModelError(i.ErrorCode, i.ErrorMessage); + + return BadRequest(); + } + + PhonebookRecord entry = await _book.CreateItemAsync(item); + + return CreatedAtRoute("Get", routeValues: new { id = entry.Id }, value: entry); + } + + [HttpPost("{id}", Name = "Update")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public async Task UpdateItemAsync(int id, [FromBody]PhonebookRecord item) + { + ValidationResult result = await _validator.ValidateAsync(item); + + if (!result.IsValid) + { + foreach (var i in result.Errors) + ModelState.AddModelError(i.ErrorCode, i.ErrorMessage); + + return BadRequest(); + } + + item.Id = id; + PhonebookRecord entry = await _book.UpdateItemAsync(item); + + return Json(entry); + } + + [HttpDelete("{id}", Name = "Delete")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public async Task DeleteItemAsync(int id) + { + PhonebookRecord? item = await _book.GetItemByIdAsync(id); + + if (item is null) + return NotFound(); + + await _book.DeleteItemAsync(item); + + return NoContent(); + } +} diff --git a/PhonebookService.Api/Program.cs b/PhonebookService.Api/Program.cs index 06befba..50044c2 100644 --- a/PhonebookService.Api/Program.cs +++ b/PhonebookService.Api/Program.cs @@ -1,11 +1,32 @@ +using FluentValidation; +using PhonebookService.Domain.Models; +using PhonebookService.Domain.Validators; +using PhonebookService.Infrastructure; + WebApplicationBuilder builder = WebApplication.CreateBuilder(args); // Add services to the container. +builder.Services.AddLogging(options => +{ + options.AddConfiguration(builder.Configuration.GetSection("Logging")); + options.AddConsole(); + options.AddDebug(); + options.AddEventSourceLogger(); +}); + builder.Services.AddControllers(); + +// Settings up infrastructure layer +builder.Services.ConfigureInfrastructure(builder.Configuration, enableSensitiveDataLogging: builder.Environment.IsDevelopment()); + +// Adding validators +builder.Services.AddScoped, PhonebookRecordValidator>(); + // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); -builder.Services.AddSwaggerGen(); +builder.Services.AddSwaggerGen(options => + options.SwaggerDoc("v1", new() { Title = "PhonebookService API", Version = "v1" })); WebApplication app = builder.Build(); @@ -13,7 +34,7 @@ WebApplication app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); - app.UseSwaggerUI(); + app.UseSwaggerUI(options => options.SwaggerEndpoint("/swagger/v1/swagger.json", "PhonebookService API v1")); } app.UseHttpsRedirection(); @@ -22,4 +43,6 @@ app.UseAuthorization(); app.MapControllers(); +app.MapGet("/", () => Results.Redirect("/api/v1/Phonebook")); + app.Run();