Ajout exposition des commentaires dans l'API

This commit is contained in:
YuukanOO 2021-04-27 16:26:54 +02:00
parent f4ebf153e2
commit 307fa9ac0f
6 changed files with 463 additions and 6 deletions

View File

@ -17,27 +17,41 @@ namespace Application
_data = data; _data = data;
} }
public void PublishComment(PublishCommentCommand cmd) public Guid PublishComment(PublishCommentCommand cmd)
{ {
var link = _linkRepository.GetById(cmd.LinkId); var link = _linkRepository.GetById(cmd.LinkId);
var comment = link.AddComment(cmd.Content); var comment = link.AddComment(cmd.Content);
_commentRepository.Add(comment); _commentRepository.Add(comment);
return comment.Id;
} }
public CommentDTO[] GetAllLinkComments(Guid linkId) public CommentDTO[] GetAllLinkComments(Guid linkId)
{ {
return _data.Comments return CommentDTOs(linkId).ToArray();
}
public CommentDTO GetCommentById(Guid id)
{
return CommentDTOs().Single(comment => comment.Id == id);
}
private IQueryable<CommentDTO> CommentDTOs(Guid? linkId = null)
{
var comments = linkId.HasValue ?
_data.Comments.Where(comment => comment.LinkId == linkId)
: _data.Comments;
return comments
.OrderByDescending(comment => comment.CreatedAt) .OrderByDescending(comment => comment.CreatedAt)
.Where(comment => comment.LinkId == linkId)
.Select(comment => new CommentDTO .Select(comment => new CommentDTO
{ {
Id = comment.Id, Id = comment.Id,
Content = comment.Content, Content = comment.Content,
UpvotesCount = 0, UpvotesCount = 0,
DownvotesCount = 0, DownvotesCount = 0,
}) });
.ToArray();
} }
} }
} }

View File

@ -6,6 +6,10 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="NSwag.AspNetCore" Version="13.10.9" /> <PackageReference Include="NSwag.AspNetCore" Version="13.10.9" />
<PackageReference Include="NSwag.MSBuild" Version="13.10.9">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>
@ -21,4 +25,9 @@
<DocumentationFile>C:\Users\Julien\Documents\Sources\cesi\hn-20-2\Apps\Api\Api.xml</DocumentationFile> <DocumentationFile>C:\Users\Julien\Documents\Sources\cesi\hn-20-2\Apps\Api\Api.xml</DocumentationFile>
</PropertyGroup> --> </PropertyGroup> -->
<!-- Permet de générer le fichier de description de l'api à chaque build qui sera utile pour la génération du client -->
<Target Name="NSwag" AfterTargets="Build">
<Exec EnvironmentVariables="ASPNETCORE_ENVIRONMENT=Development" Command="$(NSwagExe_Net50) aspnetcore2openapi /assembly:$(TargetDir)Api.dll /output:swagger.json" />
</Target>
</Project> </Project>

View File

@ -0,0 +1,48 @@
using System;
using Application;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace Api.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class CommentsController : ControllerBase
{
private readonly CommentService _commentService;
public CommentsController(CommentService commentService)
{
_commentService = commentService;
}
/// <summary>
/// Affiche un commentaire.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("{id:guid}")]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status200OK)]
public CommentDTO Show(Guid id)
{
return _commentService.GetCommentById(id);
}
/// <summary>
/// Publie un nouveau commentaire sur la plateforme.
/// </summary>
/// <param name="cmd"></param>
/// <returns></returns>
[HttpPost]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status201Created)]
public IActionResult Create(PublishCommentCommand cmd)
{
var commentId = _commentService.PublishComment(cmd);
return CreatedAtAction(nameof(Show), new { id = commentId }, null);
}
}
}

View File

@ -10,10 +10,12 @@ namespace Api.Controllers
public class LinksController : ControllerBase public class LinksController : ControllerBase
{ {
private readonly LinkService _linkService; private readonly LinkService _linkService;
private readonly CommentService _commentService;
public LinksController(LinkService linkService) public LinksController(LinkService linkService, CommentService commentService)
{ {
_linkService = linkService; _linkService = linkService;
_commentService = commentService;
} }
/// <summary> /// <summary>
@ -39,6 +41,17 @@ namespace Api.Controllers
return _linkService.GetLinkById(id); return _linkService.GetLinkById(id);
} }
/// <summary>
/// Récupère tous les commentaires associés à un lien.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("{id:guid}/comments")]
public CommentDTO[] Comments(Guid id)
{
return _commentService.GetAllLinkComments(id);
}
/// <summary> /// <summary>
/// Permet de publier un nouveau lien sur la plateforme. /// Permet de publier un nouveau lien sur la plateforme.
/// </summary> /// </summary>

