GraphQL은 Facebook에서 개발된 쿼리 언어로, REST api의 단점을 보완하고 있습니다. GraphQL을 이용하면 클라이언트는 필요한 데이터만 요청하고 서버는 필요한 데이터만 응답할 수 있어서 효율적인 통신을 할 수 있습니다. 이러한 GraphQL을 구현하는데 Apollo server는 매우 유용한 도구입니다.
Apollo server는 GraphQL 스키마, 데이터 소스 및 리졸버를 관리하는 GraphQL 서버입니다. 이 도구는 Node.js와 함께 사용할 수 있으며, Express, Koa 등 다양한 웹 프레임워크와 함께 사용할 수 있습니다.
GraphQL 스키마는 GraphQL API의 기본 구조를 정의합니다. 스키마는 GraphQL API의 타입, 쿼리, 뮤테이션 등을 정의합니다. 이러한 스키마를 작성하고 관리하기 위해 Apollo server는 GraphQL 스키마 언어를 사용합니다.
데이터 소스는 GraphQL API에서 데이터를 가져오는 방법을 정의합니다. Apollo server는 REST API, 데이터베이스, 메모리 캐시, 외부 API 등 다양한 데이터 소스와 연결할 수 있습니다. 이러한 데이터 소스를 정의하고 사용하기 위해 Apollo server는 데이터 소스 클래스를 사용합니다.
리졸버는 GraphQL API의 쿼리 또는 뮤테이션에 대한 결과를 반환하는 함수입니다. 리졸버를 작성하고 구성하기 위해 Apollo server는 리졸버 함수를 사용합니다.
먼저, 개발할 프로젝트를 담을 새로운 폴더를 만들고 해당 폴더에서 터미널을 열어 node repository를 초기화합니다.
npm init -y
다음으로 필요한 모듈들을 설치합니다.
npm install apollo-server graphql
nodemon을 개발 환경에서 서버를 실행할 때 사용합니다.
npm i nodemon -D
서버를 구현할 server.js 파일을 생성합니다.
touch server.js
.gitignore 파일을 생성하여 node_modules 폴더를 추가합니다.
touch .gitignore
echo "node_modules/" >> .gitignore
현재 폴더를 git repository로 만들어줍니다.
git init
package.json 파일을 열어 script 항목에 nodemon server.js 명령어를 추가합니다.
{
"name": "my-graphql-api",
"version": "1.0.0",
"description": "My GraphQL API",
"main": "server.js",
"type": "module",
"scripts": {
"dev": "nodemon server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"apollo-server": "^3.5.0",
"graphql": "^16.3.0"
},
"devDependencies": {
"nodemon": "^2.0.13"
}
}
ES modules를 사용하기 위해서는 package.json의 type이 module로 설정되어야 합니다.
{
"name": "my-graphql-api",
"version": "1.0.0",
"description": "My GraphQL API",
"main": "server.js",
"type": "module",
"scripts": {
"dev": "nodemon server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"apollo-server": "^3.5.0",
"graphql": "^16.3.0"
},
"devDependencies": {
"nodemon": "^2.0.13"
}
"type": "module"
}
server.js 파일에서 ApolloServer와 gql 모듈을 import합니다.
import { ApolloServer, gql } from 'apollo-server';
터미널에서 아래 명령어를 입력하여 서버를 실행합니다.
npm run dev
import { ApolloServer, gql } from "apollo-server";
const typeDefs = gql`
type Query {
text: String
hello: String
}
`;
const server = new ApolloServer({ typeDefs });
server.listen().then(({ url }) => {
console.log(`Running on ${url}`);
주어진 코드는 ApolloServer를 이용하여 GraphQL API를 구현하는 예시 코드입니다.
import { ApolloServer, gql } from "apollo-server";
const typeDefs = gql`
type Query {
text: String
hello: String
}
`;
typeDefs는 GraphQL schema를 정의합니다. 위의 코드에서는 Query 타입을 정의하고, 이 타입은 text와 hello 두 개의 필드를 가집니다. text 필드의 타입은 String이고, hello 필드의 타입도 String입니다.
const server = new ApolloServer({ typeDefs });
ApolloServer 생성자 함수에는 typeDefs와 resolvers를 인자로 전달합니다. 위의 코드에서는 typeDefs만 전달하였습니다.
server.listen().then(({ url }) => {
console.log(`Running on ${url}`);
});
ApolloServer의 listen 메서드는 HTTP 서버를 시작합니다. 이 메서드는 Promise를 반환하며, 서버가 실행되면 Promise가 완료됩니다.
Promise의 then 메서드는 Promise가 완료된 후에 실행됩니다. then 메서드에 전달된 함수는 listen 메서드에서 반환된 값의 프로퍼티를 이용하여 실행됩니다.
예를 들어, listen 메서드가 다음과 같은 객체를 반환한다면:
{ url: "http://localhost:4000/" }
then 메서드에 전달된 함수는 다음과 같이 작성할 수 있습니다.
.then(({ url }) => {
console.log(`Running on ${url}`);
})
이 함수는 url 프로퍼티를 인자로 받으며, url을 이용하여 "Running on [URL]"과 같은 로그를 출력합니다.
여기서 {url}은 객체 비구조화(destructuring) 문법을 이용한 것입니다. 객체 비구조화 문법을 이용하면 객체의 프로퍼티를 변수에 할당할 수 있습니다.
const obj = { a: 1, b: 2 };
const { a, b } = obj;
console.log(a); // 1
console.log(b); // 2
이 코드에서는 resolver를 작성하지 않았으므로, 실행 후 GraphQL Playground에서는 text와 hello 필드에 대한 결과가 null로 출력됩니다. 필요한 resolver를 작성하여 API를 구현해보세요.