Browse Source
* Adding new Endpoints * update nuget packages * Modifying API to work well with Swagger. * Remove Swashbuckle.Coremain
committed by
GitHub
20 changed files with 307 additions and 22 deletions
@ -0,0 +1,20 @@ |
|||
using System; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.API |
|||
{ |
|||
/// <summary>
|
|||
/// Base class used by API requests
|
|||
/// </summary>
|
|||
public abstract class BaseMessage |
|||
{ |
|||
/// <summary>
|
|||
/// Unique Identifier used by logging
|
|||
/// </summary>
|
|||
protected Guid _correlationId = Guid.NewGuid(); |
|||
public Guid CorrelationId() => _correlationId; |
|||
} |
|||
|
|||
public abstract class BaseRequest : BaseMessage |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
using System; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.API |
|||
{ |
|||
/// <summary>
|
|||
/// Base class used by API responses
|
|||
/// </summary>
|
|||
public abstract class BaseResponse : BaseMessage |
|||
{ |
|||
public BaseResponse(Guid correlationId) : base() |
|||
{ |
|||
base._correlationId = correlationId; |
|||
} |
|||
|
|||
public BaseResponse() |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
namespace Microsoft.eShopWeb.Web.API.CatalogItemEndpoints |
|||
{ |
|||
public class CatalogItemDto |
|||
{ |
|||
public int Id { get; set; } |
|||
public string Name { get; set; } |
|||
public string Description { get; set; } |
|||
public decimal Price { get; set; } |
|||
public string PictureUri { get; set; } |
|||
public int CatalogTypeId { get; set; } |
|||
public int CatalogBrandId { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
namespace Microsoft.eShopWeb.Web.API.CatalogItemEndpoints |
|||
{ |
|||
public class CreateCatalogItemRequest : BaseRequest |
|||
{ |
|||
public int CatalogBrandId { get; set; } |
|||
public int CatalogTypeId { get; set; } |
|||
public string Description { get; set; } |
|||
public string Name { get; set; } |
|||
public string PictureUri { get; set; } |
|||
public decimal Price { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.API.CatalogItemEndpoints |
|||
{ |
|||
public class CreateCatalogItemResponse : BaseResponse |
|||
{ |
|||
public CreateCatalogItemResponse(Guid correlationId) : base(correlationId) |
|||
{ |
|||
} |
|||
|
|||
public CatalogItemDto CatalogItem { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,48 @@ |
|||
using Ardalis.ApiEndpoints; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.eShopWeb.ApplicationCore.Entities; |
|||
using Microsoft.eShopWeb.ApplicationCore.Interfaces; |
|||
using Swashbuckle.AspNetCore.Annotations; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.API.CatalogItemEndpoints |
|||
{ |
|||
public class Create : BaseAsyncEndpoint<CreateCatalogItemRequest, CreateCatalogItemResponse> |
|||
{ |
|||
private readonly IAsyncRepository<CatalogItem> _itemRepository; |
|||
|
|||
public Create(IAsyncRepository<CatalogItem> itemRepository) |
|||
{ |
|||
_itemRepository = itemRepository; |
|||
} |
|||
|
|||
[HttpPost("api/catalog-items")] |
|||
[SwaggerOperation( |
|||
Summary = "Creates a new Catalog Item", |
|||
Description = "Creates a new Catalog Item", |
|||
OperationId = "catalog-items.create", |
|||
Tags = new[] { "CatalogItemEndpoints" }) |
|||
] |
|||
public override async Task<ActionResult<CreateCatalogItemResponse>> HandleAsync(CreateCatalogItemRequest request) |
|||
{ |
|||
var response = new CreateCatalogItemResponse(request.CorrelationId()); |
|||
|
|||
CatalogItem newItem = new CatalogItem(request.CatalogTypeId, request.CatalogBrandId, request.Description, request.Name, request.Price, request.PictureUri); |
|||
|
|||
newItem = await _itemRepository.AddAsync(newItem); |
|||
|
|||
var dto = new CatalogItemDto |
|||
{ |
|||
Id = newItem.Id, |
|||
CatalogBrandId = newItem.CatalogBrandId, |
|||
CatalogTypeId = newItem.CatalogTypeId, |
|||
Description = newItem.Description, |
|||
Name = newItem.Name, |
|||
PictureUri = newItem.PictureUri, |
|||
Price = newItem.Price |
|||
}; |
|||
response.CatalogItem = dto; |
|||
return response; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.API.CatalogItemEndpoints |
|||
{ |
|||
public class DeleteCatalogItemRequest : BaseRequest |
|||
{ |
|||
//[FromRoute]
|
|||
public int CatalogItemId { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.API.CatalogItemEndpoints |
|||
{ |
|||
public class DeleteCatalogItemResponse : BaseResponse |
|||
{ |
|||
public DeleteCatalogItemResponse(Guid correlationId) : base(correlationId) |
|||
{ |
|||
} |
|||
|
|||
public string Status { get; set; } = "Deleted"; |
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
using Ardalis.ApiEndpoints; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.eShopWeb.ApplicationCore.Entities; |
|||
using Microsoft.eShopWeb.ApplicationCore.Interfaces; |
|||
using Swashbuckle.AspNetCore.Annotations; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.API.CatalogItemEndpoints |
|||
{ |
|||
public class Delete : BaseAsyncEndpoint<DeleteCatalogItemRequest, DeleteCatalogItemResponse> |
|||
{ |
|||
private readonly IAsyncRepository<CatalogItem> _itemRepository; |
|||
|
|||
public Delete(IAsyncRepository<CatalogItem> itemRepository) |
|||
{ |
|||
_itemRepository = itemRepository; |
|||
} |
|||
|
|||
[HttpDelete("api/catalog-items/{CatalogItemId}")] |
|||
[SwaggerOperation( |
|||
Summary = "Deletes a Catalog Item", |
|||
Description = "Deletes a Catalog Item", |
|||
OperationId = "catalog-items.Delete", |
|||
Tags = new[] { "CatalogItemEndpoints" }) |
|||
] |
|||
public override async Task<ActionResult<DeleteCatalogItemResponse>> HandleAsync([FromRoute]DeleteCatalogItemRequest request) |
|||
{ |
|||
var response = new DeleteCatalogItemResponse(request.CorrelationId()); |
|||
|
|||
var itemToDelete = await _itemRepository.GetByIdAsync(request.CatalogItemId); |
|||
if (itemToDelete is null) return NotFound(); |
|||
|
|||
await _itemRepository.DeleteAsync(itemToDelete); |
|||
|
|||
return Ok(response); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
namespace Microsoft.eShopWeb.Web.API.CatalogItemEndpoints |
|||
{ |
|||
public class GetByIdCatalogItemRequest : BaseRequest |
|||
{ |
|||
public int CatalogItemId { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.API.CatalogItemEndpoints |
|||
{ |
|||
public class GetByIdCatalogItemResponse : BaseResponse |
|||
{ |
|||
public GetByIdCatalogItemResponse(Guid correlationId) : base(correlationId) |
|||
{ |
|||
} |
|||
|
|||
public CatalogItemDto CatalogItem { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
using Ardalis.ApiEndpoints; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.eShopWeb.ApplicationCore.Entities; |
|||
using Microsoft.eShopWeb.ApplicationCore.Interfaces; |
|||
using Swashbuckle.AspNetCore.Annotations; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.API.CatalogItemEndpoints |
|||
{ |
|||
public class GetById : BaseAsyncEndpoint<GetByIdCatalogItemRequest, GetByIdCatalogItemResponse> |
|||
{ |
|||
private readonly IAsyncRepository<CatalogItem> _itemRepository; |
|||
|
|||
public GetById(IAsyncRepository<CatalogItem> itemRepository) |
|||
{ |
|||
_itemRepository = itemRepository; |
|||
} |
|||
|
|||
[HttpGet("api/catalog-items/{CatalogItemId}")] |
|||
[SwaggerOperation( |
|||
Summary = "Get a Catalog Item by Id", |
|||
Description = "Gets a Catalog Item by Id", |
|||
OperationId = "catalog-items.GetById", |
|||
Tags = new[] { "CatalogItemEndpoints" }) |
|||
] |
|||
public override async Task<ActionResult<GetByIdCatalogItemResponse>> HandleAsync([FromRoute]GetByIdCatalogItemRequest request) |
|||
{ |
|||
var response = new GetByIdCatalogItemResponse(request.CorrelationId()); |
|||
|
|||
var item = await _itemRepository.GetByIdAsync(request.CatalogItemId); |
|||
if (item is null) return NotFound(); |
|||
|
|||
response.CatalogItem = new CatalogItemDto |
|||
{ |
|||
Id = item.Id, |
|||
CatalogBrandId = item.CatalogBrandId, |
|||
CatalogTypeId = item.CatalogTypeId, |
|||
Description = item.Description, |
|||
Name = item.Name, |
|||
PictureUri = item.PictureUri, |
|||
Price = item.Price |
|||
}; |
|||
return Ok(response); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using Microsoft.OpenApi.Models; |
|||
using Swashbuckle.AspNetCore.SwaggerGen; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.API |
|||
{ |
|||
public class CustomSchemaFilters : ISchemaFilter |
|||
{ |
|||
public void Apply(OpenApiSchema schema, SchemaFilterContext context) |
|||
{ |
|||
var excludeProperties = new[] { "CorrelationId" }; |
|||
|
|||
foreach (var prop in excludeProperties) |
|||
if (schema.Properties.ContainsKey(prop)) |
|||
schema.Properties.Remove(prop); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
# API Endpoints |
|||
|
|||
This folder demonstrates how to configure API endpoints as individual classes. You can compare it to the traditional controller-based approach found in /Controllers/Api. |
|||
|
|||
Loading…
Reference in new issue