MENU

Django Ninjaチュートリアル④(パスパラメータ)

Django-Ninjaチュートリアル④(パスパラメータ)

今回は前回までのDjango NinjaでのWebAPIの構築に関連した記事になります。

前回までの設定が完了していない場合は、こちらの記事をご覧になってから進めてください。

それでは始めていきます。

目次

パスパラメータの取り扱い

今回は、Django Ninjaにおけるパスパラメータの取り扱いについてみていきます。

今回も公式ドキュメントに従って進めていきます。

パスパラメータの設定

Django Ninjaでは、Pythonのformat-stringsで使用される構文と同じ構文で、パスパラメーターを宣言することができるとされています。

しかもこれは、OpenAPI のパスパラメーターにも一致しているとのことです。

それでは、早速APIを構築していきます。
今回から、別ファイル(api_v2.py)に書いていきます。

新しいAPIの読み込み

from django.contrib import admin
from django.urls import path
from example.api_v1 import app
from example.api_v2 import app_v2 # add

urlpatterns = [
  path('admin/', admin.site.urls),
  path("api/", app.urls),
  path("api_v2/", app_v2.urls), # add
]

api_v2.pyというファイルを作成し、上記のとおり読み込みます。

少し手間ですが、app_v2という名前で設定します。

from ninja import NinjaAPI

app_v2 = NinjaAPI(
  title = "Django Ninja Sample App2",
  version = "1.0.1"
)

# add 1
@app_v2.get("/items/{item_id}")
def get_item(request, item_id):
  return {"item_id": item_id}

今回は上記のように設定しました。

パスパラメーターの値はitem_idであり、URLに記載のitem_idは、引数として関数に渡されます。

この設定を記述して、http://127.0.0.1:8000/api_v2/items/fooにアクセスしてみましょう。

下記のとおり表示されれば成功です。
また、http://127.0.0.1:8000/api_v2/docsにアクセスすることで前回までと同様にOpenAPIの確認ができます。

{"item_id":"foo"}
パスパラメータのdocsイメージ

型を持つパスパラメータ

続いて、標準のPython型アノテーションを使用して、関数内のパスパラメーターの型を宣言する方法をみていきます。

from ninja import NinjaAPI

app_v2 = NinjaAPI(
  title = "Django Ninja Sample App2",
  version = "1.0.1"
)

# add 1(chanege)
@app_v2.get("/items/{item_id}")
def get_item(request, item_id: int):
  return {"item_id": item_id}

この場合、item_idint型であると宣言されてい流溜め、エラーチェックが入ります。

また先ほどと同様にhttp://127.0.0.1:8000/api_v2/items/fooにアクセスしてみると、

{
  "detail": [
    {
      "loc": [
        "path",
        "item_id"
      ],
      "msg": "value is not a valid integer",
      "type": "type_error.integer"
    }
  ]
}

とエラーが返ってきます。

また、http://127.0.0.1:8000/api_v2/docsにアクセスし、items_idfooを入力してexecuteすると、同様の結果になると思います。

fooを入れてexecuteするとerrorが出る

型アノテーションによりバリデーションが働いていることからエラーが出されています。

item_id=3としてexecuteするとどうでしょうか。

item_id=3だとHTTPレスポンスは200

{"item_id": 3}が返ってきますので、設定した型どおりのパスパラメータが渡されていることがわかりました。

このように、パスパラメータとして渡す引数に型定義をすることで、入力内容として受け取る値や引数に渡される値などに型を強制することができます。

また、Django Ninjaでは、下記のようにパスコンバーターを使用して、URLの中で型アノテーションを記述することもできます。

# add 1(chanege)
@app_v2.get("/items/{int: item_id}")
def get_item(request, item_id):
  return {"item_id": item_id}

この場合、item_idの型チェックが入り、int型に一致しない場合、URLは存在しないことになります(int型に一致しない場合、404 Not Foundが返されます)。

複数のパラメータを渡す

Django Ninjaでは、pathに必要な数の変数を渡すことができますが、それぞれの変数には一意の名称を付けることが必要です。
また、その後の関数の中で扱う引数には、先のパスパラメータで設定した名称と同じ名称で引数を使用する必要があります。

これは、複数のパラメータを渡すかどうかに限らず、当たり前のことです。
同じ引数、変数にしないとパスパラメータとして渡す値としては、適切に値が引き継がれないことになりますので、注意してください。

以下に例を示します。

使っている、year、month、dayの変数は、関数内でも同じ名称で使用される必要があります。

# add 2
@app_v2.get("/events/{year}/{month}/{day}")
def events(request, year: int, month: int, day: int):
  return {"date": [year, month, day]}

Schemaの使用

上記の例の場合、複数の変数、引数を扱っていますが、この場合、Schemaを利用して、パラメータをカプセル化することができ、グループ化して、まとめて検証することもできます。

Schemaの設定

まずは以下のようにSchemaの設定をします。

import datetime
from ninja import Schema

# add
class PathDate(Schema):
  year: int
  month: int
  day: int
  
  def value(self):
    return datetime.date(self.year, self.month, self.day)

PathDateというクラスにyearmonthdayの変数の型を定義しました。
そして、その3つの変数をdatetimeモジュールのdatetime.dateを使って、PathDateに定義した3つの変数を使って日付としてまとめています。

次に、このPathDateSchemaを使って、先ほどのGETメソッドを書き換えます。

from ninja import NinjaAPI, Path # add
from example.Schema.api_v2_schema import PathDate # add

app_v2 = NinjaAPI(
  title = "Django Ninja Sample App2",
  version = "1.0.1"
)

〜略〜

# add 2(change)
@app_v2.get("/events/{year}/{month}/{day}")
def events(request, date: PathDate = Path(...)):
  return {"date": date.value()}
  1. 本来であれば、yearmonthdayの3つのパスパラメータを関数の中で定義する必要がありますが、先ほどSchemaの中でPathDateというクラスにまとめています。
  2. したがって、APIではこのPathDatedateという引数に結びつけています。
    なお、Path(...)(...)はpython3から導入されているEllipsis(3点ドットで表されるシングルトンオブジェクト、省略記法)です。
  3. 最後に、dateの中のvalueを返しています。

Ellipsisは、値の指定が必須であることを表現するために使われているようです(Pydantic、FastAPIでそういうことのようなので、Django Ninjaでも同じかと思います。)

この設定で、再度APIを確認します。
下記のように結果が返ってくれば成功です。

書き換え後のAPIの結果

最後に

今回は、Django Ninjaのパスパラメータについてみてきました。

パスパラメータの渡し方やSchemaの定義については、FastAPIと同様の設定かもしれません。
ドキュメントも充実していますので、わかりやすい印象でした。

あえて、日本語で記事にする必要はないのかもしれませんが、自分なりに勉強の一環としてまとめてみました。

次回以降も、Django Ninjaのチュートリアルを進めていきたいと思います。

今回はここまでです。
また次回もよろしくお願いします。

Django-Ninjaチュートリアル④(パスパラメータ)

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

はじめまして、ふじです。
Python、Django、FastAPI、React.js、Next.jsを学習している、ずっと文系のプログラミング独学者です。

目次