Claude CodeでREST API開発|設計からテストまでAI駆動で高速構築

kento_morota 21分で読めます

REST APIの開発は、現代のWebアプリケーション開発において欠かせないスキルです。しかし、エンドポイントの設計、バリデーションの実装、エラーハンドリング、ドキュメント作成など、多くの工程が必要であり、開発期間が長引きがちです。Claude Codeを活用すれば、API設計のたたき台作成からエンドポイントの実装、OpenAPI仕様書の自動生成、テストコードの作成まで、AI駆動で高速にAPIを構築できます。本記事では、ExpressとFastAPIの実例を交えながら、Claude Codeを使ったREST API開発の実践的な手法を解説します。

Claude Codeを使ったAPI設計の進め方

REST APIの開発において、最初のステップとなる設計は品質を大きく左右します。Claude Codeを使えば、要件からAPIの構造を素早く設計できます。

要件からエンドポイントを設計する

自然言語で要件を伝えるだけで、Claude CodeがRESTfulなエンドポイント設計を提案します。

> Eコマースサイトの商品管理APIを設計して。
> 以下の機能が必要:
> - 商品一覧の取得(ページネーション、フィルタリング)
> - 商品詳細の取得
> - 商品の登録・更新・削除(管理者のみ)
> - 商品カテゴリの管理
> - 商品画像のアップロード

Claude Codeは以下のようなエンドポイント設計を提案します。

メソッド パス 説明 認証
GET /api/v1/products 商品一覧取得 不要
GET /api/v1/products/:id 商品詳細取得 不要
POST /api/v1/products 商品登録 管理者
PUT /api/v1/products/:id 商品更新 管理者
DELETE /api/v1/products/:id 商品削除 管理者
GET /api/v1/categories カテゴリ一覧取得 不要
POST /api/v1/categories カテゴリ作成 管理者
POST /api/v1/products/:id/images 画像アップロード 管理者

このように、RESTfulな命名規則、適切なHTTPメソッドの選択、バージョニング(/api/v1/)、認証要件まで含めた設計を自動で行います。

CLAUDE.mdでAPI設計規約を定義する

CLAUDE.mdにAPI設計の規約を記載しておくことで、一貫したAPI設計を維持できます。

# CLAUDE.md のAPI設計規約
## API設計ルール
- RESTful設計原則に従う
- エンドポイントは複数形の名詞を使用(/users, /products)
- バージョニングはURLパスに含める(/api/v1/)
- ページネーションは limit/offset パラメータを使用
- レスポンスは { data, meta, errors } 形式で統一
- HTTPステータスコードを適切に使い分ける
- 認証はBearerトークンを使用

Express.jsでのAPI実装

Node.jsの代表的なフレームワークであるExpressを使ったAPI実装を、Claude Codeで高速に行う方法を見ていきましょう。

プロジェクトの初期セットアップ

> Express + TypeScript + Prisma でREST APIプロジェクトを初期セットアップして。
> ディレクトリ構造はレイヤードアーキテクチャで。

Claude Codeは以下のような構造でプロジェクトを生成します。

src/
├── routes/          # ルート定義
│   ├── index.ts
│   └── products.ts
├── controllers/     # リクエスト/レスポンス処理
│   └── productController.ts
├── services/        # ビジネスロジック
│   └── productService.ts
├── repositories/    # データアクセス層
│   └── productRepository.ts
├── middlewares/      # ミドルウェア
│   ├── auth.ts
│   ├── validation.ts
│   └── errorHandler.ts
├── validators/      # バリデーションスキーマ
│   └── productValidator.ts
├── types/           # 型定義
│   └── index.ts
├── utils/           # ユーティリティ
│   └── response.ts
├── prisma/          # Prismaスキーマ
│   └── schema.prisma
└── app.ts           # アプリケーションエントリ

エンドポイントの実装

設計に基づいて、エンドポイントを実装させましょう。

> 商品CRUDのエンドポイントを実装して。
> コントローラー、サービス、リポジトリの各レイヤーに分けて。

Claude Codeはレイヤードアーキテクチャに従い、各層の責務を適切に分離したコードを生成します。

// src/controllers/productController.ts
import { Request, Response, NextFunction } from 'express';
import { ProductService } from '../services/productService';
import { successResponse, errorResponse } from '../utils/response';

export class ProductController {
  constructor(private productService: ProductService) {}

  getAll = async (req: Request, res: Response, next: NextFunction) => {
    try {
      const { limit = 20, offset = 0, category, search } = req.query;
      const result = await this.productService.findAll({
        limit: Number(limit),
        offset: Number(offset),
        category: category as string,
        search: search as string,
      });
      res.json(successResponse(result.data, result.meta));
    } catch (error) {
      next(error);
    }
  };

  getById = async (req: Request, res: Response, next: NextFunction) => {
    try {
      const product = await this.productService.findById(req.params.id);
      if (!product) {
        return res.status(404).json(errorResponse('商品が見つかりません'));
      }
      res.json(successResponse(product));
    } catch (error) {
      next(error);
    }
  };

