
QueryLift株式会社でバックエンド開発を担当しているウルフ ジャスティンと申します。
API開発において、フロントエンドとバックエンドの仕様齟齬による手戻りや、API仕様書と実装の乖離、新機能追加時のドキュメント更新漏れなどの課題は多くの開発チームが直面する問題です。
私たちQueryLiftでも、サービス開発において同様の課題に直面していました。しかし、OpenAPIを活用したSchema-First開発を導入することで、これらの課題を根本的に解決し、開発体験を大幅に改善することができています。
この記事では、実際にQueryLiftで導入したOpenAPI駆動開発の実装方法と、その過程で得られた学びをご紹介します。
従来のCode-First開発で感じていた課題
QueryLiftのサービス開発において、当初は一般的なCode-First開発を採用していました。つまり、まずバックエンドでAPIを実装し、その後にドキュメントを作成するという流れです。
しかし、この手法では以下のような課題に日常的に直面していました。
実装とドキュメントの乖離が常態化
最も深刻だったのは、実装後にドキュメントを作成するため、常に仕様と実装が乖離してしまうことでした。
弊社のようなスタートアップ企業においては、開発速度を重視するべくドキュメンテーションが後回しにされがちです。それにより、ドキュメントの陳腐化が大きな課題でした。
バックエンドAPI完成待ちのボトルネック
フロントエンド開発者は、バックエンドAPIが完成するまで実際の開発を進めることができず、モックデータでの開発に頼らざるを得ませんでした。
このため、フロントエンドとバックエンドの並行開発が困難で、全体的な開発スピードにボトルネックが生じていました。
口頭伝達による認識ズレ
新しいAPIエンドポイントの仕様について、SlackやMeetingでの口頭説明に頼ることが多く、細かな仕様について認識ズレが生じることがありました。
「このパラメータは必須でしたっけ?」「レスポンスの形式はどうなっていましたっけ?」といった確認作業が頻繁に発生していました。
OpenAPI Schema-First開発への転換決断
これらの課題を解決するため、私たちは開発手法を根本的に見直すことにしました。
なぜSchema-Firstに転換したのか?
従来の「実装→仕様書」の流れではなく、「仕様書→実装」への転換を行いました。
API仕様書を単なる「ドキュメント」ではなく、フロントエンドとバックエンド間の「契約書」として位置づけることで、以下のメリットを狙いました:
- 事前合意による手戻り削減:実装前に仕様を確定することで、後からの大幅な変更を防ぐ
- 並行開発の実現:仕様が確定した時点で、フロントエンドとバックエンドが同時に開発開始可能
- 自動化による品質向上:仕様書から自動でコード生成することで、人的ミスを削減
OpenAPIを選んだ理由
1. 豊富なエコシステム
OpenAPIには豊富なツール群が存在しており、コード生成、ドキュメント生成、テストツールなど、必要な機能がすべて揃っていました。
2. HTTP RESTとの親和性
QueryLiftのサービスはREST APIを採用しており、OpenAPIはこれに適合しました。
3. Swagger UIによる視覚的な仕様確認・共有
Swagger UIにより、エンジニアだけでなく、プロダクトマネージャーやデザイナーともAPIに関する仕様を共有がしやすかったです。
4. Go言語での自動コード生成サポート
バックエンドでGo言語を使用しているため、OpenAPI GeneratorによるGo言語のコード生成サポートが充実していることも決定要因でした。
QueryLift式:リポジトリ分離によるOpenAPI管理システム
OpenAPI導入にあたり、私たちは独自の管理システムを構築しました。その特徴は、「API仕様管理」と「実装」を完全に分離した2リポジトリ構成です。
リポジトリ分離のアーキテクチャ
API仕様管理リポジトリ
api-docs/
├── specs/
│ ├── base.yaml # ベース設定
│ ├── paths/ # APIパス定義
│ │ ├── auth.yaml
│ │ ├── users.yaml
│ │ └── ...
│ └── components/
│ └── schemas/ # データモデル定義
│ ├── common.yaml
│ ├── models.yaml
│ └── ...
├── merge-script.py # 分割ファイル統合スクリプト
└── dist/
└── openapi.yaml # 統合された完全仕様書バックエンド実装リポジトリ
backend/
├── gen/ # OpenAPIから自動生成されたコード
│ ├── interfaces.go
│ ├── models.go
│ ├── routes.go
│ └── ...
├── internal/
│ └── handlers/ # 生成インターフェースの実装
│ ├── auth_handler.go
│ ├── user_handler.go
│ └── ...
└── specs/ # API仕様書
└── openapi.yaml分割管理を採用した理由
機能ごとの独立した管理とレビュー
新機能追加時に、関連するファイルのみを変更すれば良いため、レビューが容易になりました。また、機能の削除時も該当ファイルを削除するだけで済みます。
共通スキーマの効率的な再利用
エラーレスポンスやページネーション情報など、複数のAPIで共通利用するスキーマをcomponents/schemas/に配置し、$refで参照することで、重複を排除しました。
大規模APIでも見通しの良い構造
APIエンドポイントが増加しても、ディレクトリ構造により整理された状態を保つことができます。
ファイル分割の具体例
実際のファイル構成の例:
base.yaml(ベース設定)
openapi: 3.0.0
info:
title: Sample API
version: 1.0.0
servers:
- url: http://localhost:8080paths/users.yaml(エンドポイント定義)
/api/v1/users:
get:
summary: ユーザー一覧取得
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '../components/schemas/models.yaml#/UserList'components/schemas/models.yaml(データモデル)
UserList:
type: object
properties:
users:
type: array
items:
$ref: '#/User'
User:
type: object
properties:
id:
type: integer
name:
type: string
required: [id, name]自動化システムの仕組み
分割管理されたOpenAPIファイルを実用的にするため、以下の自動化を実装しました。
ファイル統合の自動化
分割されたYAMLファイルを1つの完全なOpenAPI仕様書に統合するスクリプト(merge-openapi.py)を作成しました。このスクリプトを実行すると、各ディレクトリのyamlファイルを結合し、dist/openapi.yamlに完全なAPI仕様書を生成します。
コード自動生成
統合されたOpenAPI仕様書から、OpenAPI Generatorを使ってGoのコードを自動生成します:
# 仕様書の統合(merge-openapi.pyの実行)
make merge
# コード生成
make generate生成されるもの:
- APIインターフェース定義
- リクエスト/レスポンス構造体
- バリデーション関数
- ルーティング設定
生成されるコードの例
OpenAPI Generatorにより、以下のようなコードが自動生成されます:
インターフェース定義
// Code generated by OpenAPI Generator; DO NOT EDIT.
type UserAPIServicer interface {
GetUsers(context.Context) (ImplResponse, error)
CreateUser(context.Context, User) (ImplResponse, error)
}構造体定義
// Code generated by OpenAPI Generator; DO NOT EDIT.
type User struct {
ID int32 json:"id"
Name string json:"name"
}
// バリデーション関数も自動生成
func AssertUserRequired(obj User) error {
// 必須フィールドの検証ロジック
}このシステムにより、API仕様の変更から実装まで、一貫した自動化された開発フローを実現できました。
Schema-Firstによる開発ワークフローの変化
OpenAPI導入により、私たちの開発ワークフローは根本的に変化しました。
新しい開発フロー
1. API仕様設計
新機能開発は、まずOpenAPI仕様書の作成から始まります。実装の詳細ではなく、APIの外部インターフェースに集中して設計を行います。
2. 仕様レビューと合意
Swagger UIにより、エンジニアだけでなくプロダクトマネージャーなども含めて、視覚的に仕様を確認できます。この段階で仕様について十分に議論し、合意を形成することで、後の手戻りを大幅に削減できます。
3. 並行実装開始
仕様が確定した時点で、フロントエンドとバックエンドの実装を並行して開始できます:
- バックエンド: コード生成 → 生成されたインターフェースを実装
- フロントエンド: 型定義生成 → モックサーバーでの開発
4. 統合とテスト
生成されたコードにはバリデーション機能も含まれているため、OpenAPI仕様に準拠していないリクエスト/レスポンスを自動で検出できます。
実際に感じた改善点
事前の仕様合意により手戻りが大幅減少
従来は「とりあえず実装してみて、問題があったら修正」というアプローチでしたが、事前に仕様を確定することで、大幅な設計変更が後から発生することがほとんどなくなりました。
フロントエンド・バックエンドの並行開発が実現
最も大きな変化は、真の意味での並行開発が実現できたことです。フロントエンド開発者は、バックエンドAPIの完成を待つことなく、確定した仕様に基づいて開発を進めることができるようになりました。
チーム間のコミュニケーションコストが削減
「このAPIのレスポンス形式はどうなっていましたっけ?」といった確認作業が激減しました。常に最新のSwagger UIを参照すれば、すべての仕様を確認できるためです。
実装で工夫した技術的ポイント
実際の運用を通じて、以下の技術的な工夫を重ねてきました。
ファイル分割とスキーマ再利用
ファイル分割の基準を明確化し、チーム内で統一しました:
- パス定義: 機能やリソース単位で分割
- スキーマ定義: モデル単位で分割
- 共通要素: 複数機能で使用するものは独立ファイル化
エラーレスポンスなど、共通で使用するスキーマは効率的に再利用できるよう設計しました:
# 共通エラースキーマ
ErrorResponse:
type: object
properties:
error:
type: string
statusCode:
type: integer
required: [error, statusCode]自動バリデーションとカスタムルール
生成されたコードには、OpenAPI定義に基づく自動バリデーション機能が含まれています。さらにビジネス固有のルールが必要な場合は、UseCase層で追加実装しています。
統一されたエラーハンドリング
全てのAPIエンドポイントで一貫したエラーレスポンス形式を採用し、フロントエンド側でのエラーハンドリングを統一しました。
導入して分かった良かった点と課題
OpenAPI Schema-First開発を導入して、良かった点もあれば、課題もありました。
良かった点
API仕様書のメンテナンス工数がゼロに
API仕様書のメンテナンス工数が無くなったことは最も大きなメリットです。
従来は「実装が変わったからドキュメントも更新しなきゃ...」という作業が発生していましたが、Schema-Firstでは仕様書の変更が実装の起点となるため、常に仕様書が最新の状態に保たれます。
Swagger UIによる非エンジニアとの仕様共有が容易
プロダクトマネージャーとAPI仕様について議論する際に、Swagger UIが非常に有効でした。
技術的な詳細を知らないメンバーも含めて、APIの仕様について同じレベルで議論できるようになりました。
API設計の品質が自然と向上
OpenAPIで仕様を記述する過程で、API設計について深く考えるようになりました。
「このパラメータは本当に必要?」「レスポンスの構造はこれで適切?」といったことを、実装前に検討する習慣が身につき、結果的にAPI設計の品質が向上しました。
課題
初期の環境構築とルール策定に時間
2リポジトリ構成の環境構築や、ファイル分割のルール策定に想定以上の時間がかかりました。
特に、分割ファイル統合スクリプト(merge-openapi.py)の開発や、OpenAPI Generatorの設定調整などは、試行錯誤を重ねる必要がありました。
複雑なビジネスロジックはOpenAPIだけでは表現困難
OpenAPIはAPI仕様の記述には優れていますが、複雑なビジネスルールや状態遷移などは表現できません。
このため、補足的なドキュメントや、実装レベルでの詳細仕様書は別途必要でした。
まとめ - Schema-Firstが変えた開発文化
QueryLiftでのOpenAPIによるSchema-First開発導入を振り返ると、これは単なる技術的な変更ではなく、開発文化そのものを変革する取り組みでした。
「実装ありき」から「設計ありき」への意識変化
最も大きな変化は、チーム全体の意識が「とりあえず実装してみる」から「まず設計を固める」に変わったことです。この変化により、後戻りが大幅に減り、より計画的で品質の高い開発が可能になりました。
OpenAPIの真の価値
OpenAPIの価値は、単なるドキュメント生成ツールではなく、フロントエンドとバックエンド、そしてプロダクトチーム全体を繋ぐ「共通言語」となることにあります。技術的な詳細を知らないメンバーも含めて、APIの仕様について同じレベルで議論できるようになったことは、期待以上の効果でした。
継続的な改善の重要性
Schema-First開発は、導入したら終わりではありません。チームの成長や、プロダクトの複雑化に合わせて、継続的に改善していく必要があります。私たちも、より効率的で使いやすいシステムを目指して改善を続けています。
おわりに
現在、API開発での課題を感じているなら、OpenAPIによるSchema-First開発は有力な解決策の一つです。完璧なシステムを一度に構築する必要はありません。小さく始めて、チームに合った形で改善していけば、必ずその価値を実感できるはずです。
QueryLiftでの取り組みが、皆様の開発効率向上の参考になれば幸いです。