💬

API仕様書の構成/書き方(yaml)🧑‍💻🛜

に公開

はじめに🏃‍♀️‍➡️

この記事では完全初学者による初学者のための、API仕様書の構成/書き方(yaml)についてまとめました

APIとは???🤷‍♂️

APIとは、アプリとサーバーがやり取りするための窓口

AIに生成してもらった「API(ウェイター)」を例にした画像

◆API 仕様書 =【サーバーとアプリ間の取り決めを文字にした誤解0のコミュニケーションルール】のこと
◆YAML = 人間が読みやすいメモ帳形式の書き方
◆API仕様書 YAML =「設計図を YAML で書いたファイル」
→ いちばん有名なのが OpenAPIです。

API仕様書とアプリ・サーバーとの関連

そもそも API 仕様書とは

・スマホアプリや Web サイトがサーバーに「データちょうだい」とお願いするときのルールブック。
・何という URL を叩くか?
・どんなパラメータを送るか?
・成功したときはどんな JSON が返る?
・失敗したときはエラーコードはいくつ?
これらを 1 つのファイルにまとめると、プログラマー全員が同じルールで開発できます。

*️⃣ここでは本の情報を管理できるシンプルなAPI仕様書を元にAPI仕様書の構成/書き方について考えていきます
【概要】
このAPIは、本のタイトル・著者・出版社などの情報を登録、取得、更新、削除できるAPIです。

AIに作ってもらった【本の情報を管理】を想定した API 仕様書(YAML)

長いので上から順にパーツで区切って考えていきたいと思います

API仕様書で最低限必要な3オブジェクト

openapi: 3.0.3
info:
  title: 本管理API
  version: "1.0.0"
  description: |
    本のタイトル・著者・出版社・出版年を管理するためのAPIです。  
    認証無し・サンプル用途です。

api仕様書には必ず最低限記載しないといけないオブジェクトが3つあり、この画像にそのうちの2つあります。
それが、
🔴【open api】 ← 仕様バージョン宣言
🔴【info】 ← ドキュメントのタイトル、説明、バージョン情報
🔴【paths】
です。
▶info配下にあるものについては
-title: 本管理API  *このAPIドキュメントの名称
-version: "1.0.0" *ドキュメント自体のバージョン(上の段のopenapi:3.0.3 とは関連なし)
-description: |*説明
本のタイトル・著者・出版社・出版年を管理するためのAPIです。
認証無し・サンプル用途です。

servers オブジェクトとは

servers:
  - url: https://api.example.com/v1

🔴servers とは
servers: は「この API を呼ぶときの基準 URL(サーバー)」を列挙する場所のことです。

paths

paths:
  /books:
    get:
      summary: 本の一覧を取得
      responses:
        '200':
          description: 本のリストを返します
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Book'

paths の書き方と HTTP メソッド

API仕様書に必ず記載しないといけないオブジェクトの3つ目【paths:】の登場です

🔴paths: “APIエンドポイント”本体(※APIの「入り口」にあたるURLのこと。)
API仕様書の中で非常に重要な役割を担い、APIの設計を明確に伝えるための中心的な部分となります

HTTP メソッド概要

API 仕様書に出てくる「GET」「POST」などは、HTTP メソッド(動詞)のことです。
頻出の5つを以下に列挙していきます👍
メソッド:処理の種類(GET:取得、POST:追加、PUT:更新、DELETE:削除)

メソッド パス 説明
GET /books 本の一覧を取得する
POST /books 新しい本を登録する
GET /books/{id} 指定IDの本を取得する
PUT /books/{id} 指定IDの本を更新する
DELETE /books/{id} 指定IDの本を削除する

REST/HTTP API では、エンドポイント(URL)とメソッドを組み合わせて「何をどうするか」を表現します。

paths:が言おうとしていること

それでは、paths 内の内容を見ていきます

paths:
  /books:
    get:
      summary: 本の一覧を取得

この記述は、OpenAPI仕様書の「/books」というAPIエンドポイント(URL)でGETリクエスト(情報の取得)するとどうなるかを定義しています。

つまり「本の一覧を取得するAPI」の設計書を書いている部分です。
🔴summary: 本の一覧を取得
→このGETリクエストが何をするものかを、ここで短くまとめています。

 responses:
        '200':
          description: 本のリストを返します
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Book'

🔴responses:
返ってくるレスポンス(返事)の一覧。

🔴"200":
HTTPステータスコード。200は「成功した時」を意味します。

🔴description: 本のリストを返します
このレスポンスの説明。

🔴content:
サーバーが返すデータ形式ごとの設定。ここではapplication/json(JSON形式で返す)。

