diff --git a/Apps/Api/Api.csproj b/Apps/Api/Api.csproj index 842a770..2751af7 100644 --- a/Apps/Api/Api.csproj +++ b/Apps/Api/Api.csproj @@ -1,7 +1,21 @@ + + true + $(NoWarn);1591 + + + + + + + + + + net5.0 + diff --git a/Apps/Api/Controllers/LinksController.cs b/Apps/Api/Controllers/LinksController.cs new file mode 100644 index 0000000..9c2671b --- /dev/null +++ b/Apps/Api/Controllers/LinksController.cs @@ -0,0 +1,44 @@ +using System.Threading.Tasks; +using HN.Application; +using MediatR; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace Api.Controllers +{ + [ApiController] + [Route("api/[controller]")] + public sealed class LinksController : ControllerBase + { + private readonly IMediator _bus; + + public LinksController(IMediator bus) + { + _bus = bus; + } + + /// + /// Retrieve all links already posted. + /// + /// + [ProducesResponseType(typeof(LinkDto[]), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public async Task GetLinks() + { + return Ok(await _bus.Send(new ListLinksQuery())); + } + + /// + /// Post a new link. + /// + /// + /// + [HttpPost] + public async Task CreateLink(AddLinkCommand command) + { + var result = await _bus.Send(command); + + return Created("blabla", result); + } + } +} \ No newline at end of file diff --git a/Apps/Api/HttpExecutingUserProvider.cs b/Apps/Api/HttpExecutingUserProvider.cs new file mode 100644 index 0000000..57c3081 --- /dev/null +++ b/Apps/Api/HttpExecutingUserProvider.cs @@ -0,0 +1,32 @@ +using System; +using HN.Application; +using HN.Infrastructure.Identity; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Identity; + +namespace Api +{ + public sealed class HttpExecutingUserProvider : IExecutingUserProvider + { + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly UserManager _userManager; + + public HttpExecutingUserProvider(IHttpContextAccessor httpContextAccessor, UserManager userManager) + { + _httpContextAccessor = httpContextAccessor; + _userManager = userManager; + } + + public Guid GetCurrentUserId() + { + var uid = _userManager.GetUserId(_httpContextAccessor.HttpContext.User); + + if (!Guid.TryParse(uid, out Guid result)) + { + throw new UserNotConnected(); + } + + return result; + } + } +} \ No newline at end of file diff --git a/Apps/Api/Startup.cs b/Apps/Api/Startup.cs index d982d09..bebf575 100644 --- a/Apps/Api/Startup.cs +++ b/Apps/Api/Startup.cs @@ -1,12 +1,24 @@ +using System; +using HN.Application; +using HN.Infrastructure; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace Api { + public class MockExecutingContext : IExecutingUserProvider + { + public Guid GetCurrentUserId() + { + return Guid.NewGuid(); + } + } + public class Startup { public Startup(IConfiguration configuration) @@ -20,21 +32,43 @@ namespace Api // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { + services.AddHN(Configuration).ResolveConnectedUserWith(); + services.AddHttpContextAccessor(); + // Permet d'avoir des routes en lowercase + services.Configure(options => + { + options.LowercaseUrls = true; + options.LowercaseQueryStrings = true; + }); + + services.AddControllers(); + services.AddSwaggerDocument(d => + { + d.PostProcess = od => + { + od.Info.Title = "Hacker news like API in .Net"; + }; + d.SchemaType = NJsonSchema.SchemaType.OpenApi3; + }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { + app.UseOpenApi(); + if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); + app.UseSwaggerUi3(); } app.UseRouting(); app.UseEndpoints(endpoints => { + endpoints.MapControllers(); endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Hello World!"); diff --git a/Apps/Api/UserNotConnected.cs b/Apps/Api/UserNotConnected.cs new file mode 100644 index 0000000..87658b5 --- /dev/null +++ b/Apps/Api/UserNotConnected.cs @@ -0,0 +1,12 @@ +using System; + +namespace Api +{ + public sealed class UserNotConnected : Exception + { + public UserNotConnected() : base("User not connected!") + { + + } + } +} \ No newline at end of file diff --git a/Apps/Api/appsettings.json b/Apps/Api/appsettings.json index d9d9a9b..55f4a8f 100644 --- a/Apps/Api/appsettings.json +++ b/Apps/Api/appsettings.json @@ -6,5 +6,8 @@ "Microsoft.Hosting.Lifetime": "Information" } }, + "ConnectionStrings": { + "Default": "Data Source=../Website/hn.db" + }, "AllowedHosts": "*" } diff --git a/README.md b/README.md index b34dc6b..84cb22b 100644 --- a/README.md +++ b/README.md @@ -167,13 +167,17 @@ $ cd Api $ dotnet new gitignore ``` +L'attribut ApiController : https://docs.microsoft.com/en-us/aspnet/core/web-api/?view=aspnetcore-5.0#apicontroller-attribute + +On ajoute NSwag pour la génération de la documentation avec `dotnet add package NSwag.AspNetCore`. + Pour plus tard, pour la génération de doc : project.csproj true - bin\YourApi.XML + $(NoWarn);1591 ## Docker