dmr-from-django-ninja について
dmr-from-django-ninja は、`django-ninja` / `ninja-extra` の API トランスポート層を `django-modern-rest` へ段階的に移行する開発スキルです。業務ロジックと API 契約の維持を重視し、承認済みの変更を明示しながら、プロジェクト標準の検証を行います。
主な機能
- 01API を範囲ごとに段階移行
- 02ルートと入出力契約を維持
- 03DTO、コントローラー、ルーターを置換
- 04プロジェクト標準ライブラリーを評価・活用
- 05テストを更新して CI で検証
活用シーン
- 01Ninja API を DMR に移行
- 02ステータス、認証、スロットリングの維持
- 03Django API を分割移行して検証
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ wemake-services/ django-modern-rest --skill dmr-from-django-ninjaインストール後、Claude Code で/dmr-from-django-ninjaを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.claude-plugin/plugin.jsonagents/openai.yamlreferences/ninja-to-dmr-map.md詳細
django-ninja から DMR へ
概要
django-ninja / ninja-extra のトランスポート層を、段階的に django-modern-rest へ移行します。
ユーザーから明示的な依頼がない限り、ビジネスロジックは変更しないでください。
必ず最初に参照するドキュメント:
- DMR LLM ドキュメント:https://django-modern-rest.readthedocs.io/llms-full.txt
- ローカルマップ:references/ninja-to-dmr-map.md
移行ポリシー
- デフォルトモード:厳密なトランスポートの同等性。
- デフォルトで維持するもの:パス、メソッド、リクエスト/レスポンスのスキーマ、ステータスコード、ヘッダー、認証のセマンティクス、スロットリングのセマンティクス。
- ユーザーが差異を承認した場合(たとえば、DMR ネイティブのエラー形式/ステータスへの切り替え)、レガシーの動作を強制するのをやめ、その変更を
approved driftとして記録します。 - 暗黙の差異を混在させないでください。意図的な不一致はすべて明示的に列挙してください。
- 実装方針として Ninja のインフラ内部を維持しないでください。 外部から確認できる契約は維持しつつ、DMR とプロジェクト標準のライブラリを使って実現してください。
ワークフロー
Ninja の使用箇所を棚卸しする
- まずプロジェクトの API エントリーポイントと URL の配線を確認します。
- 次の使用箇所を探します:
NinjaExtraAPI、api_controller、http_get/http_post/...、ninja.Schema、ninja_jwt、Ninja の例外ハンドラー、Ninja のスロットル。 - エンドポイントごとの移行マトリクスを作成します:
- パス、メソッド、認証、スロットル、入力 DTO、出力 DTO、
- 期待されるステータス、期待されるヘッダー、
- 既知のエラーパス。
プロジェクト標準の機能を棚卸しする(必須)
- アダプターを作成する前に、移行後のトランスポート層を支えるべき既存のプロジェクトライブラリや統合を確認します。
- カスタムラッパーよりも、DMR の仕組みを通じて、プロジェクトですでに使用されているライブラリ(「Django の標準機能」)を優先してください。
- 例:
- レート制限:Ninja のスロットルをラップするのではなく、
django-ratelimitの統合がある場合はそちらを優先します。 - 認証/アカウントロックアウト:Ninja 固有の認証内部を再利用するのではなく、既存のプロジェクト認証スタック(例:axes/ミドルウェア)を優先します。
- レート制限:Ninja のスロットルをラップするのではなく、
外部から確認できる動作を固定する
- 既存のテスト、DTO、ルーティングから動作を把握します。
- コーディング前に、移行を妨げる不一致を明確にします:
- ルート/メソッドの変更、
- スキーマフィールドの変更、
- 認証/スロットルの変更、
- ステータス/ヘッダーの変更。
エラー方針を決定する(必須のゲート)
編集前にどちらかを選び、記録します:
strict parity:- 既存のエラーステータス/ペイロードのセマンティクスを維持します。
- 必要に応じて DMR のハンドラー/コンテキストに適合させます。
approved DMR-native errors:- フレームワークネイティブのエラーマッピングを使用します。
- それに応じてテストとドキュメントの想定を更新します。
- 正常系の動作と認証/スロットルの動作は引き続き維持します。
スライス単位(アプリまたはエンドポイントグループ)で移行する
- 一度に移行する範囲を限定します。
- アーキテクチャ/Lint の契約上必要な場合を除き、モジュール構成を維持します。
- Ninja のインフラを示すクラス名は維持しないでください。 トランスポートクラスの名前を中立的な名前、または DMR に沿った名前に変更します。
- 薄いトランスポートアダプターを優先します:
- ユースケース/サービス/リポジトリには手を加えず、
- DTO/コントローラー/ルーターの配線のみを変更します。
DTO とコンポーネントを移行する
ninja.Schemaを、DMR シリアライザーに対応する明示的な型付き DTO に置き換えます。- リクエストの入力元を明示的にマッピングします:
- ボディ
Body[...]、クエリQuery[...]、パスPath[...]、ヘッダーHeaders[...]、CookieCookies[...]。
- ボディ
- レスポンスにサーバー所有のフィールドが含まれる場合は、入力 DTO と出力 DTO を分けます。
ハンドラーを DMR に移行する
- 単一の操作:
Controller[...]。 - 複数のメソッドがあるパス:コントローラーとコンポジション。
- ユーザーが差異を求めていない限り、ルート名と URL 形式を維持します。
- 例外の動作を意図的に移行します:
- 厳密な同等性モード:以前のステータス/ペイロードを維持します。
- 承認済みの差異モード:DMR ネイティブのエラーを維持し、テストを更新します。
API の配線を置き換える
NinjaExtraAPIを DMR ルーターと Django の URL include 配線に置き換えます。- 差異が承認されていない限り、名前空間の安定性(
api:*名)を維持します。 - プロジェクトがすでに公開している場合に限り、docs/OpenAPI ルートを追加します。
ネイティブ機能で認証とスロットリングを移行する
- 認証要件はエンドポイントごとに維持します。
- 承認された差異がない限り、スロットリングの動作とヘッダー(例:
Retry-After)を維持します。 - DMR フックを通じて、既存のプロジェクト標準の認証/スロットリングライブラリを優先して使用します。
- ローカル開発とテストでは、グローバルな
validate_responses設定を必ず有効にします。 - 追加レスポンスはすべて
ResponseSpecで明示的に宣言します。 - すべてのレスポンスでレスポンス検証を必須にします。
- 最終的な解決策として Ninja 互換シムを使用しないでください。
一時的なシムが避けられない場合は、一時的なものだと明記し、
置き換え計画を文書化して、
unresolved gapsに記載してください。
DMR ツール用にテストを更新する
- Ninja 固有のテストツール(
ninja.testing.TestClient、 NinjaExtra ヘルパー、Ninja URL 設定フィクスチャ)を、リポジトリ標準の Django/DMR テストエントリーポイントに置き換えます。 - API テストのフィクスチャとクライアントも、移行の主要な対象として扱います。
フィクスチャの意図(
api_client、authed_api_client、トークン/認証フィクスチャ)は維持しつつ、 移行後の DMR スタックに再バインドします。 pytestプラグインの設定(conftest.py/プラグインモジュール)を監査、更新し、 移行した API テストが Ninja 専用のフィクスチャやヘルパーに依存しないようにします。- コントラクトのアサーションはエンドポイントごとに維持します。 ステータスコード、ペイロード、ヘッダー、認証動作、スロットリング動作を確認します。
- ネガティブパスのテストで、宣言済みの追加レスポンスを網羅し、
ResponseSpecのメタデータと一致させます。 - 一時的な差異として明示的に承認された場合を除き、移行したテストモジュールから
django-ninja/ninja-extraのインポートを削除します。
リポジトリ標準の CI エントリーポイントで各スライスを検証する
- このリポジトリで CI が使うのと同じコマンドを実行します。
- アドホックなコマンド群より、公式スクリプトのエントリーポイントを優先します。
- Docker 専用の CI/テスト環境が必要な場合は、Docker 内で実行します。
完了ゲート
以下を満たすまで、スライスを完了扱いにしないでください。
- リンターが成功している
- テストが成功している(または失敗が承認済みの差異として明示されている)
- レポートが更新されている
翻訳ルール
- デフォルトではビジネスロジックを変更しません。
- トランスポートの決定性と型付けを維持します。
- 隠れたルート正規化の変更(末尾スラッシュ/プレフィックス)を避けます。
- エラーペイロード形式に差異が生じても、認証とスロットリングのセマンティクスを維持します。
- フレームワークの制約(例:DMR ネイティブの検証動作)を明示します。
- 一時的なものとしてユーザーから明示的に承認されない限り、移行対象のスライスでは
django-ninja/ninja-extraのクラスを使用しないでください。 - 移行対象のトランスポートコードに、Ninja に結び付いたクラス名(例:
Ninja...で始まる名前)を残さないでください。
レポート形式(必須)
意味のある各チェックポイントと完了時に、次の3セクションで報告します。
preserved behaviorapproved driftunresolved gaps
unresolved gaps には、未解決である理由とともに、具体的なファイル/エンドポイントを記載する必要があります。
移行時の落とし穴(リポジトリに基づく)
django-ratelimitの統合では、文字列としてmethod='ALL'を渡さないでください。ratelimit.core.ALL(または同等のタプル)を使用しないと、レート制限が気付かれないまま動作しません。- ベースの Pydantic 設定で
strict=Trueを使用している場合、JSON の UUID 文字列が検証に失敗することがあります (Input should be an instance of UUID)。JSON から UUID を受け取るリクエスト DTO フィールドでは、 明示的にパースを許可してください(例:フィールド単位でstrict=Falseを指定)。 - 厳密な入力スキーマ(未知のフィールドをエラーにする)を維持する場合、入力 DTO に
extra='ignore'を設定したベースモデルを使用しないでください。入力 DTO の設定で余分なフィールドを拒否します (例:extra='forbid')。 approved DMR-native errorsモードでは、DB の整合性エラーがマッピングされていないと、 未処理の 500 エラーとして表面化することがあります。レガシーな Ninja のペイロード形式を復活させずに クライアント向けの予測可能なエラー動作を維持するには、DMR のエンドポイント/コントローラーのエラーハンドリング (modify(error_handler=...)またはコントローラーレベルのハンドラー)を使用してください。- CI の衛生管理:プロジェクト内にツール関連の成果物(例:アドホックな virtualenv/poetry 実行による
.local/...)を作成する デバッグコマンドは避けてください。フォーマット/lint の各段階でスキャンされ、失敗する可能性があります。
出力チェックリスト
- Ninja のルート配線を DMR ルーティングに置き換えました。
- Ninja のコントローラー/ハンドラーを DMR コントローラーに置き換えました。
- 移行したエンドポイントの
ninja.SchemaDTO を置き換えました。 - 認証/スロットリングの動作を維持するか、差異を明示的に承認しました。
- プロジェクト標準の機能を最初に評価し、可能な場合は使用しました。
- 移行したトランスポート層に、永続的な Ninja シムや Ninja に依存する命名が残っていません。
- 選択した方式で同等の動作カバレッジを維持するために必要な場合にのみ、テストを更新しました。
- レスポンス検証を有効にし、移行したすべてのエンドポイントのレスポンスが検証に合格しています
(
ResponseSpecで宣言された追加のレスポンスも含みます)。 - スライスごとに、リポジトリ標準の CI エントリーポイントを実行しました。
- 必須の 3 セクション形式で最終レポートを出力しました。
- 移行が成功し、移行した API サーフェスの CI が成功した後、ユーザーが保持を明示的に承認した場合を除き、プロジェクトの依存関係から 'django-ninja' と 'ninja-extra' を削除します。
コメント
Markdown 対応