はじめまして!
colorful bullet の id:blt-horo です!
本記事はDjangoでGraphQLを実装する方法を紹介します。 何項かに分けて投稿していきますので、レベル感に合わせて読み進めてもらえればと思います!
What's GraphQL
GraphQLはFacebookによって開発されたOSSで、Web APIのクエリ言語です
GraphQLは「クエリ言語」と「スキーマ言語」から構成されます
「クエリ言語」
GraphQL APIのリクエストのための言語で、これはさらにデータ取得系のquery、データ更新系のmutation、サーバーサイドからのイベントの通知であるsubscriptionの3種類があります
「スキーマ言語」
GraphQL APIの仕様を記述するための言語で、リクエストされたクエリは、スキーマ言語で記述したスキーマに従ってGraphQL処理系により実行されて、レスポンスを生成します
What's graphene-django
GraphQLのためのPython製フレームワークに graphene があります その中のgraphene-djangoはDjangoプロジェクトにGraphQL機能を簡単に追加できるようにするためのライブラリです docs.graphene-python.org
ここまでで「GraphQL」「graphene-django」とは何かを簡単に紹介しました では、次項から実際に開発に入っていきましょう!
Github
この記事で使用した環境のプロジェクトはこちらです github.com
動作環境
Ubuntu 18.04 LTS Python 3.7.3 Django 2.2 graphene-django 2.3.2
ディレクトリ構造
. ├── myproject │ ├── __init__.py │ ├── schema.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── myapp │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── fixtures │ │ ├── sample.json │ ├── migrations │ │ ├── __init__.py │ ├── models.py │ ├── schema.py │ ├── tests.py │ └── views.py └── manage.py
※仮想環境フォルダ等は省いています
プロジェクトフォルダ作成
$ mkdir myproject $ cd myproject/
Python仮想環境作成
$ python3.7 -m venv [仮想環境名] $ source [仮想環境名]/bin/activate
仮想環境名はお好みで!
※python3.7-venv
のパッケージを入れてない方は適宜インストールしてください
sudo apt-get install python3.7-venv
Djangoインストール
Djangoのインストール方法についてはこちらを参照ください
graphene-djangoインストール
pipでインストールします
$ pip install graphene_django
Djangoプロジェクト作成
$ django-admin startproject myproject .
アプリケーションの作成
サンプルアプリケーションを作成します
$ django-admin startapp myapp
設定の追加
プロジェクトの設定にgraphene_djangoとアプリのパスを追加します
# myproject/settings.py # sample project application INSTALLED_APPS += [ 'graphene_django', # 追加 'myapp', # 追加 ] GRAPHENE = { 'SCHEMA': 'myproject.schema.schema' }
モデルの定義
myproject/myapp/models.py
に次の定義を追加します
# myproject/myapp/models.py from django.db import models from django.utils import timezone class Account(models.Model): id = models.BigAutoField(primary_key=True) name = models.CharField(max_length=255, blank=True, null=True) password = models.CharField(max_length=500, blank=True, null=True) created = models.DateTimeField(blank=True, null=True) def __str__(self): return self.name
マイグレーション
以下を実行し、マイグレーションしておく
$ python manage.py makemigrations $ python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, sessions Running migrations: ~~~ Applying sessions.0001_initial... OK
スキーマの定義
myproject/myapp/schema.py
を作成し、次の定義を追加します
# myproject/myapp/schema.py import graphene from graphene_django.types import DjangoObjectType from myapp.models import Account class AccountType(DjangoObjectType): class Meta: model = Account class Query: account= graphene.Field(AccountType, id=graphene.Int()) all_accounts = graphene.List(AccountType) def resolve_account(self, info, **kwargs): id = kwargs.get('id') if id is not None: return Account.objects.get(pk=id) return None def resolve_all_accounts(self, info, **kwargs): return Account.objects.all()
また、プロジェクトのスキーマを作成し、次の定義を記述します
# myproject/myproject/schema.py import graphene import myapp.schema class Query(myapp.schema.Query, graphene.ObjectType): pass schema = graphene.Schema(query=Query)
エンドポイントの追加
URLを設定する
# myproject/myproject/urls.py from django.conf.urls import include, url from django.contrib import admin from graphene_django.views import GraphQLView from myproject.schema import schema urlpatterns = [ url(r'^graphql/', GraphQLView.as_view(graphiql=True, schema=schema)), # エンドポイント url(r'^admin/', admin.site.urls), ]
url(r'^graphql/'
のように記述するとhttp://localhost:8000/graphql/
がAPIへのリクエストを受け付けるURLとなります
また、graphiql=True
とするとこのIDEであるGraphiQLの画面にアクセスすることができます
データの読み込み
サンプルデータを読み込むために以下のJSONファイルを作成します
# myproject/myapp/fixtures/sample.json [{ "model": "myapp.Account", "pk": 1, "fields": { "name": "apple", "password": "apple-pass" } }, { "model": "myapp.Account", "pk": 2, "fields": { "name": "banana", "password": "banana-pass" } }, { "model": "myapp.Account", "pk": 3, "fields": { "name": "orange", "password": "orange-pass" } }]
下記コマンドでデータの読み込みをします $ python manage.py loaddata sample
Installed 3 object(s) from 1 fixture(s)
起動
$ python manage.py runsever Watching for file changes with StatReloader Performing system checks... System check identified no issues (0 silenced). July 29, 2019 - 05:33:21 Django version 2.2.3, using settings 'myproject.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C.
起動が成功したら、http://127.0.0.1:8000/graphql/にアクセスしましょう
上記のようにGraphiqlにアクセスできると思います
GraphQLを書こう
GraphQLはクエリと結果として取得できるデータの構造が似ていることが特徴です さっそくクエリを書いてみましょう
Graphiqlの左側のペインに以下のクエリを入力します
query { account(id:1){ id name password } }
id = 1のデータを取得しています さっそく実行ボタンを押してみましょう すると以下の結果が返ってきます
{ "data": { "account": { "id": "1", "name": "apple", "password": "apple-pass" } } }
次にデータ全体を取得するクエリを入力します
query { allAccounts{ id name password } }
同じく実行ボタンを押すと、取得結果は以下となります
{ "data": { "allAccounts": [ { "id": "1", "name": "apple", "password": "apple-pass" }, { "id": "2", "name": "banana", "password": "banana-pass" }, { "id": "3", "name": "orange", "password": "orange-pass" } ] } }
上記でも述べたように、クエリと結果の構造がとても似ています クエリの学習コストが小さくなるので便利ですね
終わりに
ここまででDjangoでGraphQLが使え、データ取得系のqueryも書けるようになりました
次回はデータ更新系のmutationを書いていきたいと思います
最後まで読んでいただきありがとうございました!
id:blt-horo さんの紹介記事