🔴schema:
返ってくるデータ(JSON)がどんな形なのかを定義します。

🔴type: array
レスポンスとして返るのは「配列(リスト)」ですよ、という意味。

🔴items:
その配列の「1個1個の中身」を定義します。

🔴$ref: '#/components/schemas/Book'
1つ1つのアイテムは「Book」という型(スキーマ)で定義されていますよ、という意味。
後ほどもう少し詳しく見ていきます👍

paths:が言いたかったこと

【結論】➡️この定義は
「/books に GET すると、本(Book型)の配列がJSONで返ってくる」
という設計・仕様を表しています!
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

おまけ

▶️次は、paths:ー/books:配下の2つ目のメソッド【POST】部分についても見てゆきます

post:
      summary: 新しい本を登録
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BookInput'
      responses:
        '200':
          description: 登録された本の情報を返します
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Book'

要素は先述の【GET】メソッドと同じなので説明は割愛します・・
【結論】➡️この API エンドポイントは

①クライアント(フロントエンドや別サービス)が「新しい本の情報」を JSON 形式で送る
②サーバー側がその本のデータをデータベースに登録する。
③登録が成功したら HTTP 200 で「登録後の本情報」を返す。

まとめると「クライアントが新しい本の詳細を送信し、サーバーがそれを登録して登録済みデータを返すための API」です。

🟨スキーマの効率化🟨

schema:
                $ref: '#/components/schemas/Book'

この書き方は、「スキーマ(データ構造)の定義を再利用するための参照」です。
具体的にどこを参照しているのか?
$ref(reference)の値が #/components/schemas/Book となっています。
これは**YAMLファイル内の「components > schemas > Book」**という場所を指しています。その本体は、yamlの下の方に必ず書かれています。

components:
  schemas:
    Book:              # ← ここ!
      type: object
      properties:
        id:
          type: integer
        title:
          type: string
        author:
          type: string
        publisher:
          type: string
        published_year:
          type: integer

コンポーネント

🔵コンポーネント:API間で重複実装を避け再利用可能にする仕組み
ここを書き換えれば、他で$ref指定している全部のレスポンスやリクエストも影響を受けるので、
型定義の「一元管理」「再利用」が簡単です!😊
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

paths:内の【/books】と【/books/{id}】の2つのパスを作った理由

🔶paths: 2つ目のエンドポイント【/books/{id}】部分についてみます
そもそもなぜ、【/books】と【/books/{id}】の2つのパス(エンドポイント)を作ったのか

パス 操作の対象 使い道の差
/books 本の全体・複数まとめて 一覧取得・新規登録
/books/{id} 特定の1冊(IDで指定した本) 詳細取得・更新・削除

【理由】
「全て/複数を扱う」ものと「特定1つを扱う」ものを分けることで、APIの設計がわかりやすくなるからです。
REST API(Webの定番設計ルール)では、この分け方が自然で直感的なので世界的に広く使われています
実生活にたとえると…
【/books】 は「図書館で本の棚を見る」「新しい本を追加する」感覚
【/books/5】 は「図書館でIDが5の本だけを特定して操作する」イメージ
➡️こうした設計を「RESTful(レストフル)」と呼びます。
▶️それでは、【/books/{id}】以降を見ていきましょう。

  /books/{id}:
    parameters:
      - name: id
        in: path
        required: true
        description: 取得・更新・削除したい本のID
        schema:
          type: integer
    get:
      summary: 指定IDの本を取得
      responses:
        '200':
          description: 本の情報を返します
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Book'
        '404':
          description: 本が見つからない場合
    put:
      summary: 指定IDの本を更新
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BookInput'
      responses:
        '200':
          description: 更新後の本の情報を返します
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Book'
        '404':
          description: 本が見つからない場合
    delete:
      summary: 指定IDの本を削除
      responses:
        '200':
          description: 削除完了メッセージを返します
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: 本を削除しました
        '404':
          description: 本が見つからない場合

GET(本の詳細取得) PUT(本の情報更新) DELETE(本の削除) メソッドがあり、それぞれリクエストに対してのレスポンスが記載されています。

parameterの働き

⭕/books/{id}: 直下の
parameters:部分に「このAPIエンドポイントが受け入れるパラメータ」のリストを書きます!

- name: id                   # パラメータ名が「id」です
  in: path                   # このパラメータは「パス」に含まれます(/books/1 の1の部分)
  required: true             # 必ず指定しないといけません
  description: 取得・更新・削除したい本のID  # パラメータの説明
  schema:
    type: integer            # idは整数でなければなりません

⏹️parameter:APIリクエスト時に「追加で渡す値・条件」のことです。
      ここではJSON形式で本の情報を渡します。
