GraphQL - Graphene: 1

Jihun Kim·2022년 4월 24일
0

GraphQL

목록 보기
8/16
post-thumbnail

이 글은 Grapehene Docs를 읽고 정리한 것입니다(조금 더 정확히는 graphene-django).


Graphene

Graphene은 파이썬에서 code-first approach를 통해 GraphQL API를 구현하는 데 사용하는 라이브러리이다.

Code-First approach란?

  • Code-First approach에서는 사용하고 있는 application의 도메인에 집중하여 도메인 엔티티에 맞는 클래스를 생성한다.
  • 이와 반대 되는 개념은 데이터베이스를 먼저 생성한 다음 데이터베이스 디자인에 맞는 클래스를 생성하는 것이다.

Graphene-django

  • django project에 쿼리를 생성하기 위해서는 다음의 두 가지가 필요하다.

    	1. Object types가 정의된 스키마
    	2. 쿼리를 input으로 받고 그 결과를 반환하는 view
  • GraphQL은 graph 구조를 사용하기 때문에 Graphene은 그래프에 나타나게 될 각 객체의 타입을 알아야 한다.

  • 또한, 그래프는 모든 접근의 시작점(진입점)이 될 root type도 알아야 한다.
    - 이 진입점은 Query 클래스를 정의하면 된다.


Installation

라이브러리 다운로드

$ pip install graphene-django

graphene_django 추가

# settings.py

INSTALLED_APPS = [
    ...
    "graphene_django"
]

graphql URL 추가

# urls.py

'''
for Django 2.0 and above
'''

from django.urls import path
from graphene_django.views import GraphQLView

urlpatterns = [
    # ...
    path("graphql", GraphQLView.as_view(graphiql=True)),
]

GraphiQL이란?
위의 urlpatterns에서 확인할 수 있듯이 graphiql=True로 설정 되어 있다. 그런데 GraphiQl은 무엇일까?

  • GraphiQL은 GraphQL IDE이다.
  • http://localhost:8000/___graphql로 접근할 수 있다.

schema의 위치 명시

# settings.py

GRAPHENE = {
    "SCHEMA": "django_root.schema.schema"
}

Schema & Object Types

모델

# cookbook/ingredients/models.py
from django.db import models

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
  • 장고 모델 각각에 대한 GraphQL 타입을 생성하려면 DjangoObjectType을 상속 받은 타입 클래스를 만들어야 한다.
    - DjangoObjectType: 장고 모델의 필드에 대응하는 GraphQL 필드를 자동으로 정의한다.

    # cookbook/schema.py
    import graphene
    from graphene_django import DjangoObjectType
    
    from cookbook.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")
    
  • 그 다음, 위에서 생성한 타입들을 Query 클래스에 나열하면 된다.
    - schema.py는 top-level의 urls.py와 같은 개념이다.

  # cookbook/schema.py
  import graphene
  from graphene_django import DjangoObjectType

  ...(위에서 정의한 Type들)...

  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):
          # We can easily optimize query count in the resolve method
          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)

직접 쿼리해 테스트 해 보면 알 수 있지만, Graphene은 js와의 호환을 위해 snakecase로 작성된 모든 필드명을 자동으로 camelcase로 변환한다.

profile
쿄쿄

0개의 댓글