🙆

Nuxt.jsでWebアプリケーション開発メモ(番外編)

に公開

Django + Nuxt.js OpenAPIでスキーマ自動生成

1. Django側の設定

1.1 必要なパッケージをインストール

cd backend/prototype_backend
pip install drf-spectacular

1.2 Django設定を更新

# settings.py
INSTALLED_APPS = [
    'rest_framework',
    'drf_spectacular',  # 追加
    # ... 他のアプリ
]

REST_FRAMEWORK = {
    'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}

SPECTACULAR_SETTINGS = {
    'TITLE': 'Prototype API',
    'DESCRIPTION': 'Prototype Backend API Documentation',
    'VERSION': '1.0.0',
    'SERVE_INCLUDE_SCHEMA': False,
}

1.3 URLパターンを追加

# urls.py
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView

urlpatterns = [
    # API schema
    path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
    # Swagger UI
    path('api/docs/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),

    # 既存のAPI URLs
    path('api/', include('api.urls')),
]

1.4 APIビューにスキーマを追加

# api/views.py
from drf_spectacular.utils import extend_schema
from rest_framework.response import Response

class UserListCreateAPIView(generics.ListCreateAPIView):
    @extend_schema(
        description="ユーザー一覧取得",
        responses={200: UserListSerializer(many=True)}
    )
    def get(self, request):
        # 既存のコード
        pass

    @extend_schema(
        description="新規ユーザー作成",
        request=UserCreateSerializer,
        responses={201: UserCreateSerializer}
    )
    def post(self, request):
        # 既存のコード
        pass

2. フロントエンド側の設定

2.1 必要なパッケージをインストール

cd frontend/prototype_frontend
npm install --save-dev openapi-typescript

2.2 型定義生成スクリプトを追加

{
  "scripts": {
    "generate-types": "openapi-typescript http://localhost:8000/api/schema/ -o types/api.ts",
    "dev": "npm run generate-types && nuxt dev",
    "build": "npm run generate-types && nuxt build"
  }
}

2.3 型定義用ディレクトリを作成

mkdir types

3. 開発フローの自動化

3.1 開発サーバー起動(型定義自動更新)

npm run dev

3.2 生成された型定義を使用

// types/api.ts が自動生成される
import type { paths } from '@/types/api'

// ログインAPIの型
type LoginRequest = paths['/api/auth/login/']['post']['requestBody']['content']['application/json']
type LoginResponse = paths['/api/auth/login/']['post']['responses']['200']['content']['application/json']

// 使用例
const response = await $fetch<LoginResponse>('/api/auth/login/', {
  method: 'POST',
  body: loginData as LoginRequest
})

4. 確認方法

4.1 Swagger UIでAPI仕様確認

http://localhost:8000/api/docs/

4.2 生成された型定義確認

export interface paths {
  "/api/auth/login/": {
    post: {
      requestBody: {
        content: {
          "application/json": {
            username: string;
            password: string;
          };
        };
      };
      responses: {
        200: {
          content: {
            "application/json": {
              access: string;
              refresh?: string;
            };
          };
        };
      };
    };
  };
}

→ Nuxt.jsでWebアプリケーション開発メモ9

Discussion