iimon TECH BLOG

iimonエンジニアが得られた経験や知識を共有して世の中をイイモンにしていくためのブログです

DRFを使用して簡単なAPIを実装する

初めに


初めまして!

株式会社iimonでエンジニアをしている遠藤です。

今回はDjango及びDRFAPIを生成する流れを理解するために、図書館の本を管理する簡単なAPIを実装できればと思います。

DRFとは


DRF(Django REST Framework)は、DjangoでRESTful APIを作成するための、サードパーティ製のDjangoのパッケージです。

そもそもRESTful APIとは、RESTの原則に沿ったAPIのことを言います。

RESTの原則とは主に

  1. アドレス可能性(Addressability)
    1. 全ての情報はURIで表現されるユニークなアドレスを持っている。
  2. ステートレス性(Stateless)
    1. HTTPメッセージの全てがリクエストを理解するための必要な情報を含んでいるため、サーバーにセッション等の状態を持たない前提で情報のやり取りを行う。
  3. 接続性(Connectability)
    1. リソースを様々な形式(HTML、XMLJSON、バイナリ)で表現できるようにする。
    2. 情報の内部に、リンクとして別の情報や状態を含めることができる
  4. 統一インターフェース(Uniform Interface)
    1. 情報の操作に、HTTPメソッド(GET, POST, PUT, DELETE等)を利用する

の4原則からなります。

RESTful APIを用いることで、バックエンドとフロントエンドとを分離することができる点が利点です。

DjangoでRESTful APIバックエンドを構築するには、自前で色々と実装する必要があるので、今回はDRFを使用していきます。

Webアプリケーションのベースとなる部分にはDjangoREST APIに特化した機能にはDRFを利用するといった使い方をします。

導入


インストール

今回は仮想環境を用いるので、先にプロジェクトとなるディレクトリを用意しておきます。

$ mkdir drf-sample

特定のプロジェクトで必要なライブラリだけを管理するために、仮想環境を作成します。 今回はvenvを用いて仮想環境を用意していきます。

pythonが入っていない場合は、まずpythonをインストールします。 https://qiita.com/koooooo/items/b21d87ffe2b56d0c589b

以下のコマンドを実行します。

$ python -m venv drf-sample

こうすることで、drf-sampleディレクトリを仮想化することができます。

drf-sampleディレクトリに移動して、ファイルが生成されていることが確認できればOKです。

$ cd drf-sample

$ls
bin      include      lib     pyvenv.cfg

仮想環境を有効化します。

$ source bin/activate

DjangoDRFをインストールしていきます。

$ pip install Django==4.2
$ pip install djangorestframework==3.14.0

プロジェクトを作成

drf-sampleディレクトリで以下のコマンドを実行しましょう!

$ django-admin startproject config .

そうすると、drf-sampleがプロジェクト化され、config という名前のフォルダとmanage.pyというファイルができていると思います。

drf-sampleディレクトリで以下のコマンドを実行して、開発用サーバーを起動させます。

$ python manage.py runserver

ブラウザでhttp://localhost:8000/にアクセスして確認してみましょう。

以下のような画面が見れたらOKです!

これで、APIを実装する準備が完了しました! 早速APIを作成していきましょう!

図書館の本を管理するAPI


