Node.js와 Apollo Server로 GraphQL 서버 구축
Node.js와 Apollo Server를 이용해 GraphQL 서버를 처음부터 구성하는 과정과 핵심 개념, 코드 예제 및 배포 고려사항을 실무 관점에서 정리한 방법
목차
개요
GraphQL은 클라이언트가 필요한 데이터만 요청할 수 있게 해주는 쿼리 언어다. Node.js 환경에서 Apollo Server를 활용하면 빠르게 GraphQL 엔드포인트를 구성할 수 있다. 이 글은 Node.js GraphQL Apollo Server에 대한 기본 흐름과 실습 예제를 중심으로 설명한다.
준비 사항
필수 도구
- Node.js LTS 버전
- npm 또는 yarn
- 간단한 코드 편집기
프로젝트는 최소한의 설정으로 시작한다. 의존성은 apollo-server와 graphql이 핵심이다.
프로젝트 초기화
프로젝트 구조는 단순하게 유지한다. package.json과 서버 진입 파일(index.js 또는 server.js)이 있으면 충분하다.
npm init -y
npm install apollo-server graphql
기본 서버 코드
스키마와 리졸버를 정의한 뒤 ApolloServer 인스턴스를 만든다. 아래 예제는 간단한 Query 타입과 in-memory 데이터로 동작한다.
const { ApolloServer, gql } = require('apollo-server');
const typeDefs = gql`
type Book {
id: ID!
title: String!
author: String!
}
type Query {
books: [Book!]!
book(id: ID!): Book
}
`;
const books = [
{ id: '1', title: 'Node.js in Action', author: 'Author A' },
{ id: '2', title: 'Learning GraphQL', author: 'Author B' }
];
const resolvers = {
Query: {
books: () => books,
book: (_, { id }) => books.find(b => b.id === id)
}
};
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
console.log(`Server ready at ${url}`);
});
코드 설명
typeDefs는 스키마 정의다. gql 템플릿 리터럴을 사용해 GraphQL 타입을 선언한다. resolvers는 스키마 타입에 대응하는 함수 모음이다. Query.books와 Query.book은 각각 전체 도서 목록과 단일 도서 조회를 처리한다.
간단한 쿼리 테스트
Apollo Server는 기본적으로 GraphQL Playground 또는 Apollo Studio Explorer 같은 인터페이스를 제공한다. 예시 쿼리는 다음과 같다.
{
books {
id
title
author
}
}
유용한 확장
입력 타입과 뮤테이션
데이터를 변경하려면 Mutation 타입과 입력 타입을 추가한다. 아래는 새 도서 추가 예시다.
const typeDefs = gql`
input AddBookInput {
title: String!
author: String!
}
type Mutation {
addBook(input: AddBookInput!): Book!
}
`;
const resolvers = {
Mutation: {
addBook: (_, { input }) => {
const newBook = { id: String(books.length + 1), ...input };
books.push(newBook);
return newBook;
}
}
};
데이터베이스 연동
실무에서는 in-memory 대신 데이터베이스를 사용한다. 연결 방식은 ORM 또는 데이터베이스 클라이언트에 따라 달라진다. 데이터 접근 로직은 리졸버에서 직접 호출해도 되고, 별도의 데이터 소스 계층으로 분리해도 된다.
보안 및 성능 고려사항
- 쿼리 복잡도 제한과 깊이 제한으로 악의적 요청 방지
- 데이터베이스 쿼리 최적화와 배치 로딩(DataLoader) 적용
- 인증과 권한 검증은 컨텍스트(context)에서 처리
예를 들어, 사용자 정보를 context에 넣고 리졸버에서 권한 검사를 수행하는 방식이 일반적이다.
배포와 운영
운영 환경에서는 다음 항목을 검토한다.
- 환경 변수로 민감 정보 관리
- 로깅과 모니터링 설정
- 스케일링을 고려한 무상태(stateless) 구성
마무리
이 글은 Node.js GraphQL Apollo Server를 처음 접하는 사람도 이해할 수 있게 구성했다. 기본 스키마 설계, 리졸버 구조, 간단한 뮤테이션과 배포 고려사항까지 다뤘다. 추가 심화 학습으로는 인증 패턴, DataLoader 활용, 서브스크립션 구성 등을 추천한다. 관련 키워드는 Node.js GraphQL Apollo Server, GraphQL 튜토리얼 Node.js, Apollo Server 예제다.