Precena Tech Book
コーポレートサイト採用サイト
  • はじめに
  • ソフトウェア開発
    • 開発環境構築
      • Homebrew
        • Homebrew用語の意味
      • ngrok
        • ngrokの導入
        • ngrokのアップグレード(v2 to v3)
      • Slack
        • Slackの/remind コマンドの形式
        • 対面での相談を気軽にするためのSlack設定
      • AWS CLI
      • Ruby
      • Scala
      • Prettier
      • zsh
        • zsh-completion
      • Mac
        • M1 Macでの開発環境構築(rosetta 無し)
    • バックエンド
      • OpenAPI
        • OpenAPI 定義ファイル分割のすゝめ
      • Ruby on Rails
        • ActiveRecordのfind_or_initialize_byメソッドにブロックを渡したときの挙動
        • Railsのアプリケーションサーバーのプロセス数とスレッド数の設定方法
        • Railsを6.1系から7.0系へアップグレードした時に調査したこと
        • schema.rbで差分が発生する事例とその復旧について
        • tmux + overmind を利用して、複数システムを1コマンドで起動できるよう設定する
        • Rails Migrationチートシート
        • GithubのプライベートリポジトリをGemfileで参照する方法
        • ActiveSupportのto_jsonメソッドの注意点
        • 危険なJSON出力を禁止するRuboCopカスタムルールの作成方法
      • Scala
        • Validated を直列に処理したい
      • DB
        • PostgreSQLにおける、削除行に対するロック獲得時の挙動
    • フロントエンド
      • React
        • Storybookを利用したビジュアルリグレッションテスト
  • インフラ開発
    • AWS
      • IAM
        • スイッチロールの設定手順
        • AWS CLIでのスイッチロールの設定手順
        • AWS Vaultを使ったスイッチロール設定手順
        • Github ActionsでIAMロールを利用してAWSリソースを操作する
      • ECS
      • SES
        • AWS SESメールボックスシミュレーターにて、カスタムヘッダや添付ファイル付きのテストEメールを送信する
      • CloudWatch
        • Amazon SNS + Slack Workflowを使って、CloudWatch Alarmの通知をSlackチャンネルへ投稿する
      • Lambda
        • lambrollでAWS Lambda関数をデプロイしたときのTips
    • Heroku
      • HerokuのStackの設定
      • Heroku Postgresの運用でよく使うコマンド集
  • セキュリティ
    • Web
      • Same Origin PolicyとCORS
      • 脆弱性診断 2社同時依頼実施記録
  • Mail
    • SPF、DKIM、DMARCを使用した迷惑メール対策
  • データ分析
    • データ分析プロセス
  • SaaS
    • Zendesk
      • 問い合わせフォームの項目をサービスごとに出し分け、各サービス担当者に自動で振り分けてメールで通知する
  • イベント
    • RubyKaigi
      • RubyKaigi 2023 に現地参加しました
    • EMConf
      • EMConfJP2025_参加レポート
  • やってみた
    • IoT
      • Raspberry Pi + PaSoRi + Python で、勤怠打刻マシンを作ってみた
  • Precena Tech Book 管理
    • コンテンツ執筆時のルール
  • 関連リンク
    • プレセナエンジニア公式Twitter
GitBook提供
このページ内
  • OpenAPIとは
  • プロジェクトでの利用法
  • OpenAPI定義ファイルの分割
  • 肥大化するopenapi.yaml
  • openapi.yamlファイルの構成
  • ファイルの分割
  • フォルダ構造
  • まとめ

役に立ちましたか?

PDFとしてエクスポート
  1. ソフトウェア開発
  2. バックエンド
  3. OpenAPI

OpenAPI 定義ファイル分割のすゝめ

前へOpenAPI次へRuby on Rails

最終更新 6 か月前

役に立ちましたか?

OpenAPIとは

RESTfulなWebサービスを記述、生成、利用、可視化するためのインターフェースファイルの仕様です。 以前はSwaggerフレームワークの一部でしたが、2016年にOpenAPI Initiativeが統括する独立プロジェクトとなりました。 Swaggerや他のいくつかのツールは、インターフェースファイルを指定してコード、ドキュメント、テストケースを生成することが可能です。

プロジェクトでの利用法

