(一)微服务(垂直API)
文章目录
- 项目地址
- 一、创建第一个垂直API
- 1.1 创建Common层
- 1. ICommand接口
- 2. IQuery接口
- 1.2 创建API
- 1. 实体
- 2. Handler
- 3. endpoint
- 1.3 使用Marten作为ORM
项目地址
- 教程作者:
- 教程地址:
- 代码仓库地址:
- 所用到的框架和插件:
dbt
airflow
一、创建第一个垂直API
1.1 创建Common层
1. ICommand接口
ICommand.cs
using MediatR;
namespace BuildingBlocks.CQRS;
public interface ICommand : ICommand<Unit>;
public interface ICommand<out TResponse> : IRequest<TResponse>;
ICommandHandler.cs
using MediatR;
namespace BuildingBlocks.CQRS;
public interface ICommandHandler<in TCommand> //无返回值: ICommandHandler<TCommand, Unit>where TCommand : ICommand<Unit>;public interface ICommandHandler<in TCommand, TResponse> //有返回值: IRequestHandler<TCommand, TResponse>where TCommand : ICommand<TResponse>where TResponse : notnull;
in(Contravariant):只在参数中使用的泛型类型
2. IQuery接口
IQuery.cs
using MediatR;
namespace BuildingBlocks.CQRS;
public interface IQuery<out TResponse> : IRequest<TResponse> where TResponse : notnull;
IQueryHandler
:
namespace BuildingBlocks.CQRS;
public interface IQueryHandler<in TQuery, TResponse>: IRequestHandler<TQuery, TResponse>where TQuery : IQuery<TResponse>where TResponse : notnull;
1.2 创建API
1. 实体
namespace Catalog.API.Models;
public class Product
{public Guid Id { get; set; }public string Name { get; set; } = default!;public List<string> Category { get; set; } = new();public string Description { get; set; } = default!;public string ImageFile { get; set; } = default!;public decimal Price { get; set; }
}
2. Handler
namespace Catalog.API.Products.CreateProduct;
public record CreateProductCommand(string Name, List<string> Category, string Description, string ImageFile, decimal Price): ICommand<CreateProductResult>;
public record CreateProductResult(Guid Id);internal class CreateProductCommandHandler : ICommandHandler<CreateProductCommand, CreateProductResult>
{public async Task<CreateProductResult> Handle(CreateProductCommand command, CancellationToken cancellationToken){var product = new Product{Name = command.Name,Category = command.Category,Description = command.Description,ImageFile = command.ImageFile,Price = command.Price};return new CreateProductResult(Guid.NewGuid()); }
}
3. endpoint
namespace Catalog.API.Products.CreateProduct;
public record CreateProductRequest(string Name, List<string> Category, string Description, string ImageFile, decimal Price);
public record CreateProductResponse(Guid Id);
public class CreateProductEndpoint : ICarterModule
{public void AddRoutes(IEndpointRouteBuilder app){app.MapPost("/products",async (CreateProductRequest request, ISender sender) =>{var command = request.Adapt<CreateProductCommand>();var result = await sender.Send(command);var response = result.Adapt<CreateProductResponse>();return Results.Created($"/products/{response.Id}", response);}).WithName("CreateProduct").Produces<CreateProductResponse>(StatusCodes.Status201Created).ProducesProblem(StatusCodes.Status400BadRequest).WithSummary("Create Product").WithDescription("Create Product");}
}
1.3 使用Marten作为ORM
- Marten只能用于postgresql的ORM使用