django-graphql[basic]

BackEnd_Ash.log·2020년 9월 27일
1

https://docs.graphene-python.org/projects/django/en/latest/tutorial-plain/

Graphene

GraphQL 은 페이스북에서 만든 어플리케이션 레이어 쿼리 언어이다.

파이썬으로 GraphQL API 를 구현하기 위해 다양한 도구를 제공하는 라이브러리.
Graphene 은 코드 우선 접근방식을 사용하고 있다.

GraphQL API VS REST API

  • REST API

REST API 는 여러개의 API Path 로 urls 를 지정하고 요청을 합니다.

ex ) /review/{pk}

  • GraphQL API
    GraphQL API 는 별도로 Path 를 만들지 않습니다.
    하나의 path 로 여러개의 자원을 한번에 조회합니다.

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

djangographene 가 설치되어있는 것을 볼 수 있다.

django 설치

django-admin startproject graphql_study
django-admin startapp ingredients
python manage.py migrate

이번에는 db 를 적용하지 않고 , 그냥 sqlite 를 사용하기로 했습니다.

models.py

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

settings.py

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

그리고 데이터를 어디서 가져올것입니다.

https://raw.githubusercontent.com/graphql-python/graphene-django/master/examples/cookbook/cookbook/ingredients/fixtures/ingredients.json

여기 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

Object Types

django 프로젝트에 쿼리를 작성하려면 필요한 몇가지가 있습니다.

  • 객체 타입 정의가 된 스키마
  • 한 view 에서 input 으로 queries 를 받고 결과를 return

GraphQL 은 평소에 익숙했던 구조로 표현하기보단
graph 구조로써 객체를 표현하게 됩니다.

  1. Graphene 은 graph 에 표현할 각 객체의 타입을 알 필요가 있습니다.

  2. graph 는 모든 접근을 할수 있는 root type 을 가진다.

  3. 각 Django models 에 대한 type 을 GraphQL 에 만들기 위해서는
    import graphene_django import DjangoObjectType
    을 해야한다.

  4. 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))),
]

python manage.py runserver

뭔가.. rest api 랑 다를바 없어보인다.

하지만

http://localhost:8000/graphql

경로로 들어가게 되면 ,
다르다 .

약간.. postman 같은 느낌이 들었다 .

대박...신기했다.

Graphene 은 Javascript Client 와의 request response 호환성을 높이기 위해 모든 필드 이름을 자동으로 카멜 케이스로 처리가 됩니다.

profile
꾸준함이란 ... ?

0개의 댓글