TypeScript で API クライアント自動生成:OpenAPI・gRPC ツール導入の手引き

TypeScript で手作業による API クライアント作成に苦労されていませんか?API 仕様の変更のたびに型定義を手動で更新し、テストコードも書き直す。そんな繰り返し作業から解放される方法があります。
OpenAPI や gRPC といった API 仕様記述ツールと自動生成ツールを組み合わせることで、型安全で保守性の高い TypeScript API クライアントを効率的に開発できるのです。
本記事では、OpenAPI と gRPC それぞれの特徴を比較し、プロジェクトに最適なツール選定の指針をお伝えします。実際のエラー例や導入事例も交えながら、初心者の方にもわかりやすく解説いたします。
背景
API 開発の現代的課題
現代の Web アプリケーション開発では、フロントエンドとバックエンドの分離が当たり前となりました。この構成では、両者間のデータのやり取りに API が重要な役割を果たします。
しかし、API を介した開発には多くの課題が存在するのです。
型安全性とメンテナンス性の重要性
TypeScript を採用する主な理由の一つは、型安全性による開発効率の向上です。コンパイル時に型エラーを検出することで、実行時エラーを大幅に削減できます。
特に API クライアントにおいて型安全性は重要で、以下のようなメリットがあります:
- リクエスト・レスポンスの型チェック
- IDE での補完機能の活用
- リファクタリング時の影響範囲の把握
課題
手動クライアント作成の問題点
従来の手作業による API クライアント作成では、数多くの問題に直面します。
型定義の重複作業
バックエンドで定義したデータ構造を、フロントエンドで再度 TypeScript の型として定義する必要があります。
typescript// バックエンド(例:Go)
type User struct {
ID int64 `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
CreatedAt time.Time `json:"created_at"`
}
// フロントエンド(TypeScript)で手動定義
interface User {
id: number;
name: string;
email: string;
created_at: string; // 日付のシリアライズ形式要注意
}
この重複作業は時間がかかるだけでなく、人的ミスの温床となります。
実際のエラー例:型不整合
手動定義でよく発生するエラーです:
typescript// 実際のAPIレスポンス
{
"user_id": 123,
"user_name": "田中太郎",
"created_at": "2024-01-15T10:30:00Z"
}
// 間違った型定義
interface User {
id: number; // 実際は "user_id"
name: string; // 実際は "user_name"
createdAt: string; // 実際は "created_at"
}
// 実行時エラー
const user = await fetchUser(123);
console.log(user.id); // undefined - プロパティが存在しない
typescriptTypeScript Error:
Property 'id' does not exist on type 'User'.
Did you mean 'user_id'?
API 仕様変更への追従コスト
API 仕様が変更されると、クライアント側も同期して更新する必要があります。
バージョン管理の複雑さ
複数の API バージョンをサポートする場合、クライアント側の管理が複雑になります:
typescript// v1 API
interface UserV1 {
id: number;
name: string;
}
// v2 API(フィールド追加)
interface UserV2 {
id: number;
name: string;
email: string;
profile_image?: string;
}
// v3 API(ブレーキングチェンジ)
interface UserV3 {
user_id: string; // number から string に変更
full_name: string; // name から full_name に変更
email: string;
avatar_url?: string; // profile_image から avatar_url に変更
}
実際のエラー例:バージョン不整合
typescript// v2を想定したコード
const fetchUser = async (id: number): Promise<UserV2> => {
const response = await fetch(`/api/v2/users/${id}`);
return response.json();
};
// しかし実際はv3にアップデート済み
const user = await fetchUser(123);
// Runtime Error: Cannot read property 'name' of undefined
console.log(user.name); // v3では 'full_name' に変更済み
cssAPI Error Response:
{
"error": "Invalid user ID format",
"message": "User ID must be a string in v3 API",
"code": "INVALID_USER_ID_FORMAT"
}
チーム間での API 仕様共有の難しさ
ドキュメントの維持管理
API ドキュメントとの同期が取れず、実装とドキュメントに乖離が発生しがちです。
コミュニケーションコスト
フロントエンド・バックエンド間での API 仕様に関する問い合わせや確認作業が頻発します。
typescript// 開発中によく発生する問題
const createUser = async (userData: CreateUserRequest) => {
try {
const response = await fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(userData),
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return response.json();
} catch (error) {
// バックエンドが期待する形式がわからない
console.error('User creation failed:', error);
}
};
実際のエラー例:リクエスト形式不整合
typescript// フロントエンドが送信したデータ
const userData = {
name: '田中太郎',
email: 'tanaka@example.com',
age: 30,
};
// しかしバックエンドが期待するのは
interface CreateUserRequest {
user_name: string; // name ではなく user_name
email_address: string; // email ではなく email_address
birth_date: string; // age ではなく birth_date
}
cssAPI Error Response:
{
"error": "Validation Error",
"details": [
{
"field": "user_name",
"message": "Required field missing"
},
{
"field": "email_address",
"message": "Required field missing"
},
{
"field": "age",
"message": "Unknown field"
}
]
}
これらの課題を解決するために、API 仕様記述ツールと自動生成ツールの活用が重要になります。
解決策
OpenAPI ツールの選定と比較
OpenAPI(旧 Swagger)は、REST API の仕様を記述するための標準的な形式です。TypeScript クライアント生成に利用できる主要ツールを比較しましょう。
OpenAPI Generator
最も人気の高いコード生成ツールです。
特徴:
- 幅広い言語・フレームワークサポート
- カスタマイズ可能なテンプレート
- アクティブなコミュニティ
導入手順:
bash# OpenAPI Generator のインストール
yarn add -D @openapitools/openapi-generator-cli
# package.json にスクリプト追加
"scripts": {
"generate-api": "openapi-generator-cli generate -i api-spec.yaml -g typescript-axios -o src/generated/api"
}
Swagger Codegen
OpenAPI Generator の前身となるツールです。
特徴:
- 安定した実績
- Java ベースの実装
- レガシープロジェクトとの親和性
orval
より現代的なアプローチを取るツールです。
特徴:
- TypeScript ファーストの設計
- React Query / SWR との統合
- 軽量で高速
typescript// orval.config.js
export default {
'my-api': {
input: './api-spec.yaml',
output: {
target: './src/generated/api.ts',
client: 'react-query',
mock: true,
},
},
};
実際のエラー例:OpenAPI Generator 設定ミス
設定ファイルが正しくない場合によく発生するエラーです:
yaml# 間違った設定例
openapi: 3.0.0
info:
title: User API
version: 1.0.0
paths:
/users:
get:
responses:
200:
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
# components セクションが未定義
bashError: Unable to resolve reference: #/components/schemas/User
at /node_modules/@apidevtools/json-schema-ref-parser/lib/resolvers/file.js:53:11
gRPC ツールの選定と比較
gRPC は Google が開発した RPC フレームワークで、Protocol Buffers を使用してサービスを定義します。
grpc-tools
公式の gRPC ツールセットです。
特徴:
- Google 公式サポート
- 高いパフォーマンス
- 強力な型システム
導入手順:
bash# 必要なパッケージのインストール
yarn add grpc-web
yarn add -D grpc-tools @grpc/proto-loader
# Proto ファイルからコード生成
protoc --js_out=import_style=commonjs:./src/generated \
--grpc-web_out=import_style=typescript,mode=grpcweb:./src/generated \
./proto/user.proto
grpc-web
ブラウザ環境で gRPC を利用するためのツールです。
特徴:
- ブラウザ対応
- HTTP/2 ストリーミング
- Envoy プロキシとの連携
ts-proto
TypeScript に特化した Protocol Buffers コンパイラです。
特徴:
- TypeScript ネイティブサポート
- 小さなバンドルサイズ
- 現代的な TypeScript 機能活用
bash# ts-proto のインストールと設定
yarn add -D ts-proto
# 生成スクリプトの設定
protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto \
--ts_proto_out=./src/generated \
--ts_proto_opt=esModuleInterop=true \
./proto/user.proto
実際のエラー例:Protocol Buffers 構文エラー
Proto ファイルの構文が間違っている場合のエラーです:
protobuf// 間違った proto ファイルの例
syntax = "proto3";
package user;
service UserService {
rpc GetUser(GetUserRequest) returns (User); // セミコロンが不要
message GetUserRequest { // message は service 外で定義
int32 id = 1;
}
}
csharpuser.proto:7:3: Expected "service" or "message" or "enum" or "import" or "package" or "option".
user.proto:9:5: "message" is not allowed here.
ツール選定マトリックス
プロジェクトの要件に応じた最適なツール選定の指針を表で示します。
# | 項目 | OpenAPI Generator | orval | grpc-tools | ts-proto |
---|---|---|---|---|---|
1 | 学習コスト | 中 | 低 | 高 | 中 |
2 | 型安全性 | ○ | ◎ | ◎ | ◎ |
3 | パフォーマンス | ○ | ○ | ◎ | ◎ |
4 | カスタマイズ性 | ◎ | ○ | ○ | ○ |
5 | コミュニティ | ◎ | ○ | ◎ | ○ |
6 | REST API 対応 | ◎ | ◎ | ✗ | ✗ |
7 | gRPC 対応 | ✗ | ✗ | ◎ | ◎ |
8 | ブラウザ対応 | ◎ | ◎ | ○※1 | ○※1 |
9 | バンドルサイズ | 中 | 小 | 大 | 小 |
10 | リアルタイム通信 | ✗ | ✗ | ◎ | ◎ |
※1 grpc-web が必要
選定基準
REST API 中心のプロジェクト:
- 新規プロジェクト → orval
- 大規模・複雑な要件 → OpenAPI Generator
gRPC 中心のプロジェクト:
- パフォーマンス重視 → grpc-tools
- モダンな TypeScript 活用 → ts-proto
ハイブリッド環境:
- 段階的移行を計画している場合は両方の導入を検討
具体例
OpenAPI Generator による TypeScript クライアント生成
実際のプロジェクトで OpenAPI Generator を使用した TypeScript クライアント生成の手順を詳しく見ていきましょう。
プロジェクト構成
bashproject/
├── api-spec.yaml # OpenAPI仕様書
├── package.json
├── openapitools.json # Generator設定
└── src/
├── generated/ # 自動生成されるファイル
│ └── api/
└── components/
└── UserList.tsx # 生成されたクライアントを使用
OpenAPI 仕様書の定義
まず、API の仕様を定義します:
yaml# api-spec.yaml
openapi: 3.0.0
info:
title: User Management API
version: 1.0.0
servers:
- url: http://localhost:3001/api
paths:
/users:
get:
operationId: getUsers
summary: ユーザー一覧取得
responses:
'200':
description: 成功
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
'500':
description: サーバーエラー
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
続いてスキーマ定義を追加します:
yamlcomponents:
schemas:
User:
type: object
required:
- id
- name
- email
properties:
id:
type: integer
format: int64
example: 123
name:
type: string
example: '田中太郎'
email:
type: string
format: email
example: 'tanaka@example.com'
created_at:
type: string
format: date-time
profile_image_url:
type: string
format: uri
nullable: true
生成設定ファイル
json// openapitools.json
{
"generator-cli": {
"version": "7.0.0",
"generators": {
"typescript-axios": {
"generatorName": "typescript-axios",
"output": "./src/generated/api",
"glob": "**/*",
"additionalProperties": {
"typescriptThreePlus": true,
"withoutPrefixEnums": true,
"enumNameSuffix": "Type"
}
}
}
}
}
package.json 設定
json{
"scripts": {
"generate-api": "openapi-generator-cli generate",
"dev": "yarn generate-api && next dev"
},
"devDependencies": {
"@openapitools/openapi-generator-cli": "^2.7.0"
},
"dependencies": {
"axios": "^1.6.0"
}
}
生成される TypeScript 型定義
コード生成を実行すると、以下のような型定義が自動生成されます:
typescript// src/generated/api/api.ts (抜粋)
export interface User {
id: number;
name: string;
email: string;
created_at?: string;
profile_image_url?: string | null;
}
export interface Error {
message: string;
code?: string;
}
// API クライアントクラス
export class DefaultApi extends BaseAPI {
public getUsers(
options?: AxiosRequestConfig
): AxiosPromise<Array<User>> {
return DefaultApiFp(this.configuration).getUsers(
options
)(this.axios, this.basePath);
}
}
React コンポーネントでの使用例
生成されたクライアントを React コンポーネントで使用します:
typescript// src/components/UserList.tsx
import React, { useEffect, useState } from 'react';
import { DefaultApi, User } from '../generated/api';
const UserList: React.FC = () => {
const [users, setUsers] = useState<User[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const fetchUsers = async () => {
try {
const api = new DefaultApi();
const response = await api.getUsers();
setUsers(response.data);
} catch (err) {
setError('ユーザー取得に失敗しました');
console.error('API Error:', err);
} finally {
setLoading(false);
}
};
fetchUsers();
}, []);
if (loading) return <div>読み込み中...</div>;
if (error) return <div>エラー: {error}</div>;
return (
<div>
<h2>ユーザー一覧</h2>
{users.map((user) => (
<div key={user.id}>
<h3>{user.name}</h3>
<p>{user.email}</p>
</div>
))}
</div>
);
};
実際のエラー例:型不整合によるコンパイルエラー
API 仕様変更時に発生するコンパイルエラーの例です:
typescript// API仕様でemailフィールドが削除された場合
const UserProfile: React.FC<{ user: User }> = ({
user,
}) => {
return (
<div>
<h3>{user.name}</h3>
{/* TypeScriptコンパイルエラー */}
<p>{user.email}</p>
</div>
);
};
typescriptTypeScript Error:
Property 'email' does not exist on type 'User'.
TS2339: Property 'email' does not exist on type 'User'.
このエラーにより、API 仕様変更の影響を事前に検出できます。
gRPC-Web + Protocol Buffers 実装
次に、gRPC を使用したクライアント実装を見ていきましょう。
Protocol Buffers サービス定義
protobuf// proto/user.proto
syntax = "proto3";
package user.v1;
option go_package = "github.com/example/user-service/gen/go/user/v1";
// ユーザー管理サービス
service UserService {
// ユーザー取得
rpc GetUser(GetUserRequest) returns (GetUserResponse);
// ユーザー一覧取得
rpc ListUsers(ListUsersRequest) returns (ListUsersResponse);
// ユーザー作成
rpc CreateUser(CreateUserRequest) returns (CreateUserResponse);
}
// リクエスト・レスポンスメッセージ
message GetUserRequest {
int64 user_id = 1;
}
message GetUserResponse {
User user = 1;
}
message ListUsersRequest {
int32 page_size = 1;
string page_token = 2;
}
続いてレスポンスとユーザーメッセージを定義します:
protobufmessage ListUsersResponse {
repeated User users = 1;
string next_page_token = 2;
}
message CreateUserRequest {
string name = 1;
string email = 2;
}
message CreateUserResponse {
User user = 1;
}
// データ型定義
message User {
int64 id = 1;
string name = 2;
string email = 3;
google.protobuf.Timestamp created_at = 4;
optional string profile_image_url = 5;
}
TypeScript コード生成
ts-proto を使用して TypeScript コードを生成します:
bash# Proto ファイルから TypeScript コード生成
yarn protoc \
--plugin=./node_modules/.bin/protoc-gen-ts_proto \
--ts_proto_out=./src/generated \
--ts_proto_opt=outputServices=grpc-js,env=browser,useOptionals=messages \
./proto/user.proto
生成された TypeScript 型定義
typescript// src/generated/user.ts (抜粋)
export interface User {
id: number;
name: string;
email: string;
createdAt?: Date;
profileImageUrl?: string;
}
export interface GetUserRequest {
userId: number;
}
export interface ListUsersRequest {
pageSize: number;
pageToken: string;
}
export interface ListUsersResponse {
users: User[];
nextPageToken: string;
}
gRPC クライアントセットアップ
typescript// src/lib/grpc-client.ts
import { UserServiceClient } from '../generated/user_grpc_web_pb';
const client = new UserServiceClient(
'http://localhost:8080',
null,
null
);
export default client;
React での gRPC クライアント使用
typescript// src/components/UserListGrpc.tsx
import React, { useEffect, useState } from 'react';
import { ListUsersRequest, User } from '../generated/user';
import grpcClient from '../lib/grpc-client';
const UserListGrpc: React.FC = () => {
const [users, setUsers] = useState<User[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchUsers = async () => {
try {
const request = new ListUsersRequest();
request.setPageSize(50);
request.setPageToken('');
const response = await grpcClient.listUsers(
request,
{}
);
setUsers(response.getUsersList());
} catch (error) {
console.error('gRPC Error:', error);
} finally {
setLoading(false);
}
};
fetchUsers();
}, []);
return (
<div>
<h2>ユーザー一覧 (gRPC)</h2>
{users.map((user) => (
<div key={user.getId()}>
<h3>{user.getName()}</h3>
<p>{user.getEmail()}</p>
</div>
))}
</div>
);
};
実際のエラー例:gRPC 接続エラー
gRPC サーバーとの接続で発生するエラー例です:
typescript// CORS設定が不適切な場合のエラー
try {
const response = await grpcClient.listUsers(request, {});
} catch (error) {
console.error('gRPC Error:', error);
/*
Error: {
code: 14,
message: "UNAVAILABLE: failed to connect to all addresses",
metadata: {}
}
*/
}
vbnetBrowser Console Error:
Access to fetch at 'http://localhost:8080/user.v1.UserService/ListUsers'
from origin 'http://localhost:3000' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check.
ハイブリッド環境での運用例
既存の REST API と新しい gRPC サービスを並行運用する実装例をご紹介します。
API アダプターパターン
異なるプロトコルを統一したインターフェースで扱います:
typescript// src/lib/api-adapter.ts
export interface UserApiAdapter {
getUsers(): Promise<User[]>;
getUser(id: number): Promise<User>;
createUser(userData: CreateUserData): Promise<User>;
}
// REST API アダプター実装
export class RestUserApi implements UserApiAdapter {
private client = new DefaultApi();
async getUsers(): Promise<User[]> {
const response = await this.client.getUsers();
return response.data;
}
async getUser(id: number): Promise<User> {
const response = await this.client.getUser(id);
return response.data;
}
async createUser(
userData: CreateUserData
): Promise<User> {
const response = await this.client.createUser(userData);
return response.data;
}
}
gRPC アダプター実装:
typescript// gRPC API アダプター実装
export class GrpcUserApi implements UserApiAdapter {
private client = grpcClient;
async getUsers(): Promise<User[]> {
const request = new ListUsersRequest();
request.setPageSize(100);
const response = await this.client.listUsers(
request,
{}
);
return response.getUsersList().map(this.convertUser);
}
async getUser(id: number): Promise<User> {
const request = new GetUserRequest();
request.setUserId(id);
const response = await this.client.getUser(request, {});
return this.convertUser(response.getUser()!);
}
private convertUser(grpcUser: any): User {
return {
id: grpcUser.getId(),
name: grpcUser.getName(),
email: grpcUser.getEmail(),
created_at: grpcUser
.getCreatedAt()
?.toDate()
?.toISOString(),
};
}
}
設定による切り替え
環境変数によって API プロトコルを切り替えます:
typescript// src/lib/api-factory.ts
export function createUserApi(): UserApiAdapter {
const useGrpc =
process.env.NEXT_PUBLIC_USE_GRPC === 'true';
if (useGrpc) {
return new GrpcUserApi();
} else {
return new RestUserApi();
}
}
// React コンポーネントでの使用
const UserManager: React.FC = () => {
const [userApi] = useState(() => createUserApi());
const handleGetUsers = async () => {
try {
const users = await userApi.getUsers();
console.log('Users:', users);
} catch (error) {
console.error('API Error:', error);
}
};
return (
<div>
<button onClick={handleGetUsers}>ユーザー取得</button>
</div>
);
};
パフォーマンス監視
両方の API のパフォーマンスを監視する仕組みを実装します:
typescript// src/lib/api-metrics.ts
interface ApiMetrics {
protocol: 'rest' | 'grpc';
operation: string;
duration: number;
success: boolean;
}
export class MetricsCollector {
private static metrics: ApiMetrics[] = [];
static async measure<T>(
protocol: 'rest' | 'grpc',
operation: string,
apiCall: () => Promise<T>
): Promise<T> {
const startTime = performance.now();
let success = true;
try {
const result = await apiCall();
return result;
} catch (error) {
success = false;
throw error;
} finally {
const duration = performance.now() - startTime;
this.metrics.push({
protocol,
operation,
duration,
success,
});
}
}
static getMetrics(): ApiMetrics[] {
return [...this.metrics];
}
static getAverageLatency(
protocol: 'rest' | 'grpc'
): number {
const protocolMetrics = this.metrics.filter(
(m) => m.protocol === protocol
);
if (protocolMetrics.length === 0) return 0;
const totalDuration = protocolMetrics.reduce(
(sum, m) => sum + m.duration,
0
);
return totalDuration / protocolMetrics.length;
}
}
実際のエラー例:プロトコル切り替え時のエラー
環境設定ミスによるエラー例です:
typescript// 環境変数が設定されていない場合
const userApi = createUserApi();
try {
const users = await userApi.getUsers();
} catch (error) {
/*
TypeError: Cannot read properties of undefined (reading 'getUsers')
at UserManager.handleGetUsers
*/
}
vbnetEnvironment Configuration Error:
NEXT_PUBLIC_USE_GRPC is not defined in .env.local
Falling back to REST API, but gRPC client not initialized.
まとめ
TypeScript における API クライアント自動生成は、現代的なアプリケーション開発において必須のスキルとなっています。本記事では、OpenAPI と gRPC という 2 つの主要なアプローチを詳しく比較し、実際の導入手順と運用例をご紹介しました。
主要なポイントの振り返り
手動実装からの脱却
従来の手作業による API クライアント作成では、型定義の重複作業や API 仕様変更への追従コストが大きな課題でした。自動生成ツールの導入により、これらの問題を根本的に解決できます。
ツール選定の重要性
プロジェクトの要件に応じた適切なツール選定が成功の鍵となります:
# | 選定基準 | 推奨ツール | 理由 |
---|---|---|---|
1 | REST API 中心・新規プロジェクト | orval | TypeScript ファースト設計、軽量 |
2 | REST API 中心・大規模プロジェクト | OpenAPI Generator | 豊富なカスタマイズオプション |
3 | gRPC 中心・パフォーマンス重視 | grpc-tools | Google 公式、高性能 |
4 | gRPC 中心・モダンな開発 | ts-proto | 小さなバンドル、現代的機能 |
型安全性によるメリット
自動生成された TypeScript クライアントにより、以下のメリットを享受できます:
- コンパイル時エラー検出: API 仕様変更時の影響を事前に把握
- IDE サポート: 自動補完とリファクタリング支援
- ドキュメント同期: 仕様とコードの乖離防止
実際のエラー処理
記事で示した実際のエラー例は、以下のような検索で見つけやすくなっています:
Property 'email' does not exist on type 'User'
Unable to resolve reference: #/components/schemas/User
UNAVAILABLE: failed to connect to all addresses
CORS policy: Response to preflight request doesn't pass access control check
これらのエラーメッセージを参考に、トラブルシューティングを効率的に行えるでしょう。
導入時の推奨アプローチ
段階的導入戦略
既存プロジェクトへの導入は段階的に進めることをお勧めします:
Phase 1: 検証
bash# 小さなAPIエンドポイントで試験導入
yarn add -D @openapitools/openapi-generator-cli
yarn generate-api
Phase 2: 部分適用
- 新機能の API から自動生成クライアントを利用
- 既存 API とのハイブリッド運用
Phase 3: 全面移行
- 全 API エンドポイントの自動生成化
- CI/CD パイプラインへの統合
組織での導入成功のポイント
チーム教育の重要性
新しいツールの導入には、チーム全体の理解と協力が不可欠です。特に以下の点に注意しましょう:
- API 仕様書の書き方トレーニング
- 自動生成コードの扱い方説明
- エラー対処法の共有
品質管理の仕組み
自動生成されたコードの品質を保つため、以下の仕組みを導入することをお勧めします:
typescript// CI/CDでの自動チェック例
// .github/workflows/api-validation.yml
name: API Schema Validation
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'yarn'
- run: yarn install
- run: yarn generate-api
- run: yarn type-check
# 生成されたコードのテスト
- run: yarn test:generated-api
今後の発展性
エコシステムの進化
API クライアント自動生成のエコシステムは急速に進化しています。特に注目すべき動向:
- OpenAPI 3.1 対応: JSON Schema 完全対応による型表現力向上
- gRPC-Web の成熟: ブラウザでの gRPC 利用の簡素化
- GraphQL 統合: REST/gRPC/GraphQL の統一的な扱い
パフォーマンス最適化
自動生成ツールのパフォーマンスも向上し続けています:
- 並列処理: 複数 API 仕様の同時処理
- インクリメンタル生成: 変更差分のみ再生成
- Tree Shaking: 未使用コードの自動除去
実践への第一歩
まずは小さなプロジェクトや新機能から始めて、自動生成のメリットを実感してください。
今日から始められる最小構成
bash# 1. OpenAPI Generator のインストール
yarn add -D @openapitools/openapi-generator-cli
# 2. 簡単なAPI仕様の作成
echo "openapi: 3.0.0
info:
title: Test API
version: 1.0.0
paths:
/test:
get:
responses:
'200':
description: OK" > api-spec.yaml
# 3. TypeScript クライアント生成
yarn openapi-generator-cli generate \
-i api-spec.yaml \
-g typescript-axios \
-o ./src/generated/api
TypeScript における API クライアント自動生成は、開発効率と品質の両方を大幅に向上させる強力な手法です。適切なツール選定と段階的な導入により、あなたのプロジェクトでも必ず成果を得られるはずです。
ぜひ今日から実践を始めて、より効率的で安全な API 開発を体験してください。
関連リンク
公式ドキュメント
- OpenAPI Specification - OpenAPI 仕様の公式ドキュメント
- OpenAPI Generator - コード生成ツールの公式サイト
- gRPC - gRPC の公式サイト
- Protocol Buffers - Protocol Buffers の公式ドキュメント
TypeScript 関連ツール
- orval - 現代的な OpenAPI クライアント生成ツール
- ts-proto - TypeScript 特化の Protocol Buffers コンパイラ
- grpc-web - ブラウザ向け gRPC クライアント
学習リソース
- OpenAPI 3.0 Tutorial - OpenAPI 仕様の学習チュートリアル
- gRPC Basics - TypeScript - TypeScript での gRPC 基礎
- Axios Documentation - HTTP クライアントライブラリ
関連記事
- review
愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
- review
週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
- review
新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
- review
科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来
- review
人類はなぜ地球を支配できた?『サピエンス全史 上巻』ユヴァル・ノア・ハラリが解き明かす驚愕の真実
- review
え?世界はこんなに良くなってた!『FACTFULNESS』ハンス・ロスリングが暴く 10 の思い込みの正体