こんにちは。クロスマートで請求書を始めとした帳票サービスの開発を行っているDev2 テックリードのたけじい(@pouhiroshi)です。
先月は pytestを並列実行してCIを倍速にした話 - クロスマート Tech Blog と言う記事を寄稿させていただきました。 まだご覧になってない方はぜひそちらも読んでみてください。
Django上でREST APIを快適に開発する「Django Ninja」
DjangoはPythonで最も人気のあるウェブフレームワークの一つです。その柔軟性と強力な機能により、多くの開発者に選ばれています。しかしREST APIの開発においては、Djangoだけではいくつかの制限があります。 Django上でREST APIを開発する際に真っ先に思い浮かぶのは「Django Rest Framework」ではないでしょうか。弊社も利用しているフレームワークです。
これまではDRF以外に選択肢に上がるフレームワークはあまりありませんでしたが、ついに新たなフレームワーク「Django Ninja」が登場しました。
個人的にはDjangoNinjaのサイトに掲載されているこちらの標語が気に入っています。 fast to learn, fast to code, fast to run !! (早く習得でき、早くコードが書けて、早く実行できる! まるで忍者のように!)
この記事では、Django Ninjaがどのようなフレームワークであるか、その魅力と、簡単なサンプルを通じてその使い方をご紹介します。
Django Ninjaの概要
Django Ninjaは、Djangoの上に構築された、高速で使いやすいREST APIフレームワークです。Pythonの型ヒントをフルに活用し、開発者がより少ないコードで、より明確かつ効率的にAPIを構築できるよう設計されています。 FastAPIにインスパイアされたこのフレームワークは、非同期プログラミングもサポートしており、大規模なアプリケーションでも高性能を維持することができます。
すでにGithubのスター数は6.2k(2024/4/14時点)までに達しています。
Django Ninjaのいいところ
Django Ninjaの最大の魅力はそのパフォーマンスと生産性の向上です。 以下は公式サイトにも書かれている主な利点です。
- 高速実行: ASGIサポートにより非同期処理が可能で、リクエストを高速に処理できます。またRust製のPydanticV2を利用しており、高速にバリデーションを行うことができます。
- 型チェックの強化: Pythonの型ヒントを利用することで、エラーを事前に検出しやすくなり、開発プロセスがスムーズになります。
- 直感的なAPI設計: FastAPIにインスパイアされたこのフレームワークの開発は、ルーティングやリクエストのバリデーションがシンプルで、直感的にAPIを設計できます。
- APIの標準に基づいた設計:: OpenAPIやJSON Schemaなど、APIのオープンスタンダードに基づいています。特にルーターと入出力に該当するSchemaを実装すると、自動でSwaggerが自動生成される機能は秀逸です。
- Djangoのエコシステムとの互換性: Djangoの既存の機能やライブラリとシームレスに連携し、Djangoアプリケーションに容易に組み込むことができます。DjangoORMや既存の実装もそのまま利用可能です。
- 製品に利用事例あり: 複数の企業でライブプロジェクトに使用されており、実際の運用環境での利用が確認されています。
Pydantic v2についてはFastAPIでも利用されている高速ライブラリです。 以前にも記事にしましたので、気になる方はこちらを参照ください。 データ型検証ライブラリ Pydantic v2の紹介 - クロスマート Tech Blog
Django Ninjaを使ったREST APIのサンプル
以下のコードスニペットは、GETリクエストでユーザーのリストを取得し、POSTリクエストで新しいユーザーを追加する方法を示しています。
api.py
from ninja import NinjaAPI, Schema from typing import List class User(Schema): name: str # nameは必須 age: int | None = None # ageは任意項目のためNullable api = NinjaAPI() # データベースの代わりにリストを使用 users_db: List[User] = [ User(name="John Doe", age=30), User(name="Jane Doe", age=25) ] @api.get("/users") def list_users(request): return users_db @api.post("/users") def create_user(request, user: User): users_db.append(user) return {"success": True, "created_user": user} # 以下のようにDjangoのurls.pyにNinjaAPIを追加することを忘れないでください。
urls.py
from django.urls import path, include from .api import api # api.pyからapiインスタンスをインポート urlpatterns = [ path('api/', api.urls), # NinjaAPIのルートを追加 # 他のURLパターンがあればここに追加します。 ]
コードの解説
User
クラスの定義:User
クラスはSchema
を継承しており、これによりユーザーのデータ構造を定義しています。ここではname
とage
という2つのフィールドが含まれています。任意項目の場合はOptionalフィールドとして宣言し、デフォルト値を定義します。GETリクエスト (
api/users
エンドポイント): このエンドポイントは登録されている全ユーザーのリストを返します。実際のアプリケーションでは、このデータはデータベースから取得されることが一般的ですが、これはサンプルのためリストを代わりに使用しています。もちろん従来通り、DjangoORMを利用してデータベースからデータを取得することも可能です。POSTリクエスト (
api/users
エンドポイント): 新しいユーザーを作成するためのエンドポイントです。リクエストボディからユーザーデータを受け取り、それをusers_db
リストに追加します。成功した場合には、作成されたユーザー情報とともに成功メッセージを返します。postデータとしてUserスキーマを受け取っており、pydanticによるバリデーションが行われます。nameが必須項目となっておりnameがpostデータに含まれていない場合はDjango Ninjaが422エラーにハンドリングしてくれます。複雑なバリデーションがある場合も、スキーマでPydanticの@model_validatorや@field_validatorデコレータを利用してカスタムバリデーションを定義できます。
このようにDjango Ninjaを使うと、型ヒントを活用しながら簡潔にAPIエンドポイントを定義できます。入出力に関するバリデーションはSchemaで行われPydanticを利用して行われます。ここまで実装すればswaggerによるAPI仕様書の自動生成もされます。
おまけ(DjangoNinjaExtra)
Django Ninjaだけでも嬉しい機能はかなり揃っているのですが、それに加え、積極的な機能拡充が「Django Ninja Extra」というAddOnの形で提供され、こちらも活発に開発が進められているようです。
Django Ninja Extraは、Django Ninjaの機能を拡張するフレームワークで、特にクラスベースでAPIを設計するための追加機能が提供されています。以下に、その主要な特徴をまとめます。
- クラスベースの設計: APIをクラスベースの方式で設計することができます。(先程のルーター定義をControllerクラスに実装するようになります)これにより、オブジェクト指向の設計原則をAPI開発に適用しやすくなります。
- 権限管理: ルートレベルまたはコントローラーレベルで定義された権限や認証を使用して、エンドポイントを簡単に保護することができます。これにより、セキュリティが強化され、アクセス管理が容易になります。
- 依存性注入: コントローラークラスは、Pythonの
Injector
やdjango_injector
を用いた依存性注入をサポートしています。これにより、APIControllerクラスにAPIに依存するサービスを注入し、必要な場所で利用することが可能になります。
これらの機能により、Django Ninja Extraは、より柔軟かつ効率的なAPI開発を可能にします。 Django Ninja Extraにもぜひ注目してみてください。
まとめ
Django Ninjaは、DjangoでREST APIを開発する際の強力なフレームワークです。その速度、簡潔さ、そしてDjangoの持つ強力な機能との組み合わせは、多くのプロジェクトにおいて大きな利点となるでしょう。このフレームワークを使えば、開発者はより集中してビジネスロジックの実装に注力できるため、より迅速かつ効率的な開発が可能となります。是非一度、Django Ninjaを試してみてください。
終わりに
クロスマートではエンジニアやBizDevなど広く一緒に働く仲間を募集中です。
弊社のプロダクト開発チームはアジャイル開発を取り入れており、「素早く価値を顧客に届ける」をモットーとしております。 下のグラフはプロダクト開発チームのFourKeys*1分析です。高いリリース頻度を維持しています。
今後も、Django Ninjaのような生産性の良い技術を取り入れ、ユーザのためになる機能をどんどんリリースしていこうと考えています。
🥷素早く開発!素早くリリース!素早く改善したい! 🥷 というagilityに満ちたエンジニアさんにはとてもお薦めな会社です。 ぜひ一緒に外食産業のためになるサービスを楽しく開発しましょう!!
*1:Four Keysは、DORA(DevOps Research and Assessment)が6年におよぶ研究を踏まえて提唱した、ソフトウェア開発チームのパフォーマンスを測る4つ(デプロイの頻度、変更のリードタイム、変更失敗率、本番障害の復元にかかる時間)の指標です。