まとめ表

パラメーター スキーマ
目的 APIリクエストの条件・指定 データの形・中身の設計図
使われる場所 URL・クエリ・ヘッダーなど リクエストボディ&レスポンス
/books/{id} の id 本(Book)の情報(id, title等)
定義の仕方 parameters: やinlineで指定 schemas:にまとめて指定

🟥パラメーター:「どのデータを」「どうやって」取りたいか等の指定(主にリクエスト先・条件)
🟥スキーマ:「やりとりするデータ自体がどういう形か」という設計図(主にリクエストボディ・レスポンス)
両方ともとても大事なので、区別して使いましょう👍


requiredの働き

続いてコンポーネント内、
▶️required: 以降は何を表しているのか見ていきましょう☺️
白線で囲っていない部分は先に述べた、🟨スキーマの効率化🟨に該当する本体部分です👍
❓required: とは
required: は、その下にリストで書かれた項目(プロパティ)が
「必須である(=省略せず必ず値を指定しなければならない)」ことを示します。
❓どこで使うの
主に スキーマ定義(components > schemas > モデル名) の中で使います。

components:
  schemas:
    Book:
      type: object
      properties:
        id:
          type: integer
          example: 1
        title:
          type: string
          example: よくわかるAPI入門
        author:
          type: string
          example: 田中 太郎
        publisher:
          type: string
          example: サンプル出版
        published_year:
          type: integer
          example: 2024
      required:
        - id
        - title
        - author
        - publisher
        - published_year

💡この場合の意味
requiredのリストにある、
id, title, author, publisher, published_year
は、「Bookオブジェクトを用意するときは絶対に必ずこの5つを省略せず記述して下さい!」
という意味です。

フィールド名 説明
id integer 本のユニークなID 1
title string タイトル よくわかるAPI入門
author string 著者名 田中 太郎
publisher string 出版社名 サンプル出版
published_year integer 出版年 2024

▶️省略するとリクエスト/レスポンスとして**不正扱い(エラー)**になります

【重要】tags:

▶️今回のサンプル仕様書には出てきませんでしたが、かなりよく使う【tags:】メソッドについて触れます
利点: エンドポイントを論理的にグルーピングし、可読性とナビゲーションを向上させる
    ドキュメント UI(Swagger-UI、)でサイドバー区分けに使用

🟨使い方
*tags セクションで名前と説明を定義し
*paths: 各エンドポイントの tags 配列で参照。

【最後に・・・・】

  1. API仕様書・OpenAPIの目的
    API仕様書は「どんなデータをどうやってやりとりするか」「どのURLでどんな操作ができるか」を表す“設計図”です。
    OpenAPI(Swagger)は、その設計図を**プログラムや人間の両方が読めるフォーマット(YAMLやJSON)**で書くための国際的な標準フォーマットです。

2. パス設計 (/books と /books/{id} など)
/books は「本のリスト取得」「本の新規登録」など、複数まとめて or 新規追加に使うパス
/books/{id} は「特定の本1冊」に対する取得・更新・削除用のパス
この分け方はREST API の基本で、シンプルで分かりやすい設計になる

3. パラメーターとは?
パラメーターは「APIリクエストを送る時に値をセットする場所」。
例えば /books/{id} の「id」や /books?limit=10 の「limit」など
「何番の本を取るか」「何件とるか」などの“条件指定”に使う
OpenAPIでは、パスやクエリ、ヘッダーなどで使い分け、required: true で「必須」を指定できる

4. スキーマとは?
スキーマ(schema)は「やりとりするデータの設計図」
例:「本(Book)」のデータはid title author publisher published_year などでできている
データの構造や型、必須/任意項目などを components: 以下の schemas: で定義する
スキーマはリクエストやレスポンスの型チェックや自動生成ドキュメントにも利用される

5. Bookスキーマ/BookInputスキーマの違い
Bookスキーマ:APIレスポンス用、idを含む。「本の情報」として取得・返却時に使う
BookInputスキーマ:リクエスト(新規登録や更新)用、idは含まない。利用者が送るときの「入力フォーム」のようなもの
2つに分けることでAPIの役割や責任が明確&安全になる

6. components: とは
「再利用できる部品(モデルやパラメータ)」をまとめて書く場所
ここに「Book」などのスキーマを登録し、他の場所で $ref で参照する
可読性やメンテナンス性アップ!

7. required: の使い方
パラメーター定義での required: true は「この値は絶対に必要(省略不可)」
スキーマでの required: [title, ...] は「このプロパティが必須」
指定しないとバリデーションエラーとなり、安全なAPI運用が実現できる

Discussion