tkherox blog

データサイエンスおよびソフトウェア開発、たまに育児についての話を書いています

Django Rest FrameworkでAPIをサクッと作ってみた

Django Rest Framworkとは

Pythonのwebフレームワークと言えばDjangoがメジャーですよね.
Flask等の軽量フレームワークなどもありますが,世の中で一般的に必要とされる機能を実装しようとするとやはり機能不足を感じます.その点.Djangoは一通り必要な機能は備えており,迷ったらDjangoを利用すれば良いと思います.
そして,DjangoをベースとしてRESTfulなAPIを作成する場合に利用するのがDjango Rest Frameworkというライブラリです.今回はDjango Rest Frameworkを使ってAPIを作成してみましょう.

www.django-rest-framework.org

Django Rest Frameworkの仕組み

一般的なWebフレームワークと同様にMVCモデル(DjangoではModel-Template-Viewモデル)に従った考え方をベースとしてアーキテクチャは構成されております.そして,Django Rest FrameworkはTemplateの部分をSerializerに置き換えたものと考えておくと理解が早いと思います.

ClientがリクエストするとURL Resolverによってアクセスされた情報と一致するViewへルーティングを行いView内で定義した各種処理を行います.RESTfulであるということはURLとリソースが1対1で対応している設計思想に従うというになりますが,実装では必ずしもModelを経由して利用しなければいけない訳ではないので上記のアーキテクチャとは限りません.

インストール

では,早速インストールから環境の構築まで行なっていきましょう. 今回の環境は以下になります.

Python環境がインストールはされている前提でpipを使ってインストールします.

$ pip install django django-restframework

これだけでインストールは完了です.非常に簡単ですね.
プロジェクトの作成方法はDjango側が担っているのでDjangoで普段の要領でプロジェクトを開始する際のコマンドを実行していきます.

$ django-admin startproject rest_sample
$ cd rest_sample/

次に今回のAPIとなるアプリを作成していきます.アプリ名は適当にpostとしていますが,ご自身の環境に合わせて適宜変更してください.

python manage.py startapp post

これまでのコマンドが正常に終了していれば以下のようなディレクトリ構成でファイルが生成されていると思います.

root/
  ├─ manage.py
  ├─ rest_sample
  │   ├── __init__.py
  │   ├── settings.py
  │   ├── urls.py
  │   └── wsgi.py
  └─ post
      ├── __init__.py
      ├── admin.py
      ├── apps.py
      ├── migrations
      ├── models.py
      ├── tests.py
      ├── urls.py
      └── views.py

これで準備は終わりですので本題の実装の方へ移っていきましょう.

実装方法

ここからが本題のDjango Rest Framework側の実装になります. まずは rest_sample/settings.py でrest frameworkと作成したアプリの設定を行います.

INSTALLED_APPS = (
    ...
    'rest_framework',
    'post',    
)

次にモデルの定義をpost/models.pyに適用します. シンプルに投稿する内容のタイトルや内容を記録するカラムと作成日時等の付随する情報を定義しました.

class Post(models.Model):
    title      = models.CharField(max_length=255)
    category   = models.IntegerField()
    context    = models.TextField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

そして,定義したモデルをデータベースに反映させるためにマイグレーションを実行します.デフォルトではsqlite3のデータベースに設定されているためそのまま利用します.

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

続いて入力されたパラメータとシリアライズする処理を記述していきます. Railsでいう所のハイパーパラメータと認識してもらうと理解が早いかと思います(実際には異なりますが).新しくpost/serializer.pyというファイルを作成してその内に処理を記述していきます.

from rest_framework import serializers

class PostSerializer(serializers.ModelSerializer):

    class Meta:
        model = Post
        verbose_name = '投稿'
        verbose_name_plural = '投稿一覧'
        fields = ('id' 'title', 'category', 'context', 'created_at', 'updated_at')

viewにはコントローラーとなる処理を記述していきます.
viewにはいくつかのクラスがあるのですが,今回はModelViewSetクラスを用います.ModelViewSetクラスはGenericViewSetクラスを継承したクラスでmodelのCRUD操作がViewSetのアクションとして暗黙的に実装されるため,コードを簡易的に記述することができます.これだけでCURDの処理が記述できてしまうのには驚きですね.

from from rest_framework import viewsets
from .models import Post
from .serializer import PostSerializer

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

最後にルーティングの記述をしていきます.
djangoのurlの設定とほとんど要領で設定できます.rest_sample/urls.pyに以下の内容を記述します.

from django.conf.urls import url, include
from django.contrib import admin

from post.urls import router

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^api/v1/', include(router.urls)),
]

import先のpost/urls.pyDjango Rest Frameworkのルーターの設定を記述したら完了です.

from rest_framework import routers
from .views import PostViewSet

router = routers.DefaultRouter()
router.register(r'posts', PostViewSet)

ここまで設定すればリクエストされたURLに応じてviewで定義したメソッドにルーティング処理が行われるようになりました.
これで作業は完了です.

APIサーバの実行

サーバの起動方法はDjangoの起動方法と同じです. ターミナル上で以下のコマンドを実行して見ましょう.

$ python manage.py runserver

サーバが起動できたら別のターミナルを開いてcurlコマンドでレスポンスを確認してみます. 初めはリソースがないためGETをリクエストしても何も面白くはないので,POSTメソッドでデータベースに新しいリソースを登録することを試みてみましょう.

$ curl -X POST -d "title=sample&category=4&context=message" http://localhost:8000/api/v1/post
{
    "id": 1,
    "title": "sample",
    "category": 4,
    "context": "message",
    "created_at": "2020-3-15T21:23:12.54213Z",
    "updated_at": "2020-3-15T21:23:12.54213Z"
}

ちゃんと動作していそうですね.
このようにDjango Rest Frameworkを用いることで簡単にAPIを作ることができます.APIを自作できるようになると他のサービスに作成した機能を組み込むことができるので開発効率の向上にも繋がりますね.

まとめ

今回は非常に簡単なCRUDの機能をDjango Rest Frameworkで実装する方法をご紹介いたしました.API機能を非常に簡単に実装できるため是非みなさんも使ってみてください.また,API認証の機能なども提供しており,サードパティ製のライブラリと組み合わせればOAuth認証なども実現できます. 今後は少し実際の利用に即した機能をご紹介して行ければと思います.