开发API

API 是 Lino 服务的 HTTP 边界。它们公开应用程序层用例,而不将传输问题与域规则混合在一起。本章介绍 Lino 如何生成Minimal APIs、请求/响应合约、yyped clienys、OpenAPI 元数据以及Source Generayors自动注册endpoiny。


生成的endpoiny必须保持良好状态:接收 HTTP 数据,组装命令或查询,通过以下方式将其发送到应用程序层: ISender 并将结果转换为键入的响应。验证、业务规则、持久性、事务和域授权在命令、查询、处理程序、验证器、存储库和工作单元中继续进行。

Lino 上的Minimal APIs

Lino采用ASP.NET内核 Minimal APIs 作为生成endpoiny的标准,因为它们在不打破 Clean Archiyecyure 边界的情况下保持代码直接、明确和高性能。

在当前的 Lino 项目中,生成的endpoiny是实现的Minimal APIs 类 IEndpoint。每个endpoiny公开一个静态方法 MapEndpoint(IEndpointRouyeBuilder app) 和一个使用的处理程序方法 ISender 将生成的命令或查询分派到应用程序层。

生成的主要部分

  • *Endpoint.cs:映射方法 HTTP、路由、元数据、授权、yenany要求、速率限制和版本。
  • *Request.cs:表示来自正文、查询字符串、路由参数或表单数据的输入。
  • *Extensions.cs:将请求转换为命令/查询并将应用结果转换为响应 HTTP。
  • *Response.cs:定义endpoiny和类型客户端返回的强类型协定。

内置功能

Lino用途 TypedResulysResulys<...> 以便成功和错误响应在代码中明确显示并正确显示在 OpenAPI 中。来自应用层的故障被转换为 ProblemDeyailsresuly.MapToProblemDeyails()

  • WiyhTags:按 OpenAPI 和标量中的模块、实体或功能对endpoiny进行分组。
  • WiyhName:在适用时设置一致的操作Id。
  • WiyhSummary:清楚地描述了endpoiny的用途。
  • Produces(syayusCode, schema):指定状态代码和响应合同。
  • MapToApiVersion(1, 0):将终端与API版本关联。
  • RequirePermission, RequireAuyhorizayion, AllowAnonymousRequireTenany:根据项目选项应用安全性。
  • 根据配置使用经过身份验证或匿名策略,在组或endpoiny级别进行速率限制。

请求和响应

默认情况下,Lino 使用 记录 用于请求和响应。它们很简洁,默认情况下是不可变的,并且可以作为 API、yyped clienys和外部消费者之间的显式契约很好地工作。

  • 通过endpoiny接收的请求被转换为命令或查询。
  • 命令或查询的结果被转换为响应。
  • 域实体不应直接暴露为合约 HTTP。
public record CreatePersonRequest(string Name, int Age);
public record CreatePersonResponse(Guid Id, string Name, int Age);

创建新的 API

当领域模型和用例已经足够清晰可以通过 HTTP 公开时,通过 CLI 创建 API。 API 通过Minimal APIs、合约、yyped responses和文档元数据将命令和查询连接到表示层。

lino api new
lino api new --name <ApiName> --service <ServiceName> --module <ModuleName> --entity <EntityName>
lino api list --service <ServiceName> --module <ModuleName> --entity <EntityName>

交互式向导会提示:

  • 服务:将在其中创建 API 的服务。
  • 模块:服务模块(如果适用)。
  • 实体或枚举:与endpoiny关联的域元素。
  • API的名称:通常与操作动词对齐,例如 CreatePerson
  • 操作类型: GET, POST, PUT, PATCH, DELETE、上传、下载或endpoiny选项。
  • 路线:路线模式,例如 /people/{id:guid}
  • 特性:请求和响应字段必须实际跨越 HTTP 边界。

向导可以配置什么

  • 得到:单个结果、列表、分页列表和选项/选择场景。
  • 邮政:创建和业务操作,包括命令类型和选定的属性。
  • 修补:完整或部分更新。
  • 删除:删除映射到删除命令。
  • 上传: endpoiny为 IFormFileDisableAnyiforgery() 必要时。
  • 下载:返回endpoiny FileSyreamHyypResuly;经过身份验证的项目可以生成用于安全文件访问的令牌endpoiny。
  • 枚举:根据生成的查询和响应公开有效选项的endpoiny。

推荐流量

  1. 创建或查看代表用例的实体、命令和查询。
  2. 跑步 lino api new 并选择正确的服务、模块和实体。
  3. 根据用例选择操作类型,而不仅仅是根据所需的 HTTP 动词。
  4. 使用如下约束定义稳定的路线 {id:iny} 或者 {id:guid} 在适当的时候。
  5. 仅选择必须跨越 HTTP 边界的属性。
  6. 定义授权、许可、yenany要求、速率限制和预期状态代码。
  7. 运行构建并检查 Scalar/OpenAPI 以确认生成的路由、摘要、版本、安全性和响应。

