인턴

GraphQL 알아보기

imsmile2000 2024. 1. 18. 17:44

GraphQL이란?

페이스북에서 만든 쿼리 언어로 SQL과 비슷하지만 언어적 구조 차이가 매우 크다

 

 

GraphQL과 SQL의 차이점

GraphQL SQL
웹 클라이언트가 데이터를 서버로부터 가져오는 것이 목적 데이터베이스 시스템에 저장된 데이터를 가져오는 것이 목적
클라이언트 시스템에서 작성하고 호출 백엔드 시스템에서 작성하고 호출

 

# SQL 쿼리 예시
SELECT plot_id, species_id, sex, weight, ROUND(weight / 1000.0, 2) FROM surveys

# Gql 쿼리 예시
{
	hero{
    	name
        friend{
        	name
        }
    }
}

 

GraphQL 파이프라인

 

 

 

 

GraphQL의 구조

Query / Mutation

GraphQL에는 '쿼리 변수'라는 개념이 있어 gql을 구현한 클라이언트에서는 이 '쿼리 변수'에 프로그래밍으로 값을 할당할 수 있는 함수 인터페이스가 존재한다.

query getStudentInfo($studentId: ID){
	personalInfo(studentId: $studentId){
    	name
        address1
        address2
        major
    }
   	
    classInfo(year: 2018, studentId: $studentId){
    	classCode
        className
        teacher{
        	name
            major
        }
        classRoom{
        	id
            maintainer{
            	name
            }
        }
    }
    SATInfo(schoolCode: 0412, studentId: $studentId){
    	totalScore
        dueDate
    }
}

 

 

schema/type

type Character{ //오브젝트 타입: Character
	name: String! 
    appearsIn: [Episode!]! //!(느낌표)는 필수값을 의미, 대괄호는 배열을 의미
    //필드: name, appearsIn
}
//스칼라 타입: String, ID, int 등

 

 

resolver

  • gql 쿼리문 파싱은 대부분 gql 라이브러리에서 처리한다.
  • gql 쿼리에서는 각각의 필드마다 함수가 하나씩 존재한다. 각각의 필드의 데이터를 반환하는 함수가 리졸버다.
  • 리졸버 함수는 총 4개의 인자를 받는다
  Query: {
    paymentsByUser: async (parent, { userId }, context, info) => {
        const limit = await Limit.findOne({ where: { UserId: userId } })
        const payments = await Payment.findAll({ where: { LimitId: limit.id } })
        return payments        
    },  
  },
  Payment: {
    limit: async (payment, args, context, info) => {
      return await Limit.findOne({ where: { id: payment.LimitId } })
    }
  }
  1. parent: 연쇄적 리졸버 호출에서 부모 리졸버가 리턴한 객체, 현재 리졸버가 내보낼 값 조절
  2. args: 쿼리에서 입력으로 넣은 인자
  3. context: 모든 리졸버에게 전달됨. 로그인 정보 혹은 권한 같이 주요 컨텍스트 정보 가지고 있음
  4. info: 현재 쿼리의 특정 필드 정보를 가지고 있음 (잘 사용하지 않음)

 

 

REST API와의 차이점

REST API를 통해서 정보를 받아오려면 필요한 정보 이외에도 많은 정보를 함께 받아야한다.

// REST API request
GET, https://swapi.dev/api/people/1

// REST API response
{
    "name": "Luke Skywalker",
    "height": "172",
    "mass": "77",
    "hair_color": "blond",
    "skin_color": "fair",
    "eye_color": "blue",
    "birth_year": "19BBY",
    "gender": "male",
    "homeworld": "http://swapi.dev/api/planets/1/",
    "films": ["http://swapi.dev/api/films/1/", "http://swapi.dev/api/films/2/", "http://swapi.dev/api/films/3/", "http://swapi.dev/api/films/6/"],
    "species": [],
    "vehicles": ["http://swapi.dev/api/vehicles/14/", "http://swapi.dev/api/vehicles/30/"],
    "starships": ["http://swapi.dev/api/starships/12/", "http://swapi.dev/api/starships/22/"],
    "created": "2014-12-09T13:50:51.644000Z",
    "edited": "2014-12-20T21:17:56.891000Z",
    "url": "http://swapi.dev/api/people/1/"
}
출처: https://hahahoho5915.tistory.com/63 [넌 잘하고 있어:티스토리]

 

하지만 이름, 키, 몸무게 데이터만 필요할 때 GraphQL을 사용하면 훨씬 간단하다.

// GraphQL request
query {
    person(personID: 1) {
        name
        height
        mass
    }
}

// GraphQL response
{
    "data": {
        "person": {
            "name": "Luke Skywalker",
            "height": 172,
            "mass": 77
        }
    }
}
출처: https://hahahoho5915.tistory.com/63 [넌 잘하고 있어:티스토리]

 

 

GraphQL의 장단점

장점

  1. HTTP 요청 횟수를 줄일 수 있다.
    RESTful의 경우 필요한 리소스 별로 요청 해야하고, 필요한 데이터들이 부분적으로 나눠서 개발되어 있다면 그만큼 요청 횟수가 늘어난다. 하지만 GraphQL은 원하는 정보를 하나의 쿼리에 모두 담아 요청 할 수 있다.

  2. HTTP 응답 사이즈를 줄일 수 있다.
    Restful의 경우 응답의 형태가 정해져있기 때문에 필요한 정보만 부분적으로 요청하는 것이 힘들고, 자연스럽게 데이터의 사이즈가 클 수 밖에 없다. GraphQL을 사용함으로써 응답 데이터 사이즈를 최소화하여 모바일 환경의 부담을 줄일 수 있다.

  3. 프론트엔드와 백엔드 개발자의 부담을 덜 수 있다.
    Restful API를 사용한다면 프론트엔드 개발자는 API의 request/response 형식에 의존하게 된다. 따라서 새로운 엔드포인트를 효율적이게 개발하기 위해서는 프론트엔드와 백엔드 개발자의 커뮤니케이션이 강제되는 경우가 많았다.
    하지만 GraphQL은 request/response 의존도가 많이 없기 때문에, 개발자들의 API 개발 부담을 덜 수 있다.

단점

  1. 고정된 요청과 응답만 필요할 때에는 query로 인해 요청의 크기가 Restful보다 커질 수 있다.
  2. 캐싱이 REST보다 복잡하다.
  3. 파일 업로드 구현 방법이 정해져있지 않아 직접 구현해야 한다.