はじめまして!
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 さんの紹介記事