libraryというアプリケーションを作成し、図書館にある本の貸出可能状況を管理するための、簡単なAPIを作成していきます。今回は本のタイトルと貸出可否のみを管理する簡易的な設計にします。

  1. アプリケーションの作成

    今回はlibraryという名前のアプリケーションとapiv1という名前のアプリケーションを作成していきます。

    以下のコマンドを実行します。

     $  python manage.py startapp library
     $  python manage.py startapp apiv1
    
  2. 設定ファイルの修正

    アプリケーションが作成できたら、config/settings.pyに、インストールしたDRFと、作成したアプリケーションを追加します。

     ...
    
     INSTALLED_APPS = [
         ...
         "django.contrib.staticfiles",
             "rest_framework", # 追加
             "apiv1", # 追加
             "library" # 追加
     ]
     ...
    

    次に、言語コードタイムゾーンを修正します。

     ...
    
     # 言語コードを修正
     LANGUAGE_CODE = "ja" # 修正
     # タイムゾーンを修正
     TIME_ZONE = "Asia/Tokyo" # 修正
    
     ...
    

    今回は認証にDRFcookie認証を使用するため、設定していきます。

     REST_FRAMEWORK = {
         "DEFAULT_AUTJENTICATION_CLASS": [
             "rest_framework.authentication.SessionAuthentication",
         ],
     }
    
  3. モデルの作成

    では、いよいよ本データを管理するためのモデルを作成していきましょう!

     from django.db import models
    
     # Create your models here.
    
     class Book(models.Model):
         """本モデル"""
         title = models.CharField(verbose_name="タイトル", max_length=20)
         available = models.BooleanField(verbose_name="貸出可", default=True)
         created_at = models.DateTimeField(verbose_name="登録日", auto_now=True)
    
             # DjangoAdminでデータを表示するために設定されてたりする
         def __str__(self):
             return self.title
    

    データベースのマイグレーションを実行します。

     $ python manage.py makemigrations library
     $ python manage.py migrate
    

    ちなみに、Django Adminから作成したモデルのデータにアクセスしたい場合には、admin.pyを以下のように修正します。

     from django.contrib import admin
     from .models import Book
    
     class BookAdmin(admin.ModelAdmin):
         list_display = ("title", "available", "created_at")
         readonly_fields = ("created_at",)
    
     admin.site.register(Book, BookAdmin)
    
  4. RESTful APIバックエンドを作成

    apiv1アプリケーションに追加していきます。

    まず、serializerファイルを作成します。

     from rest_framework import serializers
     from library.models import Book
    
     class BookSerializer(serializers.ModelSerializer):
         class Meta:
             model = Book
             fields = ["title", "available"]
    

    serializerはデータを変換するためのクラスで、主に以下の2つの役割があります。

    1. 入力データとオブジェクトの相互変換
    2. 入力データのバリデーション

次に、viewファイルを修正します。

from rest_framework.viewsets import ModelViewSet
from rest_framework.permissions import IsAuthenticated
from library.models import Book
from .serializers import BookSerializer

class BookViewSet(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
        # 権限のあるユーザー以外のアクセスを拒否する
    permission_classes = [IsAuthenticated]

DjangoはMVTモデルで、DjangoのViewはMVCモデルでいうControllerに該当します。

DRFのviewも基本的には同じです。JSON形式のリクエストオブジェクトを受け取り、JSON形式のレスポンスオブジェクトを作成する役割を担っています。

  1. ルーティング設定

    いよいよ最後の工程です!

    APIのエンドポイントを追加して、URLにアクセスできるようにしましょう。

    今回は以下のURLパターンを用意します。

    HTTPメソッド URL 処理
    GET, POST /auth/login ログイン
    GET, POST /auth/logout ログアウト
    GET, POST /books 本の情報の取得、登録
    PATCH /books// 本の情報の更新

    まず、config/urls.pyにpathを追加します。

     from django.contrib import admin
     from django.urls import path, include # 追加
    
     urlpatterns = [
         path("admin/", admin.site.urls),
             path("auth/", include("rest_framework.urls")),# 追加
             # apiv1/urls.pyを読む
         path("", include("apiv1.urls")), # 追加
     ]
    

    apiv1アプリケーションにもurls.pyを作成します。

     from django.urls import path, include
     from rest_framework import routers
     from . import views
    
     router = routers.DefaultRouter()
     router.register("books", views.BookViewSet)
    
     app_name = "apiv1"
     urlpatterns = [
         path("", include(router.urls))
     ]
    

動作確認


まず、ログインに必要なユーザーを作成します!

$ python manage.py createsuperuser

上記のコマンドを設定すると、ユーザー名、メールアドレス、パスワードの設定が求められるので、入力します。

最終的に、

Superuser created successfully.

と表示されればOKです。

ユーザーが設定できたら、まずhttp://localhost:8000にアクセスしてみましょう。

以下のような画面が表示されると思います。

apiv1/views.pypermission_classesを設定しているので、ログインしていない状態でhttp://localhost:8000/books/ にアクセスすると403エラーになると思います。

そこで、右上のLog inボタンを押し、先ほど作成したユーザーでログインします。

そうすると、GETとPOSTのAPIが叩けるようになったかと思います!

また、Django Adminにアクセスする場合は、http://localhost:8000/admin/にアクセスし、同様に先ほど作成したユーザーでログインします。

以上が確認できれば完了です。

今回は簡単な設計しかしていないので、ぜひ公式ドキュメントなども読んでみてください!

参考:

https://docs.djangoproject.com/ja/4.2/intro/tutorial01/

https://qiita.com/koooooo/items/b21d87ffe2b56d0c589b

https://www.amazon.co.jp/現場で使える-Django-Framework-(Django-の教科書シリーズ)-ebook/dp/B07XWL8FPM

https://www.manajob.jp/python/python-app/venv

https://qiita.com/NagaokaKenichi/items/0647c30ef596cedf4bf2

https://www.infraexpert.com/study/sdn09.html