diff --git a/Apps/HackerNet.Api/Controllers/LinksController.cs b/Apps/HackerNet.Api/Controllers/LinksController.cs
new file mode 100644
index 0000000..9d4d2be
--- /dev/null
+++ b/Apps/HackerNet.Api/Controllers/LinksController.cs
@@ -0,0 +1,56 @@
+using HackerNet.Application;
+using HackerNet.Infrastructure.AspNet.Filters;
+using Microsoft.AspNetCore.Mvc;
+
+namespace HackerNet.Api.Controllers;
+
+[ApiController]
+[Route("/api/links")]
+public class LinksController : ControllerBase
+{
+ private readonly LinkService _linkService;
+
+ public LinksController(LinkService linkService)
+ {
+ _linkService = linkService;
+ }
+
+ ///
+ /// Retourne les derniers liens publiés de la plateforme.
+ ///
+ ///
+ [HttpGet]
+ public ActionResult GetLinks()
+ {
+ return _linkService.GetPublishedLinks();
+ }
+
+ ///
+ /// Récupère un lien par son identifiant.
+ ///
+ ///
+ ///
+ [HttpGet("{id:guid}")] // https://docs.microsoft.com/fr-fr/aspnet/core/fundamentals/routing?view=aspnetcore-6.0#route-constraint-reference
+ [CustomExceptionFilter]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ public ActionResult GetLinkDetail(Guid id)
+ {
+ return _linkService.GetLinkDetail(id);
+ }
+
+ ///
+ /// Publie un nouveau lien sur la plateforme
+ ///
+ ///
+ ///
+ [HttpPost]
+ [ProducesResponseType(StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(StatusCodes.Status201Created)]
+ public ActionResult PublishLink(PublishLinkCommand cmd)
+ {
+ var id = _linkService.PublishLink(cmd);
+
+ return CreatedAtAction(nameof(GetLinkDetail), new { id = id }, null);
+ }
+}
\ No newline at end of file
diff --git a/Apps/HackerNet.Api/HackerNet.Api.csproj b/Apps/HackerNet.Api/HackerNet.Api.csproj
new file mode 100644
index 0000000..3ae7d7a
--- /dev/null
+++ b/Apps/HackerNet.Api/HackerNet.Api.csproj
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(NoWarn);1591
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Apps/HackerNet.Api/Program.cs b/Apps/HackerNet.Api/Program.cs
new file mode 100644
index 0000000..c6ed57b
--- /dev/null
+++ b/Apps/HackerNet.Api/Program.cs
@@ -0,0 +1,20 @@
+using HackerNet.Infrastructure.AspNet;
+
+var builder = WebApplication.CreateBuilder(args);
+
+builder.Services.AddHackerNetServices();
+builder.Services.AddControllers();
+builder.Services.AddOpenApiDocument(d =>
+{
+ d.Title = "HackerNet API";
+});
+
+var app = builder.Build();
+
+app.UseOpenApi();
+app.UseSwaggerUi3();
+
+app.MapGet("/", () => "Hello World!");
+app.MapControllers();
+
+app.Run();
diff --git a/Apps/HackerNet.Api/Properties/launchSettings.json b/Apps/HackerNet.Api/Properties/launchSettings.json
new file mode 100644
index 0000000..a1c2d0c
--- /dev/null
+++ b/Apps/HackerNet.Api/Properties/launchSettings.json
@@ -0,0 +1,28 @@
+{
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:35593",
+ "sslPort": 44377
+ }
+ },
+ "profiles": {
+ "HackerNet.Api": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "applicationUrl": "https://localhost:7252;http://localhost:5230",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ }
+ }
+}
diff --git a/Apps/HackerNet.Api/api.http b/Apps/HackerNet.Api/api.http
new file mode 100644
index 0000000..1265606
--- /dev/null
+++ b/Apps/HackerNet.Api/api.http
@@ -0,0 +1,17 @@
+@url = https://localhost:7252
+
+GET {{url}}/api/links
+
+###
+
+POST {{url}}/api/links
+Content-Type: application/json
+
+{
+ "url": "https://localhost:7252/api/links",
+ "description": "kfjkljfe"
+}
+
+###
+
+GET {{url}}/api/links/7f92770b-e3ef-4443-ab5d-8aca6449530f
\ No newline at end of file
diff --git a/Apps/HackerNet.Api/appsettings.Development.json b/Apps/HackerNet.Api/appsettings.Development.json
new file mode 100644
index 0000000..ff66ba6
--- /dev/null
+++ b/Apps/HackerNet.Api/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
diff --git a/Apps/HackerNet.Api/appsettings.json b/Apps/HackerNet.Api/appsettings.json
new file mode 100644
index 0000000..4d56694
--- /dev/null
+++ b/Apps/HackerNet.Api/appsettings.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "AllowedHosts": "*"
+}
diff --git a/HackerNet.sln b/HackerNet.sln
index 4eeb445..8c222f8 100644
--- a/HackerNet.sln
+++ b/HackerNet.sln
@@ -13,6 +13,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Apps", "Apps", "{EB14E7E3-2
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HackerNet.Web", "Apps\HackerNet.Web\HackerNet.Web.csproj", "{7844261A-7074-4882-9507-B9B1F5A45921}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HackerNet.Api", "Apps\HackerNet.Api\HackerNet.Api.csproj", "{A3BFAAD5-9914-450E-8303-457B29F4990E}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -38,8 +40,13 @@ Global
{7844261A-7074-4882-9507-B9B1F5A45921}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7844261A-7074-4882-9507-B9B1F5A45921}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7844261A-7074-4882-9507-B9B1F5A45921}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A3BFAAD5-9914-450E-8303-457B29F4990E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A3BFAAD5-9914-450E-8303-457B29F4990E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A3BFAAD5-9914-450E-8303-457B29F4990E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A3BFAAD5-9914-450E-8303-457B29F4990E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{7844261A-7074-4882-9507-B9B1F5A45921} = {EB14E7E3-2556-4B17-8D81-18F322480B5C}
+ {A3BFAAD5-9914-450E-8303-457B29F4990E} = {EB14E7E3-2556-4B17-8D81-18F322480B5C}
EndGlobalSection
EndGlobal