From f0e9054b36a942769d8e8d17083641eb25784772 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Tue, 21 Sep 2021 12:37:59 +0200 Subject: [PATCH] CollectionAPI: Documenting the public api --- .../Controllers/IRepository.cs | 1 - .../Models/Utils/RequestError.cs | 1 + src/Kyoo.Core/Views/CollectionApi.cs | 55 ++++++++++++++++--- src/Kyoo.Core/Views/Helper/CrudApi.cs | 51 ++++++++++++++--- 4 files changed, 90 insertions(+), 18 deletions(-) diff --git a/src/Kyoo.Abstractions/Controllers/IRepository.cs b/src/Kyoo.Abstractions/Controllers/IRepository.cs index 805de8ec..21a65c12 100644 --- a/src/Kyoo.Abstractions/Controllers/IRepository.cs +++ b/src/Kyoo.Abstractions/Controllers/IRepository.cs @@ -179,7 +179,6 @@ namespace Kyoo.Abstractions.Controllers /// Delete all resources that match the predicate. /// /// A predicate to filter resources to delete. Every resource that match this will be deleted. - /// If the item is not found /// A representing the asynchronous operation. Task DeleteAll([NotNull] Expression> where); } diff --git a/src/Kyoo.Abstractions/Models/Utils/RequestError.cs b/src/Kyoo.Abstractions/Models/Utils/RequestError.cs index e37bf63c..fa40fc64 100644 --- a/src/Kyoo.Abstractions/Models/Utils/RequestError.cs +++ b/src/Kyoo.Abstractions/Models/Utils/RequestError.cs @@ -30,6 +30,7 @@ namespace Kyoo.Abstractions.Models.Utils /// /// The list of errors that where made in the request. /// + /// ["InvalidFilter: no field 'startYear' on a collection"] [NotNull] public string[] Errors { get; set; } /// diff --git a/src/Kyoo.Core/Views/CollectionApi.cs b/src/Kyoo.Core/Views/CollectionApi.cs index 91e9c24e..e920f52c 100644 --- a/src/Kyoo.Core/Views/CollectionApi.cs +++ b/src/Kyoo.Core/Views/CollectionApi.cs @@ -24,7 +24,9 @@ using Kyoo.Abstractions.Controllers; using Kyoo.Abstractions.Models; using Kyoo.Abstractions.Models.Exceptions; using Kyoo.Abstractions.Models.Permissions; +using Kyoo.Abstractions.Models.Utils; using Kyoo.Core.Models.Options; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using static Kyoo.Abstractions.Models.Utils.Constants; @@ -67,21 +69,25 @@ namespace Kyoo.Core.Api } /// - /// Lists that are contained in the with id . + /// Get shows in collection (via id) /// + /// + /// Lists the shows that are contained in the collection with the given id. + /// /// The ID of the . - /// A key to sort shows by. See for more information. + /// A key to sort shows by. /// An optional show's ID to start the query from this specific item. - /// - /// An optional list of filters. See for more details. - /// + /// An optional list of filters. /// The number of shows to return. /// A page of shows. - /// or is invalid. - /// No collection with the ID could be found. + /// The filters or the sort parameters are invalid. + /// No collection with the given ID could be found. [HttpGet("{id:int}/shows")] [HttpGet("{id:int}/show", Order = AlternativeRoute)] [PartialPermission(Kind.Read)] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(RequestError))] + [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> GetShows(int id, [FromQuery] string sortBy, [FromQuery] int afterID, @@ -101,13 +107,30 @@ namespace Kyoo.Core.Api } catch (ArgumentException ex) { - return BadRequest(new { Error = ex.Message }); + return BadRequest(new RequestError(ex.Message)); } } + /// + /// Get shows in collection (via slug) + /// + /// + /// Lists the shows that are contained in the collection with the given slug. + /// + /// The slug of the . + /// A key to sort shows by. + /// An optional show's ID to start the query from this specific item. + /// An optional list of filters. + /// The number of shows to return. + /// A page of shows. + /// The filters or the sort parameters are invalid. + /// No collection with the given slug could be found. [HttpGet("{slug}/shows")] [HttpGet("{slug}/show", Order = AlternativeRoute)] [PartialPermission(Kind.Read)] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(RequestError))] + [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> GetShows(string slug, [FromQuery] string sortBy, [FromQuery] int afterID, @@ -127,10 +150,24 @@ namespace Kyoo.Core.Api } catch (ArgumentException ex) { - return BadRequest(new { Error = ex.Message }); + return BadRequest(new RequestError(ex.Message)); } } + /// + /// Get libraries containing this collection + /// + /// + /// Lists the libraries that contain the collection with the given id. + /// + /// The slug of the . + /// A key to sort shows by. + /// An optional show's ID to start the query from this specific item. + /// An optional list of filters. + /// The number of shows to return. + /// A page of shows. + /// The filters or the sort parameters are invalid. + /// No collection with the given slug could be found. [HttpGet("{id:int}/libraries")] [HttpGet("{id:int}/library", Order = AlternativeRoute)] [PartialPermission(Kind.Read)] diff --git a/src/Kyoo.Core/Views/Helper/CrudApi.cs b/src/Kyoo.Core/Views/Helper/CrudApi.cs index ad10bfb9..1c214da3 100644 --- a/src/Kyoo.Core/Views/Helper/CrudApi.cs +++ b/src/Kyoo.Core/Views/Helper/CrudApi.cs @@ -45,7 +45,8 @@ namespace Kyoo.Core.Api private readonly IRepository _repository; /// - /// The base URL of Kyoo. This will be used to create links for images and . + /// The base URL of Kyoo. This will be used to create links for images and + /// . /// protected Uri BaseURL { get; } @@ -110,7 +111,7 @@ namespace Kyoo.Core.Api /// /// Get a specific resource via it's slug (a unique, human readable identifier). /// - /// The slug of the resource to retrieve. + /// The slug of the resource to retrieve. /// The retrieved resource. /// A resource with the given ID does not exist. [HttpGet("{slug}")] @@ -166,7 +167,8 @@ namespace Kyoo.Core.Api [PartialPermission(Kind.Read)] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(RequestError))] - public async Task>> GetAll([FromQuery] string sortBy, + public async Task>> GetAll( + [FromQuery] string sortBy, [FromQuery] int afterID, [FromQuery] Dictionary where, [FromQuery] int limit = 20) @@ -253,9 +255,20 @@ namespace Kyoo.Core.Api } } + /// + /// Delete by ID + /// + /// + /// Delete one item via it's ID. + /// + /// The ID of the resource to delete. + /// The item has successfully been deleted. + /// No item could be found with the given id. [HttpDelete("{id:int}")] [PartialPermission(Kind.Delete)] - public virtual async Task Delete(int id) + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task Delete(int id) { try { @@ -269,9 +282,20 @@ namespace Kyoo.Core.Api return Ok(); } + /// + /// Delete by slug + /// + /// + /// Delete one item via it's slug (an unique, human-readable identifier). + /// + /// The slug of the resource to delete. + /// The item has successfully been deleted. + /// No item could be found with the given slug. [HttpDelete("{slug}")] [PartialPermission(Kind.Delete)] - public virtual async Task Delete(string slug) + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task Delete(string slug) { try { @@ -285,17 +309,28 @@ namespace Kyoo.Core.Api return Ok(); } + /// + /// Delete all where + /// + /// + /// Delete all items matching the given filters. If no filter is specified, delete all items. + /// + /// The list of filters. + /// The item(s) has successfully been deleted. + /// One or multiple filters are invalid. [HttpDelete] [PartialPermission(Kind.Delete)] - public virtual async Task Delete(Dictionary where) + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(RequestError))] + public async Task Delete([FromQuery] Dictionary where) { try { await _repository.DeleteAll(ApiHelper.ParseWhere(where)); } - catch (ItemNotFoundException) + catch (ArgumentException ex) { - return NotFound(); + return BadRequest(new RequestError(ex.Message)); } return Ok();