View File

@ -10,3 +10,17 @@ Content-Type: application/json
{ {
"url": "http://google.com" "url": "http://google.com"
} }
###
GET {{url}}/api/links/0860619e-6a13-45fe-86a8-6aa64e263f38/comments
###
POST {{url}}/api/comments
Content-Type: application/json
{
"linkId": "55be28a5-fdfb-48f7-8442-5f900048c292",
"content": "a new comment!"
}

359
Apps/Api/swagger.json Normal file
View File

@ -0,0 +1,359 @@
{
"x-generator": "NSwag v13.10.9.0 (NJsonSchema v10.4.1.0 (Newtonsoft.Json v12.0.0.0))",
"openapi": "3.0.0",
"info": {
"title": "Hacker News Clone API",
"version": "1.0.0"
},
"paths": {
"/api/Comments/{id}": {
"get": {
"tags": [
"Comments"
],
"summary": "Affiche un commentaire.",
"operationId": "Comments_Show",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "guid"
},
"x-position": 1
}
],
"responses": {
"404": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
},
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CommentDTO"
}
}
}
}
}
}
},
"/api/Comments": {
"post": {
"tags": [
"Comments"
],
"summary": "Publie un nouveau commentaire sur la plateforme.",
"operationId": "Comments_Create",
"requestBody": {
"x-name": "cmd",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PublishCommentCommand"
}
}
},
"required": true,
"x-position": 1
},
"responses": {
"400": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
},
"404": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
},
"201": {
"description": ""
}
}
}
},
"/api/links": {
"get": {
"tags": [
"Links"
],
"summary": "Récupère la liste liste des derniers liens publiés.",
"operationId": "Links_Index",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/LinkDTO"
}
}
}
}
}
}
},
"post": {
"tags": [
"Links"
],
"summary": "Permet de publier un nouveau lien sur la plateforme.",
"operationId": "Links_Create",
"requestBody": {
"x-name": "cmd",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PublishLinkCommand"
}
}
},
"required": true,
"x-position": 1
},
"responses": {
"400": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
},
"201": {
"description": ""
}
}
}
},
"/api/links/{id}": {
"get": {
"tags": [
"Links"
],
"summary": "Récupère les détails d'un lien.",
"operationId": "Links_Show",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "guid"
},
"x-position": 1
}
],
"responses": {
"404": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
},
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LinkDTO"
}
}
}
}
}
}
},
"/api/links/{id}/comments": {
"get": {
"tags": [
"Links"
],
"summary": "Récupère tous les commentaires associés à un lien.",
"operationId": "Links_Comments",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "guid"
},
"x-position": 1
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CommentDTO"
}
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"ProblemDetails": {
"type": "object",
"additionalProperties": {
"nullable": true
},
"properties": {
"type": {
"type": "string",
"nullable": true
},
"title": {
"type": "string",
"nullable": true
},
"status": {
"type": "integer",
"format": "int32",
"nullable": true
},
"detail": {
"type": "string",
"nullable": true
},
"instance": {
"type": "string",
"nullable": true
},
"extensions": {
"type": "object",
"nullable": true,
"additionalProperties": {}
}
}
},
"CommentDTO": {
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"format": "guid"
},
"content": {
"type": "string",
"nullable": true
},
"upvotesCount": {
"type": "integer",
"format": "int32"
},
"downvotesCount": {
"type": "integer",
"format": "int32"
}
}
},
"PublishCommentCommand": {
"type": "object",
"additionalProperties": false,
"required": [
"linkId",
"content"
],
"properties": {
"linkId": {
"type": "string",
"format": "guid",
"minLength": 1
},
"content": {
"type": "string",
"minLength": 1
}
}
},
"LinkDTO": {
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"format": "guid"
},
"url": {
"type": "string",
"nullable": true
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"upvotesCount": {
"type": "integer",
"format": "int32"
},
"downvotesCount": {
"type": "integer",
"format": "int32"
},
"commentsCount": {
"type": "integer",
"format": "int32"
}
}
},
"PublishLinkCommand": {
"type": "object",
"additionalProperties": false,
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"format": "uri",
"minLength": 1
}
}
}
}
}
}