Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added product getbyid function #933

Merged
merged 18 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using FSH.WebApi.Catalog.Domain.Events;
using Microsoft.Extensions.Logging;
using MediatR;

namespace FSH.WebApi.Catalog.Application.Products.EventHandlers;

public class ProductReadEventHandler(ILogger<ProductReadEventHandler> logger) : INotificationHandler<ProductRead>
{
public async Task Handle(ProductRead notification,
CancellationToken cancellationToken)
{
logger.LogInformation("handling product read domain event..");
await Task.FromResult(notification);
logger.LogInformation("finished handling product read domain event..");
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Microsoft.Extensions.DependencyInjection;
using FSH.WebApi.Catalog.Domain.Exceptions;
using FSH.Framework.Core.Persistence;
using FSH.Framework.Core.Caching;
using FSH.WebApi.Catalog.Domain;
using MediatR;

namespace FSH.WebApi.Catalog.Application.Products.Get.v1;
public sealed class GetProductHandler(
[FromKeyedServices("catalog:products")] IReadRepository<Product> repository,
ICacheService cache)
: IRequestHandler<GetProductRequest, GetProductResponse>
{
public async Task<GetProductResponse> Handle(GetProductRequest request, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(request);
var item = await cache.GetOrSetAsync(
$"product:{request.Id}",
async () =>
{
var productItem = await repository.GetByIdAsync(request.Id, cancellationToken);
if (productItem == null) throw new ProductItemNotFoundException(request.Id);
return new GetProductResponse(productItem.Id, productItem.Name, productItem.Description, productItem.Price);
},
cancellationToken: cancellationToken);
return item!;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using MediatR;

namespace FSH.WebApi.Catalog.Application.Products.Get.v1;
public class GetProductRequest : IRequest<GetProductResponse>
{
public Guid Id { get; set; }
public GetProductRequest(Guid id) => Id = id;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
namespace FSH.WebApi.Catalog.Application.Products.Get.v1;
public sealed record GetProductResponse(Guid? Id, string Name, string? Description, decimal Price);
7 changes: 7 additions & 0 deletions api/modules/Catalog/Catalog.Domain/Events/ProductRead.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using FSH.Framework.Core.Domain.Events;

namespace FSH.WebApi.Catalog.Domain.Events;
public sealed record ProductRead : DomainEvent
{
public Product? Product { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using FSH.Framework.Core.Exceptions;

namespace FSH.WebApi.Catalog.Domain.Exceptions;
public sealed class ProductItemNotFoundException : NotFoundException
{
public ProductItemNotFoundException(Guid id)
: base($"product with id {id} not found")
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public override void AddRoutes(IEndpointRouteBuilder app)
{
var productGroup = app.MapGroup("products").WithTags("products");
productGroup.MapProductCreationEndpoint();
productGroup.MapGetProductEndpoint();
}
}
public static WebApplicationBuilder RegisterCatalogServices(this WebApplicationBuilder builder)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using FSH.WebApi.Catalog.Application.Products.Get.v1;
using FSH.Framework.Infrastructure.Auth.Policy;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Http;
using MediatR;

namespace FSH.WebApi.Catalog.Infrastructure.Endpoints.v1;
public static class GetProductEndpoint
{
internal static RouteHandlerBuilder MapGetProductEndpoint(this IEndpointRouteBuilder endpoints)
{
return endpoints.MapGet("/{id:guid}", (Guid id, ISender mediator) => mediator.Send(new GetProductRequest(id)))
.WithName(nameof(GetProductEndpoint))
.WithSummary("gets product by id")
.WithDescription("gets prodct by id")
.Produces<GetProductResponse>()
.RequirePermission("Permissions.Products.View")
.MapToApiVersion(1);
}
}