Django資産を活用できる!Django Ninjaのススメ

こんにちは。クロスマートで請求書を始めとした帳票サービスの開発を行っているDev2 テックリードのたけじい(@pouhiroshi)です。

先月は pytestを並列実行してCIを倍速にした話 - クロスマート Tech Blog と言う記事を寄稿させていただきました。 まだご覧になってない方はぜひそちらも読んでみてください。

Django上でREST APIを快適に開発する「Django Ninja」

DjangoPythonで最も人気のあるウェブフレームワークの一つです。その柔軟性と強力な機能により、多くの開発者に選ばれています。しかし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にインスパイアされたこのフレームワークは、非同期プログラミングもサポートしており、大規模なアプリケーションでも高性能を維持することができます。

django-ninja.dev

github.com

すでに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パターンがあればここに追加します。
]

コードの解説

  1. Userクラスの定義: UserクラスはSchemaを継承しており、これによりユーザーのデータ構造を定義しています。ここではnameageという2つのフィールドが含まれています。任意項目の場合はOptionalフィールドとして宣言し、デフォルト値を定義します。

  2. GETリクエスト (api/usersエンドポイント): このエンドポイントは登録されている全ユーザーのリストを返します。実際のアプリケーションでは、このデータはデータベースから取得されることが一般的ですが、これはサンプルのためリストを代わりに使用しています。もちろん従来通り、DjangoORMを利用してデータベースからデータを取得することも可能です。

  3. 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仕様書の自動生成もされます。

https://eadwincode.github.io/django-ninja-extra/images/ui_swagger_preview_readme.gif

おまけ(DjangoNinjaExtra)

Django Ninjaだけでも嬉しい機能はかなり揃っているのですが、それに加え、積極的な機能拡充が「Django Ninja Extra」というAddOnの形で提供され、こちらも活発に開発が進められているようです。

eadwincode.github.io

Django Ninja Extraは、Django Ninjaの機能を拡張するフレームワークで、特にクラスベースでAPIを設計するための追加機能が提供されています。以下に、その主要な特徴をまとめます。

  • クラスベースの設計: APIをクラスベースの方式で設計することができます。(先程のルーター定義をControllerクラスに実装するようになります)これにより、オブジェクト指向の設計原則をAPI開発に適用しやすくなります。
  • 権限管理: ルートレベルまたはコントローラーレベルで定義された権限や認証を使用して、エンドポイントを簡単に保護することができます。これにより、セキュリティが強化され、アクセス管理が容易になります。
  • 依存性注入: コントローラークラスは、PythonInjectordjango_injectorを用いた依存性注入をサポートしています。これにより、APIControllerクラスにAPIに依存するサービスを注入し、必要な場所で利用することが可能になります。

これらの機能により、Django Ninja Extraは、より柔軟かつ効率的なAPI開発を可能にします。 Django Ninja Extraにもぜひ注目してみてください。

まとめ

Django Ninjaは、DjangoREST APIを開発する際の強力なフレームワークです。その速度、簡潔さ、そしてDjangoの持つ強力な機能との組み合わせは、多くのプロジェクトにおいて大きな利点となるでしょう。このフレームワークを使えば、開発者はより集中してビジネスロジックの実装に注力できるため、より迅速かつ効率的な開発が可能となります。是非一度、Django Ninjaを試してみてください。

終わりに

クロスマートではエンジニアやBizDevなど広く一緒に働く仲間を募集中です。

弊社のプロダクト開発チームはアジャイル開発を取り入れており、「素早く価値を顧客に届ける」をモットーとしております。 下のグラフはプロダクト開発チームのFourKeys*1分析です。高いリリース頻度を維持しています。

一日平均3件を超えるリリースを行なっています!

今後も、Django Ninjaのような生産性の良い技術を取り入れ、ユーザのためになる機能をどんどんリリースしていこうと考えています。

🥷素早く開発!素早くリリース!素早く改善したい! 🥷 というagilityに満ちたエンジニアさんにはとてもお薦めな会社です。 ぜひ一緒に外食産業のためになるサービスを楽しく開発しましょう!!

xorder.notion.site

*1:Four Keysは、DORA(DevOps Research and Assessment)が6年におよぶ研究を踏まえて提唱した、ソフトウェア開発チームのパフォーマンスを測る4つ(デプロイの頻度、変更のリードタイム、変更失敗率、本番障害の復元にかかる時間)の指標です。