Upgrade to Pro — share decks privately, control downloads, hide ads and more …

OpenAPIに静的解析とフォーマッターを導入する

 OpenAPIに静的解析とフォーマッターを導入する

CTOA若手エンジニアコミュニティ勉強会 #5
https://ctoa-wakate.connpass.com/event/318007/

uutan1108

May 31, 2024
Tweet

More Decks by uutan1108

Other Decks in Programming

Transcript

  1. 自己紹介 • うーたん ◦ X:@uutan1108 • 株式会社ゆめみ ◦ 新卒2年目 ◦

    サーバーサイドエンジニア • 趣味 ◦ アニメを観ること 3
  2. OpenAPI とは OpenAPI仕様(旧Swagger仕様) は、REST API用のAPI記述フォー マットです。 OpenAPI Specification (formerly Swagger

    Specification) is an API description format for REST APIs. An OpenAPI file allows you to describe your entire API, including https://ohmoriyusuke.github.io/openapi-sample/ What Is OpenAPI? https://swagger.io/docs/specification/about/
  3. paths: /pets: get: summary: List all pets description: Retrieves a

    list of all pets, with pagination options. parameters: - name: limit in: query description: How many items to return at one time (max 100) required: false schema: type: integer maximum: 100 format: int32 responses: "200": description: A paged array of pets headers: x-next: description: A link to the next page of responses schema: type: string content: application/json: schema: $ref: "#/components/schemas/Pets" https://github.com/OHMORIYUSUKE/openapi-sample/blob/main/openapi.yaml#L17-L51 openapi.yaml
  4. paths: /pets: get: summary: List all pets description: Retrieves a

    list of all pets, with pagination options. parameters: - name: limit in: query description: How many items to return at one time (max 100) required: false schema: type: integer maximum: 100 format: int32 responses: "200": description: A paged array of pets headers: x-next: description: A link to the next page of responses schema: type: string content: application/json: schema: $ref: "#/components/schemas/Pets" https://github.com/OHMORIYUSUKE/openapi-sample/blob/main/openapi.yaml#L17-L51 エンドポイント名 クエリパラメータ レスポンス
  5. { "name": "open-api-sample", "version": "1.0.0", "description": "", "main": "index.js", "author":

    "", "license": "ISC", "scripts": { "lint": "spectral lint 'openapi.yaml'", "lint:ci": "spectral lint --format github-actions -F warn 'openapi.yaml'", "check": "prettier --check .", "fix": "prettier --write .", "build": "redocly build-docs -o ./dist/index.html ./openapi.yaml", "generate:typescript": "openapi-generator-cli generate -i openapi.yaml -g typescript-axios -o generated/ts" }, "devDependencies": { "@openapitools/openapi-generator-cli": "^2.13.4", "@redocly/cli": "^1.13.0", "@stoplight/spectral-cli": "^6.11.1", "prettier": "^3.2.5" } } YAMLを指定して TypeScriptの スキーマを生成 package.json
  6. /** * Retrieves a list of all pets, with pagination

    options. * @summary List all pets * @param {number} [limit] How many items to return at one time (max 100) * @param {*} [options] Override http request option. * @throws {RequiredError} */ listPets: async (limit?: number, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => { const localVarPath = `/pets`; // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); let baseOptions; if (configuration) { baseOptions = configuration.baseOptions; } const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; const localVarHeaderParameter = {} as any; const localVarQueryParameter = {} as any; if (limit !== undefined) { localVarQueryParameter['limit'] = limit; } 自動生成された コード generated/ts/api.ts
  7. @stoplight/spectral-cli とは - カスタムルールセット: JSON または YAML オブジェクト を lint

    するためのカスタムルールを作成します。 - すぐに使えるルールセット: OpenAPI v2 & v3および AsyncAPIドキュメントの検証と lint Custom Rulesets: Create custom rules to lint JSON or YAML objects Ready-to-use Rulesets: Validate and lint OpenAPI v2 & v3 and AsyncAPI Documents @stoplight/spectral-cli https://www.npmjs.com/package/@stoplight/spectral-cli
  8. paths: /pets: get: summary: List all pets description: Retrieves a

    list of all pets, with pagination options. parameters: - name: limit in: query description: How many items to return at one time (max 100) required: false schema: type: integer maximum: 100 format: int32 responses: "200": description: A paged array of pets headers: x-next: description: A link to the next page of responses schema: type: string content: application/json: schema: $ref: "#/components/schemas/Pats" openapi.yaml
  9. { "name": "open-api-sample", "version": "1.0.0", "description": "", "main": "index.js", "author":

    "", "license": "ISC", "scripts": { "lint": "spectral lint 'openapi.yaml'", "lint:ci": "spectral lint --format github-actions -F warn 'openapi.yaml'", "check": "prettier --check .", "fix": "prettier --write .", "build": "redocly build-docs -o ./dist/index.html ./openapi.yaml", "generate:typescript": "openapi-generator-cli generate -i openapi.yaml -g typescript-axios -o generated/ts" }, "devDependencies": { "@openapitools/openapi-generator-cli": "^2.13.4", "@redocly/cli": "^1.13.0", "@stoplight/spectral-cli": "^6.11.1", "prettier": "^3.2.5" } } spectral lint package.json
  10. 静的解析を実行 open-api-sample % npm run lint > [email protected] lint >

    spectral lint 'openapi.yaml' /project/open-api-sample/openapi.yaml 45:23 error invalid-ref '#/components/schemas/Pats' does not exist paths./pets.get.responses[200].content.application/json.schema.$ref 115:10 warning oas3-unused-component Potentially unused component has been detected. components.schemas.Pets ✖ 2 problems (1 error, 1 warning, 0 infos, 0 hints) 静的解析を実行
  11. 静的解析を実行後 open-api-sample % npm run lint > [email protected] lint >

    spectral lint 'openapi.yaml' /project/open-api-sample/openapi.yaml 45:23 error invalid-ref '#/components/schemas/Pats' does not exist paths./pets.get.responses[200].content.application/json.schema.$ref 115:10 warning oas3-unused-component Potentially unused component has been detected. components.schemas.Pets ✖ 2 problems (1 error, 1 warning, 0 infos, 0 hints) スペルミス(パスをミス) を指摘
  12. paths: /pets: get: summary: List all pets description: Retrieves a

    list of all pets, with pagination options. parameters: - name: limit in: query description: How many items to return at one time (max 100) required: false schema: type: integer maximum: 100 format: int32 responses: "200": description: A paged array of pets headers: x-next: description: A link to the next page of responses schema: type: string content: application/json: schema: $ref: "#/components/schemas/Pats" https://github.com/OHMORIYUSUKE/openapi-sample/blob/main/openapi.yaml#L17-L51 スペルミス openapi.yaml
  13. prettier とは Prettierとは? 意見を取り入れたコード整形ツール 多くの言語をサポート ほとんどのエディタと統合できる オプションが少ない What is Prettier?

    An opinionated code formatter Supports many languages Integrates with most editors Has few options » YAML もサポート している Prettier stable https://prettier.io/
  14. paths: /pets: get: summary: List all pets description: Retrieves a

    list of all pets, with pagination options. parameters: - name: limit in: query description: How many items to return at one time (max 100) required: false schema: type: integer maximum: 100 format: int32 responses: "200": description: A paged array of pets headers: x-next: description: A link to the next page of responses schema: type: string content: application/json: schema: $ref: "#/components/schemas/Pets" openapi.yaml
  15. { "name": "open-api-sample", "version": "1.0.0", "description": "", "main": "index.js", "author":

    "", "license": "ISC", "scripts": { "lint": "spectral lint 'openapi.yaml'", "lint:ci": "spectral lint --format github-actions -F warn 'openapi.yaml'", "check": "prettier --check .", "fix": "prettier --write .", "build": "redocly build-docs -o ./dist/index.html ./openapi.yaml", "generate:typescript": "openapi-generator-cli generate -i openapi.yaml -g typescript-axios -o generated/ts" }, "devDependencies": { "@openapitools/openapi-generator-cli": "^2.13.4", "@redocly/cli": "^1.13.0", "@stoplight/spectral-cli": "^6.11.1", "prettier": "^3.2.5" } } prettier --check package.json
  16. open-api-sample % npm run check > [email protected] check > prettier

    --check . Checking formatting... openapi.yaml [error] openapi.yaml: SyntaxError: Nested mappings are not allowed in compact mappings (20:16) [error] 18 | /pets: [error] 19 | get: [error] > 20 | summary: List all pets [error] | ^^^^^^^^^^^^^ [error] > 21 | description: Retrieves a list of all pets, with pagination options. [error] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [error] > 22 | operationId: listPets [error] | ^ [error] 23 | tags: [error] 24 | - pets [error] 25 | parameters: All matched files use Prettier code style! フォーマッターを 実行
  17. open-api-sample % npm run check > [email protected] check > prettier

    --check . Checking formatting... openapi.yaml [error] openapi.yaml: SyntaxError: Nested mappings are not allowed in compact mappings (20:16) [error] 18 | /pets: [error] 19 | get: [error] > 20 | summary: List all pets [error] | ^^^^^^^^^^^^^ [error] > 21 | description: Retrieves a list of all pets, with pagination options. [error] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [error] > 22 | operationId: listPets [error] | ^ [error] 23 | tags: [error] 24 | - pets [error] 25 | parameters: All matched files use Prettier code style! descriptionのインデント がずれていることを指摘
  18. paths: /pets: get: summary: List all pets description: Retrieves a

    list of all pets, with pagination options. parameters: - name: limit in: query description: How many items to return at one time (max 100) required: false schema: type: integer maximum: 100 format: int32 responses: "200": description: A paged array of pets headers: x-next: description: A link to the next page of responses schema: type: string content: application/json: schema: $ref: "#/components/schemas/Pets" https://github.com/OHMORIYUSUKE/openapi-sample/blob/main/openapi.yaml#L17-L51 インデントが ずれている openapi.yaml
  19. Redoc とは Redoc は、OpenAPI (旧 Swagger) 定義からドキュメントを生成する オープン ソース ツールです。

    Redoc is an open source tool for generating documentation from OpenAPI (formerly Swagger) definitions. https://ohmoriyusuke.github.io/openapi-sample/ Redocly / redoc https://github.com/Redocly/redoc
  20. { "name": "open-api-sample", "version": "1.0.0", "description": "", "main": "index.js", "author":

    "", "license": "ISC", "scripts": { "lint": "spectral lint 'openapi.yaml'", "lint:ci": "spectral lint --format github-actions -F warn 'openapi.yaml'", "check": "prettier --check .", "fix": "prettier --write .", "build": "redocly build-docs -o ./dist/index.html ./openapi.yaml", "generate:typescript": "openapi-generator-cli generate -i openapi.yaml -g typescript-axios -o generated/ts" }, "devDependencies": { "@openapitools/openapi-generator-cli": "^2.13.4", "@redocly/cli": "^1.13.0", "@stoplight/spectral-cli": "^6.11.1", "prettier": "^3.2.5" } } redocly build-docs package.json
  21. 54

  22. 55