GraphQL이란? - 간단한 Query 작성
REST API의 단점
Overfetching
$ curl -X GET http://binary01.me/interns
[
{
"id": 1,
"name": "이진수",
"job": "IT"
},
{
"id": 2,
"name": "박경남",
"job": "IT"
},
...
]
이전 포스팅의 내용을 가져와서 다시 보자!
위 GET 요청은 인턴사원들의 id, name, job을 Client에게 Response 해준다.
하지만 Client가 id, job에 대한 값들은 필요 없고 name만 필요로 한다면??
REST API에서 어떻게 해야 할까?
$ curl -X GET http://binary01.me/names
위와 같은 Endpoint를 하나 만들어 name만 반환해주는 GET 요청을 만들 수 있다.
그렇다면 id만 필요할 경우는 ? job만 필요한 경우는 ? 🤔
이에 지친 개발자들은 결국 /interns로 인턴사원들의 모든 정보를 받아온 다음 필요한 것만 가져다 쓴다.
-> 이것이 바로 Overfetching
Overfetching 이란 Client가 어느 시점에 필요하지 않은 데이터까지 요청하는 것을 말한다. 이는 APP의 성능 저하를 유도하며 보안상으로도 좋다고 할 수 없다.
Underfetching
Underfetching은 Overfetching과 반대되는 개념이다.
Client에서 필요로 하는 데이터가 충분하지 않아, 추가적인 API를 계속 만들어야 한다는 것 또는 추가적인 요청을 계속해야 한다는 것이다.
GraphQL
드디어 GraphQL이다.
아래 내용은 중요하다고 이전 글에서 다시 한번 가져왔다.
GraphQL은 REST API의 대체재 성격으로 2015년 Facebook에서 발표한 통신 API이다. GraphQL은 REST API의 단점인 Underfetching, Overfetching을 효과적으로 줄일 수 있다.
또한, GraphQL은 단일 EndPoint를 지향함으로써 /graphql에서 모든 요청을 처리한다.
GraphQL은 API를 위한 쿼리 언어이며 이미 존재하는 데이터로 쿼리를 수행하기 위한 런타임이다.
Query language라고 하면 SQL이 생각난다! SQL은 서버와 데이터베이스가 정보를 주고받기 위한 언어다.
이와 유사하게 GraphQL은 서버와 클라이언트가 정보를 주고받기 위한 언어라고 생각하면 된다!
바로 JS로 작성된 코드를 보여 설명하겠다!
mkdir graphql_test
cd graphql_test
npm init -y
npm install --save express
npm install --save express-graphql
npm install --save graphql-tools
touch app.js
graphql_test 폴더를 만든 후, 해당 폴더에 들어가서 npm init -y로 package.json 파일을 만들어 준다.
다음으로 express, express-graphql, graphql-tools 모듈을 설치해준다.
마지막으로 app.js 파일을 만들어 준다.
const express = require('express');
const graphqlHTTP = require('express-graphql');
const { makeExecutableSchema } = require("graphql-tools");
app.js 파일 안에 위와 같이 설치한 모듈들을 불러온다.
각 모듈을 아주 간단하게 설명하자면, express는 자체적인 최소한의 기능을 갖춘 라우팅 및 미들웨어 웹 프레임워크이다.
express-graphql은 미들웨어로 express와 함께 사용할 것이다.
graphql-tools은 GraphQL에서 필요한 typeDefs, resolvers를 결합하여 하나의 schema로 만들어 주는 데 사용한다.
const typeDefs = `
type Query {
test: String
}
`;
const resolvers = {
Query: {
test: () => "binary01.me"
}
};
typeDefs, resolvers는 위와 같이 작성해준다.
typeDefs에 정의한 Query는 데이터를 읽어오는 GraphQL의 기능 중 하나이다.
test : String에서 test는 Query의 이름이며, String은 데이터 반환 type이다.
typeDefs에 test라는 이름의 Query와 데이터 반환 type을 지정했으니,
Query test은 어떤 동작을 한 후 String을 반환하는지 resolvers에서 정의해보자!
test: () => "binary01.me"
Query test는 input이 없고 바로 binary01.me라는 String을 반환한다고 resolvers에 작성하였다!
const schema = makeExecutableSchema({
typeDefs,
resolvers
});
다음으로 makeExecutableSchema를 이용하여 typeDefs, resolvers를 하나의 schema로 만들어 준다.
const app = express();
app.use('/graphql', graphqlHTTP({
schema: schema,
graphiql: true,
}));
app.listen(3000);
console.log('Running a GraphQL API server at localhost:3000/graphql');
app.use를 활용하여 Endpoint /graphql로 통신할 수 있게 해준다.
마지막으로 3000번 포트로 서버를 열어준다.
다음으로 package.json이 있는 폴더로 가서 node app.js 입력해준 후 엔터!
node app.js
Running a GraphQL API server at localhost:3000/graphql
코드에 문제가 없으면 console에 위와 같은 문구가 뜨며 서버가 실행된다!
그 후 주소창에 위와 같이 입력하고 접속하면 ~

짜잔~! GraphiQL이 뜨는 것을 확인할 수 있다.
GraphiQL은 Query, Mutation, Subscription (아직 설명은 안 했지만..) 등을 테스트하고
어떤 type들이 정의된 지 확인할 수 있는 아주 좋은 GraphQL의 IDE라고 할 수 있다.

GraphiQL 왼쪽 창에 위와 같은 코드를 입력하고 실행 버튼을 누르면 오른쪽과 같은 결과를 얻을 수 있다.
위 링크는 제목 그대로 GraphQL을 설명하는데, 시간도 짧고 중요한 부분을 아주 재미있게 잘 설명했다. 꼭 한 번 보는 걸 추천한다!
마무리
오늘은 REST API의 단점을 간략히 설명하고, 바로 GraphQL의 코드를 보며 설명해보았다.
하지만 Mutation, Subscription도 설명해야 하고 Apollo 등등 아직 설명할 게 너무 많다. 안뇽~ ✌✌
app.js
const express = require('express');
const graphqlHTTP = require('express-graphql');
const { makeExecutableSchema } = require("graphql-tools");
const typeDefs = `
type Query {
test: String
}
`;
const resolvers = {
Query: {
test: () => "binary01.me"
}
};
const schema = makeExecutableSchema({
typeDefs,
resolvers
});
const app = express();
app.use('/graphql', graphqlHTTP({
schema: schema,
graphiql: true,
}));
app.listen(3000);
console.log('Running a GraphQL API server at localhost:3000/graphql');