プレセナの一部プロジェクトでは、API定義をOpenAPI仕様に従って記述するだけでなく、定義ファイル(openapi.yaml)からコードを自動生成して利用しています。

OpenAPI定義ファイルの分割

肥大化するopenapi.yaml

当初はAPI定義ファイルであるopenapi.yamlの1ファイルに全ての記述をしていました。 結果として、下記のような問題が発生しました。

  1. ファイルサイズの増加(約2500行)

  2. コンフリクトの頻発

  3. 編集すべき記述を素早く見つけられない

これらの問題に対処するためにopenapi.yamlの分割をおこなうことにしました。

openapi.yamlファイルの構成

openapi.yamlのファイルは大きく分けると下の様なブロックに分かれています。

  • バージョン情報といったメタ情報:info、serversなど

  • エンドポイントのURLやリクエスト/レスポンス情報:paths

  • 再利用可能なオブジェクト情報:components

openapi: "3.0.0"
info:
  version: 1.0.0
  title: Swagger Petstore
  license:
    name: MIT
servers:
  - url: http://petstore.swagger.io/v1
paths:
  /pets:
    get:
      summary: List all pets
      operationId: listPets
      tags:
        - pets
      parameters:
        - name: limit
          in: query
          description: How many items to return at one time (max 100)
          required: false
          schema:
            type: integer
            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"
・・・略・・・
components:
  schemas:
    Pet:
      type: object
      required:
        - id
        - name
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
        tag:
          type: string
    Pets:
      type: array
      items:
        $ref: "#/components/schemas/Pet"
・・・略・・・

主に記述量が肥大化してしまうのは pathsとcomponentsであったため、これらを別ファイルに分割しました。

ファイルの分割

ファイルの分割は簡単です。 定義内の他コンポーネントを参照できるようにするフィールドである$ref を相対パスで記述するだけです。

openapi.yaml

...(infoやserversは省略)...

paths:
  /pet:
    $ref: "./paths/pet.yaml"
  /pet/{petId}/upload-image:
    $ref: "./paths/upload-image.yaml"

/paths/pet.yaml

    get:
      summary: List all pets
      operationId: listPets
      tags:
        - pets
      parameters:
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            format: int32
      responses:
        '200':
          content:
            application/json:    
              schema:
                $ref: "../schemas/Pet" # $refの記述
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "../schemas/Error" # $refの記述

/schemas/Pet.yaml

    Pet:
      type: object
      required:
        - id
        - name
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
        tag:
          type: string

フォルダ構造

openapi.yamlをルートファイルとして、同階層にpathとschemasのフォルダを作成しました。

.
├── openapi.yaml
├── paths # pathの定義ファイルを置く
│   ├── pet.yaml
│   ├── pet_find-by-status.yaml
│   ├── ...
│   └── pet_petId_upload-image.yaml
└── schemas  # schemasの定義ファイルを置く
    ├── Pet.yaml
    ├── User.yaml
    ├── ...
    └── Tag.yaml

paths配下のファイルの命名規則としては、シンプルにエンドポイントURLの「/」を「_」にするファイル名としました。

/paths/pet/find-by-status.yaml のように階層を深くするアイデアもあったのですが、schemasへの参照を$refで記述する際、"../../schemas/Foo", "../../../schemas/Bar" のように 「..」を書く回数の混乱が生じないように現在のような命名規則をとりました。

エンドポイントURLにidが含まれる場合(ex. /pet/{petId}/upload-image)、理想的にはpet_[petId]_upload-image.yamlのようにしたかったのですが、「[]」を含むと自動生成コードで問題が生じたため、シンプルにpet_petId_upload-image.yaml としました。

まとめ

OpenAPIの正確な仕様については、↓から確認できます。

分割によって見通しがよく開発をすすめることができるようになりました。 Visual Studio Codeで開発しているなら、この拡張をいれることで$ref の記述からファイル参照もできるのでおすすめです。 しばらくこれで開発を進めてみて、課題感がまた出てきたらブラッシュアップしていきたいと思います。

https://swagger.io/specification/
https://marketplace.visualstudio.com/items?itemName=42Crunch.vscode-openapi
LogoOpenAPI-Specification/petstore.yaml at main · OAI/OpenAPI-SpecificationGitHub
Swagger UI で可視化したAPI定義のサンプル