Notice
Recent Posts
Recent Comments
Link
«   2025/09   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Tags more
Archives
Today
Total
관리 메뉴

최용우

Django에서 Graphql을 사용해보자 본문

장고

Django에서 Graphql을 사용해보자

용우쨩 2024. 10. 12. 22:57

Rest API의 창궐

나는 지금 작업하고 설문조사 프로젝트에서 Django를 사용하여 백엔드 서버를 만들고 있다.

Django는 내가 가장 좋아하는 파이썬 백엔드 프레임워크이고 지금까지는 주로 DRF(Django Rest Framework)와 결합하여 Rest API를 주로 제공해왔다.

<Rest API>

이 방식은 현재까지도 많은 사람들이 좋아하는 방식이고 그렇게 사용하고 있다.

그러나 한 5년전이었나 Facebook(현 Meta)에서 GraphQL이라는 새로운 API 개념을 만들었고 이는 프론트와 백엔드 개발 환경을 매우 다른 양상으로 바꾸었다. 그런데 어떻게 바꾸었냐고?

GraphQL이란? (Graph Query Language)

핵심은 간단하다. "내가 원하는 정보만 받아서 쓰자." 이것이 가능하다면 백엔드 입장에서는 중구난방 만들어진 중복된 엔드포인트가 사라지며 프론트 입장에서는 효율적으로 데이터를 받아올 수 있다. 매우 좋은 것이다. 반대로 쿼리를 처리하기 때문에 서버에 연산 부담을 줄 수 있고 캐싱이 어렵다는 단점도 있다. 아래는 Graphql의 주요 특징이다.

  1. 단일 엔드포인트: 모든 요청은 하나의 엔드포인트를 통해 처리됩니다.
  2. 명시적 쿼리: 클라이언트가 필요한 필드를 명시할 수 있습니다.
  3. 타입 시스템: GraphQL은 엄격한 타입 시스템을 통해 스키마를 정의하고, 이를 기반으로 쿼리와 응답의 타입을 보장합니다.

Graphene이란?

Django에서 GraphQL을 구현하기 위한 라이브러리다. Graphene은 Pythonic한 방식으로 GraphQL 스키마, 쿼리, 뮤테이션 등을 정의할 수 있으며, Django 모델과의 통합을 도와준다. 한마디로 Wrapper인 셈. DRF에 익숙하다면 몇번 사용만으로 감을 익힐 수 있다.

공식문서에도 설명이 잘 나오니 확인하면 좋다.

 

Django-Graphene 예제

# models.py 모델만들기
from django.db import models

class User(models.Model):
    username = models.CharField(max_length=100)
    email = models.EmailField()

    def __str__(self):
        return self.username

class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    author = models.ForeignKey(User, related_name='posts', on_delete=models.CASCADE)

    def __str__(self):
        return self.title

 

 

# schema.py GraphQL 스키마 정의
import graphene
from graphene_django.types import DjangoObjectType
from .models import User, Post

# Django 모델을 위한 GraphQL 타입 정의
class UserType(DjangoObjectType):
    class Meta:
        model = User

class PostType(DjangoObjectType):
    class Meta:
        model = Post

# 쿼리 정의
class Query(graphene.ObjectType):
    all_users = graphene.List(UserType)
    all_posts = graphene.List(PostType)
    post_by_title = graphene.Field(PostType, title=graphene.String(required=True))

    def resolve_all_users(root, info):
        return User.objects.all()

    def resolve_all_posts(root, info):
        return Post.objects.all()

    def resolve_post_by_title(root, info, title):
        try:
            return Post.objects.get(title=title)
        except Post.DoesNotExist:
            return None

# 스키마 정의
schema = graphene.Schema(query=Query)

 

# urls.py
from django.contrib import admin
from django.urls import path
from graphene_django.views import GraphQLView
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    # GraphQL 뷰 경로 설정
    path('graphql/', csrf_exempt(GraphQLView.as_view(graphiql=True))),
]

 

이 세 파일을 작성했다면 이제 쿼리를 작성해보자!

# 모든 게시글과 사용자 조회
{
  allPosts {
    title
    content
    author {
      username
    }
  }
  allUsers {
    username
    email
  }
}

 

이렇게 요청한다면 서버에서 모든 게시글과 모든 사용자에 대한 정보를 Json으로 반환한다.

 

GraphQL 장점

1. 데이터 페칭의 유연성 증가

  • REST: 기존 REST API에서는 각 리소스마다 고유한 엔드포인트를 제공하며, 필요한 데이터를 여러 엔드포인트에 걸쳐 여러 번 요청해야 했지만 이는 과도한 네트워크 요청(over-fetching)이나 불필요한 데이터 전달(under-fetching)을 야기한다.
  • GraphQL: GraphQL은 단일 엔드포인트에서 모든 데이터 요청을 처리할 수 있다. 클라이언트는 필요한 데이터의 구조를 자유롭게 정의할 수 있어, 더 적은 요청으로 더 유연한 데이터 페칭이 가능하다. 불필요한 데이터를 받아오거나 여러 엔드포인트를 거치는 비효율이 해소된것이 특징이다.

2. 강력한 타입 시스템

  • REST: REST는 주로 URL과 HTTP 메서드를 통해 자원을 관리하며, 서버에서 전달하는 데이터 형식에 대한 명확한 스키마 정의가 없는 경우가 많다. 클라이언트와 서버 간 데이터 형식이 맞지 않을 때 문제가 발생할 수 있다.
  • GraphQL: GraphQL은 스키마 기반의 API로, 엄격한 타입 시스템을 사용한다. 스키마에서 정의한 타입을 기반으로 데이터의 구조를 강력하게 보장하며, 개발자가 쿼리의 유효성을 사전에 확인할 수 있어 오류를 방지한다.

3. 단일 엔드포인트

  • REST: REST API는 리소스마다 별도의 엔드포인트를 가지는데 특정한 데이터를 가져오기 위해서는 여러 엔드포인트를 호출해야 한다.
  • GraphQL: GraphQL은 모든 데이터를 하나의 엔드포인트를 통해 처리한다. 클라이언트는 하나의 쿼리로 여러 리소스의 데이터를 동시에 요청할 수 있어, 여러 요청을 관리할 필요가 없다.

4. 클라이언트 주도 데이터 구조

  • REST: REST API에서는 서버가 응답 데이터의 구조를 결정한다. 클라이언트는 서버가 반환하는 모든 데이터를 받아야 하며, 불필요한 필드도 함께 받아와야 하는 문제가 있다.
  • GraphQL: GraphQL에서는 클라이언트가 필요한 필드를 지정할 수 있다. 필요한 데이터만을 선택적으로 받아올 수 있는데 이를 통해 클라이언트 주도적인 데이터 구조 설계가 가능해진다.

GraphQL vs Rest API

무엇보다 내가 어떤 어플리케이션을 개발하느냐가 중요하다. 목적에 맞게 가장 알맞은 방법을 사용하는게 미덕이다. 정답에 가까운 방법이 있을뿐 정답은 없다.