【发布时间】:2018-03-30 15:03:34
【问题描述】:
使用 ServiceStack OpenApiFeature,openapi.json 文件中生成的operationId 遵循以下约定:
[RequestName][route path slice without first path*][http verb][digit if required for uniqueness]
没有第一个路径的路径路径切片* 只是删除路径中的第一项。所以如果路由路径是blog/author/name,逻辑会抓取author/name。
这是在OpenApiService::GetOperationName method 中定义的。在某些情况下,此逻辑会在依赖 openapi.json 的工具中创建次优操作命名。例如,如果您有一个服务公开了GET 操作以获取客户的详细信息、客户摘要等,并且详细信息请求的定义如下:
[Api("Get a customer's details.")]
[Route("/customer/details", "GET")]
public class GetCustomerDetailsRequest : IReturn<GetCustomerDetailsResponse>
{ ... }
路线将是这样的(这很好):
/customer/details?customerId=2
...但是生成的 OpenAPI operationId 会是 GetCustomerDetailsRequestdetails_Get,这不是很好。
有没有办法使用OpenApiFeature 自定义生成的operationId?如果没有,是否有其他命名约定可以保持 REST 风格的路由约定,但提供更好的 OpenAPI operationId?
编辑:感谢mythz 指出ApiDeclarationFilter。它允许您完全自定义生成的openapi.json。这就是我改变operationId的方式:
Plugins.Add(new OpenApiFeature
{
ApiDeclarationFilter = declaration =>
{
foreach (var p in declaration.Paths)
{
foreach (var httpVerb in _httpVerbs) // _httpVerbs is just a list of http verbs
{
// retrieve the operation value using reflection and pattern matching. This is to prevent having to use a switch statement to go through each http verb and check if it's been implemented
if (p.Value.GetType().GetProperty(httpVerb).GetValue(p.Value) is OpenApiOperation operation)
{
// Set the "OperationId" property using the convention [RequestClassName]_[Http Verb]. Note for simplicity here, I'm not checking for a unique operation Id. You should do that to ensure open api compliance
ReflectionHelper.SetProperty($"{httpVerb}.OperationId", p.Value,
$"{operation.RequestType}_{httpVerb}");
}
}
}
}
});
【问题讨论】:
标签: servicestack openapi