인턴
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의 구조
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 } })
}
}
- parent: 연쇄적 리졸버 호출에서 부모 리졸버가 리턴한 객체, 현재 리졸버가 내보낼 값 조절
- args: 쿼리에서 입력으로 넣은 인자
- context: 모든 리졸버에게 전달됨. 로그인 정보 혹은 권한 같이 주요 컨텍스트 정보 가지고 있음
- 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의 장단점
장점
- HTTP 요청 횟수를 줄일 수 있다.
RESTful의 경우 필요한 리소스 별로 요청 해야하고, 필요한 데이터들이 부분적으로 나눠서 개발되어 있다면 그만큼 요청 횟수가 늘어난다. 하지만 GraphQL은 원하는 정보를 하나의 쿼리에 모두 담아 요청 할 수 있다. - HTTP 응답 사이즈를 줄일 수 있다.
Restful의 경우 응답의 형태가 정해져있기 때문에 필요한 정보만 부분적으로 요청하는 것이 힘들고, 자연스럽게 데이터의 사이즈가 클 수 밖에 없다. GraphQL을 사용함으로써 응답 데이터 사이즈를 최소화하여 모바일 환경의 부담을 줄일 수 있다. - 프론트엔드와 백엔드 개발자의 부담을 덜 수 있다.
Restful API를 사용한다면 프론트엔드 개발자는 API의 request/response 형식에 의존하게 된다. 따라서 새로운 엔드포인트를 효율적이게 개발하기 위해서는 프론트엔드와 백엔드 개발자의 커뮤니케이션이 강제되는 경우가 많았다.
하지만 GraphQL은 request/response 의존도가 많이 없기 때문에, 개발자들의 API 개발 부담을 덜 수 있다.
단점
- 고정된 요청과 응답만 필요할 때에는 query로 인해 요청의 크기가 Restful보다 커질 수 있다.
- 캐싱이 REST보다 복잡하다.
- 파일 업로드 구현 방법이 정해져있지 않아 직접 구현해야 한다.