2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

まめコーヒーアドベントカレンダーAdvent Calendar 2021

Day 15

NSwagでBuild時にclient側のSwaggerを自動生成する(NSwagの紹介)

Last updated at Posted at 2021-12-14

はじめに

この記事はまめコーヒ
まめコーヒーアドベントカレンダー Advent Calendar 2021, 15日目の記事です

こちらのコミュニティで、以前C#のコードジェネレーターであるNSwagの紹介しましたので
その時の内容を簡単に記事に起こします

NSwagについて

C# のコードジェネレータで、API Contollerの内容より、
Swaggerのコードを自動生成してくれます
webAPI.drawio.png

使用するライブラリ

  • NSwag Asp.NET core(NSwag本体)

  • NSwag MSBuild(Build時にNSwagを走らせるのに必要)

生成されるコードについて

NSwagはコントローラーを見てOpenAPI の仕様書を生成してくれます

例えば、以下のようなContollerがあったときは


namespace NSwag_app.Controllers
{
    [ApiController]
    public class TestController : Controller
    {
        [HttpGet]
        [Route("[controller]")]
        public TestArray Test()
        {
            return new TestArray();
        }
    }

    public class Test
    {   
        public string test{ get; set; }
    }

    public class TestArray
    {
        public Test[] tests { get; set; }
    }
}

下記のようなjsonファイルを出力してくれます

     "/Test": {
        "get": {
          "tags": [
            "Test"
          ],
          "operationId": "Test_Test",
          "responses": {
            "200": {
              "description": "",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/TestArray"
                  }
                }
              }
            }
          }
        }
      },

NSwagでSwaggerを自動生成する

どのようにSwaggerを生成するかはnswag.jsonで管理します
設定項目は多岐にわたっており、一個ずつ確認していくのは大変ですが
NSwag Studioという、GUIで設定ができるツールがあるので、
こちらから設定して、設定ファイルをエクスポートするのが早いのではないでしょうか

出力をTypeScriptsで設定した場合、
下記のようなtsファイルが出力されます

.ts
export class TestApiFactory {
    private instance: AxiosInstance;
    private baseUrl: string;
    protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined;

    constructor(baseUrl?: string, instance?: AxiosInstance) {
        this.instance = instance ? instance : axios.create();
        this.baseUrl = baseUrl !== undefined && baseUrl !== null ? baseUrl : "";
    }

    test(  cancelToken?: CancelToken | undefined): Promise<TestArray> {
        let url_ = this.baseUrl + "/Test";
        url_ = url_.replace(/[?&]$/, "");

        let options_ = <AxiosRequestConfig>{
            method: "GET",
            url: url_,
            headers: {
                "Accept": "application/json"
            },
            cancelToken
        };

        return this.instance.request(options_).catch((_error: any) => {
            if (isAxiosError(_error) && _error.response) {
                return _error.response;
            } else {
                throw _error;
            }
        }).then((_response: AxiosResponse) => {
            return this.processTest(_response);
        });
    }

    protected processTest(response: AxiosResponse): Promise<TestArray> {
        const status = response.status;
        let _headers: any = {};
        if (response.headers && typeof response.headers === "object") {
            for (let k in response.headers) {
                if (response.headers.hasOwnProperty(k)) {
                    _headers[k] = response.headers[k];
                }
            }
        }
        if (status === 200) {
            const _responseText = response.data;
            let result200: any = null;
            let resultData200  = _responseText;
            result200 = TestArray.fromJS(resultData200);
            return result200;
        } else if (status !== 200 && status !== 204) {
            const _responseText = response.data;
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
        }
        return Promise.resolve<TestArray>(<any>null);
    }
}

かつ、APIの引数または、返り値がmodel定義しているときは、
modelも一緒に作ってくれます

export interface ITest {
    test?: string;
}

Build時にNSwagを走らせるには

Build時にNSwagを走らせるにはNSwag MSBuildをインストールする必要があります

基本的には、プロジェクトファイルに以下のように書き込んであげれば良いです
Versionはプロジェクに合わせてかえてあげてください


  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.1.16" />
    <PackageReference Include="NSwag.AspNetCore" Version="13.13.2" />
    <PackageReference Include="NSwag.MSBuild" Version="13.13.2">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>

終わりに

フロントとバックエンドが完全に分離しているようなシステムの場合、
APIの仕様変更がフロンまで修正がいかず、
バグになることがあったり、修正してもメンテが大変だったりしますが、
NSwagのようなコードジェネレーターを使えば、
自動でSwaggerの修正してくれて、かつコンパイルエラーで呼び出し部分のエラー箇所を教えてくれるので、
ぜひ、使ってみると良いのではないでしょうか

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?