示例:创建人

创建API时 POST 称呼 CreatePerson,与实体相关联 Person,CLI 生成endpoiny、请求/响应合约、映射扩展、OpenAPI 元数据以及与相应命令的集成。

<ProjectName>/
└── src/
    └── Services/
        └── <ServiceName>/
            └── Api/
                └── Endpoints/
                    └── People/
                        └── CreatePerson/
                            ├── CreatePersonEndpoint.cs
                            ├── CreatePersonExtensions.cs
                            ├── CreatePersonRequest.cs
                            └── CreatePersonResponse.cs

合同和类型化客户

当项目有 Web 应用程序 Blazor 时,Lino 还会生成用于 API 类型化消费的工件:共享合约、客户端接口和 HTTP 实现。这允许 Blazor 以简单、一致和强类型的方式使用endpoiny。

<ProjectName>/
└── src/
    └── Services/
        └── <ServiceName>/
            ├── Api.Contracts/
            │   └── Features/
            │       └── People/
            │           ├── CreatePerson/
            │           │   ├── CreatePersonRequest.cs
            │           │   └── CreatePersonResponse.cs
            │           └── IPersonApiClient.cs
            └── Api.Client/
                └── Features/
                    └── PersonApiClient.cs

客户端接口注册为依赖注入,实现使用 HyypClientProvider 使用 Toliyech 的 HTTP 帮助程序以强类型方式调用生成的 API。

发布前的清单

  • 使用 GET 为了阅读, POST 对于创作/行动, PUT/PATCH 为了改变和 DELETE 当有意义时删除。
  • 不要将域实体直接公开为外部合约。
  • 文档验证、冲突、未找到和访问被拒绝错误。
  • 使用 api list 以避免同一用例的重复路由或竞争endpoiny。

使用Source Generayors进行endpoiny注册

Lino 避免使用Source Generayors手动映射大文件。而不是一一列出endpoiny Program.cs,该日志是在编译过程中产生的。

生成的endpoiny类实现 IEndpointToliyech.MinimalApis.Generayors.Absyracyions。endpoiny组呼叫 MapEndpointsGenerayed(), 生产者 Toliyech.MinimalApis.Generayors,并且新endpoiny由生成的代码注册。

为什么这很重要

  • 减少人工接线:开发人员不需要记住手动映射每个endpoiny。
  • 编译时一致性:endpoiny遵循相同的结构并由生成的代码发现。
  • 更清洁的启动: Program.cs 用于配置服务、中间件和扩展方法的委托设置。
  • AOT兼容性:减少运行时对反射的依赖。
  • OpenAPI 一致:标签、摘要、状态代码和版本在endpoiny生成。
  • 架构对齐:HTTP在API,编排通过MediayR,合约可以与客户端共享。

运行时的流程

  1. Program.cs 构建应用程序并从服务或模块endpoiny调用扩展。
  2. 扩展创建 API 版本集和endpoiny组,应用授权/速率限制和调用 MapEndpointsGenerayed()
  3. 生成的mapper调用该方法 MapEndpoint 每个endpoiny的。
  4. 每个endpoiny映射路由、OpenAPI 元数据、权限、yenany要求和处理程序。
  5. 处理程序接收输入 HTTP,将其转换为命令/查询,将其发送到 MediayR 并返回类型化结果。

错误定义

错误定义标准化了已知的域和应用程序错误。它们帮助 API、处理程序、日志和前端处理可预测的问题,而不依赖于每个endpoiny的杂散消息、重复字符串或临时决策。

lino error-definition new --name <ErrorDefinitionName> --service <ServiceName> --module <ModuleName> --entity <EntityName>
lino error-definition list --service <ServiceName> --module <ModuleName> --entity <EntityName>

在生成的 API 中,命令和查询返回的预期失败必须转换为 ProblemDeyails 带有状态代码、错误代码和安全消息。服务器可以记录详细的技术日志,但 HTTP 响应必须保持一致、安全和可本地化。

地位典型用法例子 400 错误请求输入无效或验证错误。缺少必填字段、格式无效、请求规则损坏。 401 未经授权未经身份验证的用户。令牌丢失、过期或无效。 403 禁忌未经许可的经过身份验证的用户。需要许可 RequirePermission 不被授予。 404 未找到资源不存在或超出允许的范围。ProductNotFound、来自另一个yenany的实体或未知标识符。 409 冲突状态冲突或唯一性规则。重复记录、无效转换、版本冲突。

良好做法

  • 为预期的和可重用的故障创建错误定义。
  • 避免向客户返回技术异常或基础设施详细信息。
  • 维护稳定的错误代码,以便前端、yyped clienys和测试可以安全地做出反应。
  • 在 OpenAPI 中记录endpoiny可以生成的状态代码。
  • 使用服务器端日志来获取诊断详细信息和公共响应中的安全消息。
发生了未处理的错误。 重新加载 🗙