ASP.NET CoreのWebAPIとAutoRestで良い感じの.NETクライアントライブラリーを生成する
AutoRest は OpenAPI( Swagger )で定義された RestAPI に接続するクライアントコードを生成するライブラリーです。 ASP.NET Core で実装した WebAPI に対して AutoRest で良い感じのクライアントライブラリーを生成する時のポイントメモです。
環境
- .NET Core SDK 3.1.100
- ASP.NET Core 3.1 + Swashbuckle.AspNetCore@5.0.0-rc.5
- Node.js 12.14.1
- npm 6.13.6
- AutoRest 3.0.5231
AutoRestのクライアント生成
事前準備
AutoRest でクライアントライブラリーを生成するには Node.js 10.x 以上と .NET Core 2.0 SDK が必要なのでインストールしておきます。
また生成したクライアントコードは API に接続するコードのみで CS プロジェクトファイルは含まれないため、事前に .NET Standard 2.0 のライブラリープロジェクトを1つ作成しておきます。作成したプロジェクトには Microsoft.Rest.ClientRuntime
を NuGet から追加することを忘れずに。
クライアントコードの生成
クライアントコードを生成するため、先に作成したライブラリープロジェクト上にコードを生成します。 OpenAPI v3 のコードを生成するには AutoRest 3.x が必要なため @beta
を付与して実行します。
npx autorest@beta --csharp --namespace="ApiClient" --input-file="http://localhost:5000/swagger/v1/swagger.json" --output-folder="xxxxxxxxxx"
OpenAPI で設定されたタグに応じてファイルを分割してくれないため、生成された WebAPIExtensions.cs
を眺めると全ての API に接続する拡張メソッドが含まれており、名前も重複して Get1Async
となっていてとても残念な感じです。
良い感じのクライアントコード生成
AutoRest で良い感じのクライアントコードを生成するには OperationId に一工夫加える必要があります。 AutoRest では OperationId に含まれる _
毎にクライアントコードが分割されるため、 OpenAPI 定義を生成する際に例えばコントローラー名を OperationId に含めるなどします。
SwashbuckleでOperationIdにコントローラー名をPrefixにする
Swashbuckle には OpenAPI 定義を生成するのにいくつかの設定があります。そのうち IOperationFilter
を使用すると生成される OpearationId を任意にカスタマイズすることができます。例えばコントローラー名を付与するならこんな感じになります。
public class CustomOperationFilter : IOperationFilter { public void Apply(OpenApiOperation operation, OperationFilterContext context) { if (context.ApiDescription.ActionDescriptor is ControllerActionDescriptor controller) { operation.OperationId = $"{controller.ControllerName}_{operation.OperationId ?? controller.ActionName}"; } } }
作成した IOperationFilter
を AddSwaggerGen
で設定します。
/// <summary> /// OpenAPIミドルウェアの設定を追加します。 /// </summary> public static void AddOpenApi(this IServiceCollection services) { services.AddSwaggerGen(options => { options.SwaggerDoc("v1", new OpenApiInfo { Title = "WebAPI", Version = "v1.0.0" }); options.OperationFilter<CustomOperationFilter>(); // ココ }); }
クライアントコードの生成
OperationId にコントローラー名を付与したら再度 AutoRest でクライアントコードを生成してみます。今回はコントローラー毎に分かれたクライアントコードが生成されました。