  create = async (req: Request, res: Response, next: NextFunction) => {
    try {
      const product = await this.productService.create(req.body);
      res.status(201).json(successResponse(product));
    } catch (error) {
      next(error);
    }
  };
}

FastAPIでのAPI実装

Pythonの高速APIフレームワークであるFastAPIでも、Claude Codeによる効率的な開発が可能です。

FastAPIプロジェクトの構築

> FastAPI + SQLAlchemy + Pydantic で商品管理APIを実装して。
> 型安全なスキーマ定義とCRUDエンドポイントを含めて。

Claude Codeは、FastAPIの機能を活かした型安全なAPI実装を生成します。

# app/routers/products.py
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from typing import Optional
from app.database import get_db
from app.schemas.product import (
    ProductCreate,
    ProductUpdate,
    ProductResponse,
    ProductListResponse,
)
from app.services.product_service import ProductService

router = APIRouter(prefix="/api/v1/products", tags=["products"])

@router.get("/", response_model=ProductListResponse)
async def get_products(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    category: Optional[str] = None,
    search: Optional[str] = None,
    db: Session = Depends(get_db),
):
    service = ProductService(db)
    return service.find_all(
        limit=limit, offset=offset,
        category=category, search=search
    )

@router.post("/", response_model=ProductResponse, status_code=201)
async def create_product(
    product: ProductCreate,
    db: Session = Depends(get_db),
):
    service = ProductService(db)
    return service.create(product)

FastAPIのPydanticスキーマによる自動バリデーション、依存性注入、自動ドキュメント生成などの特徴を最大限活用したコードが生成されます。

バリデーションとエラーハンドリング

堅牢なAPIには、適切な入力バリデーションとエラーハンドリングが不可欠です。Claude Codeはエラーハンドリングパターンを熟知しており、包括的なバリデーションロジックを生成できます。

リクエストバリデーション

> 商品登録APIのバリデーションを実装して。
> Zodスキーマを使って、名前(必須・100文字以内)、
> 価格(必須・正の整数)、説明(任意・1000文字以内)、
> カテゴリID(必須・存在チェック)を検証して。
// src/validators/productValidator.ts
import { z } from 'zod';

export const createProductSchema = z.object({
  name: z
    .string()
    .min(1, '商品名は必須です')
    .max(100, '商品名は100文字以内で入力してください'),
  price: z
    .number()
    .int('価格は整数で入力してください')
    .positive('価格は正の数で入力してください'),
  description: z
    .string()
    .max(1000, '説明は1000文字以内で入力してください')
    .optional(),
  categoryId: z
    .string()
    .uuid('不正なカテゴリIDです'),
});

export const updateProductSchema = createProductSchema.partial();

export const queryProductSchema = z.object({
  limit: z.coerce.number().int().min(1).max(100).default(20),
  offset: z.coerce.number().int().min(0).default(0),
  category: z.string().optional(),
  search: z.string().optional(),
});

統一的なエラーレスポンス

APIのエラーレスポンスを統一するミドルウェアも自動生成できます。

// src/middlewares/errorHandler.ts
import { Request, Response, NextFunction } from 'express';
import { ZodError } from 'zod';
import { Prisma } from '@prisma/client';

export function errorHandler(
  error: Error,
  req: Request,
  res: Response,
  next: NextFunction
) {
  // バリデーションエラー
  if (error instanceof ZodError) {
    return res.status(400).json({
      data: null,
      errors: error.errors.map((e) => ({
        field: e.path.join('.'),
        message: e.message,
      })),
    });
  }

  // Prisma固有のエラー
  if (error instanceof Prisma.PrismaClientKnownRequestError) {
    if (error.code === 'P2002') {
      return res.status(409).json({
        data: null,
        errors: [{ message: '既に存在するデータです' }],
      });
    }
    if (error.code === 'P2025') {
      return res.status(404).json({
        data: null,
        errors: [{ message: 'データが見つかりません' }],
      });
    }
  }

  // その他のエラー
  console.error(error);
  res.status(500).json({
    data: null,
    errors: [{ message: 'サーバー内部エラーが発生しました' }],
  });
}

OpenAPI仕様書の自動生成

APIドキュメントの作成は開発者にとって負担が大きい作業ですが、Claude Codeを使えばOpenAPI(Swagger)仕様書を自動生成できます。

実装コードからOpenAPI仕様を生成

> 実装済みのすべてのエンドポイントからOpenAPI 3.0仕様書を生成して。
> リクエスト/レスポンスのスキーマ、認証情報、エラーレスポンスを含めて。

Claude Codeは実装コードを分析し、エンドポイント定義、スキーマ定義、認証方式を含む包括的なOpenAPI仕様を生成します。ドキュメント自動生成機能と組み合わせることで、実装とドキュメントを常に同期させることが可能です。

# openapi.yaml(一部抜粋)
openapi: 3.0.0
info:
  title: 商品管理API
  version: 1.0.0
  description: Eコマースサイト商品管理API
