https://docs.graphene-python.org/projects/django/en/latest/tutorial-plain/
GraphQL 은 페이스북에서 만든 어플리케이션 레이어 쿼리 언어이다.
파이썬으로 GraphQL API 를 구현하기 위해 다양한 도구를 제공하는 라이브러리.
Graphene 은 코드 우선 접근방식을 사용하고 있다.
REST API 는 여러개의 API Path 로 urls 를 지정하고 요청을 합니다.
ex ) /review/{pk}
https://github.com/graphql/graphql-spec
위의 링크를 참조 해서 읽어보면 이해가 됩니다.
가상환경 셋팅 ...후
pip install django graphene_django
pip list
Package Version
aniso8601 7.0.0
asgiref 3.2.10
certifi 2020.6.20
Django 3.1.1
graphene 2.1.8
graphene-django 2.13.0
graphql-core 2.3.2
graphql-relay 2.0.1
pip 20.2.2
promise 2.3
pytz 2020.1
Rx 1.6.1
setuptools 49.6.0.post20200814
singledispatch 3.4.0.3
six 1.15.0
sqlparse 0.3.1
Unidecode 1.1.1
wheel 0.35.1
django 와 graphene 가 설치되어있는 것을 볼 수 있다.
django-admin startproject graphql_study
django-admin startapp ingredients
python manage.py migrate
이번에는 db 를 적용하지 않고 , 그냥 sqlite 를 사용하기로 했습니다.
from django.db import models
# Create your models here.
class Category(models.Model):
name = models.CharField(max_length = 100)
def __str__(self):
return self.name
class Ingredient(models.Model):
name = models.CharField(max_length = 100)
notes = models.TextField()
category = models.ForeignKey(Category , related_name = "ingredients" , on_delete=models.CASCADE )
def __str__(self):
return self.name
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'ingredients',
]
python manage.py makemigrations
python manage.py migrate
그리고 데이터를 어디서 가져올것입니다.
여기 url 로 들어가서 복사를 하고
mkdir -p ingredients/fixtures
touch ingredients.json
파일을 만드시고 ,
[
{
"model": "ingredients.category",
"pk": 1,
"fields": {
"name": "Dairy"
}
},
{
"model": "ingredients.category",
"pk": 2,
"fields": {
"name": "Meat"
}
},
{
"model": "ingredients.ingredient",
"pk": 1,
"fields": {
"name": "Eggs",
"notes": "Good old eggs",
"category": 1
}
},
{
"model": "ingredients.ingredient",
"pk": 2,
"fields": {
"name": "Milk",
"notes": "Comes from a cow",
"category": 1
}
},
{
"model": "ingredients.ingredient",
"pk": 3,
"fields": {
"name": "Beef",
"notes": "Much like milk, this comes from a cow",
"category": 2
}
},
{
"model": "ingredients.ingredient",
"pk": 4,
"fields": {
"name": "Chicken",
"notes": "Definitely doesn't come from a cow",
"category": 2
}
}
]
붙여넣기를 해줍니다.
python manage.py loaddata ingredients
GraphQL 은 평소에 익숙했던 구조로 표현하기보단
graph 구조로써 객체를 표현하게 됩니다.
Graphene 은 graph 에 표현할 각 객체의 타입을 알 필요가 있습니다.
graph 는 모든 접근을 할수 있는 root type 을 가진다.
각 Django models 에 대한 type 을 GraphQL 에 만들기 위해서는
import graphene_django import DjangoObjectType
을 해야한다.
Query class 안에 필드 타입으로써 list 를 나열해야합니다.
import graphene
from graphene_django import DjangoObjectType
from graphql_study.ingredients.models import Category , Ingredient
class CategoryType(DjangoObjectType):
class Meta:
model = Category
fields = ("id" , "name" , "ingredients")
class IngredientType(DjangoObjectType):
class Meta:
model = Ingredient
fields = ("id" , "name" , "notes" , "category")
class Query(graphene.ObjectType):
all_ingredients = graphene.List(IngredientType)
category_by_name = graphene.Field(CategoryType, name=graphene.String(required = True))
def resolve_all_ingredients(root , info):
return Ingredient.objects.select_related("category").all()
def resolve_category_by_name(root , info , name):
try:
return Category.objects.get(name = name)
except Category.DoesNotExist:
return None
schema = graphene.Schema(query = Query)
settings.py
INSTALLED_APPS = [
...
"graphene_django",
]
그리고 settings.py 에 추가를 해줘야합니다.
GRAPHENE = {
"SCHEMA" : "graphql_study.schema.schema"
}
graphql_study/urls.py
from django.contrib import admin
from django.urls import path
from django.views.decorators.csrf import csrf_exempt
from graphene_django.views import GraphQLView
from graphql_study.schema import schema
urlpatterns = [
path('admin/', admin.site.urls),
path("graphql" , csrf_exempt(GraphQLView.as_view(graphiql=True , schema=schema))),
]
뭔가.. rest api 랑 다를바 없어보인다.
하지만
경로로 들어가게 되면 ,
다르다 .
약간.. postman 같은 느낌이 들었다 .
대박...신기했다.
Graphene 은 Javascript Client 와의 request response 호환성을 높이기 위해 모든 필드 이름을 자동으로 카멜 케이스로 처리가 됩니다.