paths:
  /api/v1/products:
    get:
      summary: 商品一覧取得
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
            minimum: 1
            maximum: 100
        - name: offset
          in: query
          schema:
            type: integer
            default: 0
      responses:
        '200':
          description: 成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProductListResponse'

APIテストの自動化

APIの品質を保証するためには、エンドポイントごとのテストが欠かせません。テスト自動生成の手法を活用して、包括的なAPIテストを作成しましょう。

エンドポイントテストの自動生成

> すべての商品APIエンドポイントに対する統合テストを生成して。
> 正常系・異常系・認証テストを含めて。

Claude Codeは各エンドポイントの正常系、異常系(不正入力、存在しないリソース)、認証テスト(未認証アクセス、権限不足)を網羅したテストを生成します。

// __tests__/integration/products.test.ts
describe('GET /api/v1/products', () => {
  it('商品一覧を取得できる', async () => {
    const response = await request(app).get('/api/v1/products');
    expect(response.status).toBe(200);
    expect(response.body.data).toBeInstanceOf(Array);
    expect(response.body.meta).toHaveProperty('total');
  });

  it('ページネーションが正しく動作する', async () => {
    const response = await request(app)
      .get('/api/v1/products?limit=5&offset=0');
    expect(response.body.data.length).toBeLessThanOrEqual(5);
  });

  it('カテゴリでフィルタリングできる', async () => {
    const response = await request(app)
      .get(`/api/v1/products?category=${testCategoryId}`);
    response.body.data.forEach((product: any) => {
      expect(product.categoryId).toBe(testCategoryId);
    });
  });
});

describe('POST /api/v1/products', () => {
  it('認証済みの管理者が商品を作成できる', async () => {
    const response = await request(app)
      .post('/api/v1/products')
      .set('Authorization', `Bearer ${adminToken}`)
      .send(validProduct);
    expect(response.status).toBe(201);
  });

  it('未認証ユーザーは商品を作成できない', async () => {
    const response = await request(app)
      .post('/api/v1/products')
      .send(validProduct);
    expect(response.status).toBe(401);
  });

  it('不正なデータでバリデーションエラーが返る', async () => {
    const response = await request(app)
      .post('/api/v1/products')
      .set('Authorization', `Bearer ${adminToken}`)
      .send({ name: '', price: -100 });
    expect(response.status).toBe(400);
    expect(response.body.errors).toBeDefined();
  });
});

認証・認可の実装

APIの認証・認可はセキュリティの要です。Claude Codeは一般的な認証パターンを理解しており、JWTやOAuthの実装を効率的に行えます。

JWT認証ミドルウェアの実装

> JWT認証のミドルウェアを実装して。
> ロールベースのアクセス制御も含めて。
// src/middlewares/auth.ts
import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';

interface JwtPayload {
  userId: string;
  role: 'admin' | 'user';
}

export function authenticate(req: Request, res: Response, next: NextFunction) {
  const token = req.headers.authorization?.replace('Bearer ', '');
  if (!token) {
    return res.status(401).json({ errors: [{ message: '認証が必要です' }] });
  }
  try {
    const payload = jwt.verify(token, process.env.JWT_SECRET!) as JwtPayload;
    req.user = payload;
    next();
  } catch {
    return res.status(401).json({ errors: [{ message: 'トークンが無効です' }] });
  }
}

export function authorize(...roles: string[]) {
  return (req: Request, res: Response, next: NextFunction) => {
    if (!roles.includes(req.user.role)) {
      return res.status(403).json({ errors: [{ message: '権限がありません' }] });
    }
    next();
  };
}

セキュリティ監査機能と併用すれば、認証実装のセキュリティ上の問題も事前に検出できます。

まとめ

Claude Codeを活用したREST API開発は、設計からテストまでのすべての工程を大幅に効率化します。本記事で解説した主要なポイントを振り返ります。

  • API設計:要件からRESTfulなエンドポイント設計を自動生成
  • 実装:Express/FastAPIで、レイヤードアーキテクチャに沿った実装を高速化
  • バリデーション:ZodやPydanticを使った型安全な入力検証を自動生成
  • エラーハンドリング:統一されたエラーレスポンス形式を一括実装
  • ドキュメント:OpenAPI仕様書を実装コードから自動生成
  • テスト:正常系・異常系・認証テストを網羅的に自動作成
  • 認証・認可:JWT認証とロールベースアクセス制御を安全に実装

API開発は反復的な作業が多い領域であるため、Claude Codeの恩恵を最も受けやすい分野の一つです。データベース移行Gitワークフローとの連携も含めて、開発プロセス全体の最適化を進めてみてください。まずは小規模なCRUD APIから始めて、徐々にClaude Codeの活用範囲を広げていくことをおすすめします。

#Claude Code#API開発#REST
共有:
無料メルマガ

週1回、最新の技術記事をお届け

AI・クラウド・開発の最新記事を毎週月曜にメールでお届けします。登録は無料、いつでも解除できます。

プライバシーポリシーに基づき管理します

AI活用のヒントをお探しですか?お気軽にご相談ください。

まずは話だけ聞いてもらう