GraphQL은 페이스북(현 메타)에서 개발한, API를 위한 쿼리 언어(Query Language)이자 해당 쿼리를 실행하기 위한 런타임입니다. REST API의 몇 가지 문제점을 해결하기 위해 등장했습니다.
REST API의 문제점:
이름만 필요한데, 나이, 주소, 가입일까지 모두 받아옴)GraphQL의 해결책:
/graphql)를 사용합니다.# 클라이언트가 서버에 보내는 쿼리
query {
user(id: "1") {
name
email
posts {
title
}
}
}
# 서버가 클라이언트에게 보내는 응답 (JSON)
{
"data": {
"user": {
"name": "Alice",
"email": "alice@example.com",
"posts": [
{ "title": "My first post" },
{ "title": "GraphQL is awesome" }
]
}
}
}
GET과 유사합니다.POST, PUT, DELETE를 합친 것과 유사합니다.@nestjs/graphql과 @nestjs/apollo 패키지를 통해 GraphQL 서버를 매우 쉽고 구조적으로 구축할 수 있도록 지원합니다.npm install @nestjs/graphql @nestjs/apollo graphql apollo-server-express
app.module.ts)에 GraphQLModule 등록GraphQLModule.forRoot()를 사용하여 GraphQL 서버의 기본 설정을 구성합니다.
autoSchemaFile: true: 코드(TypeScript 클래스)를 기반으로 GraphQL 스키마 파일(schema.gql)을 자동으로 생성해주는 매우 강력한 옵션입니다. (Code-First 접근 방식)driver: ApolloDriver: GraphQL 쿼리를 실행할 엔진으로 Apollo Server를 사용하도록 지정합니다.// app.module.ts
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver } from '@nestjs/apollo';
@Module({
imports: [
GraphQLModule.forRoot({
driver: ApolloDriver,
autoSchemaFile: true,
}),
],
})
export class AppModule {}
@ObjectTypeGraphQL 스키마에서 사용될 데이터 타입을 정의합니다. NestJS에서는 @ObjectType() 데코레이터가 붙은 클래스를 사용하여 이를 정의합니다.
@Field(): 외부로 노출될 필드를 명시합니다.
// movie.dto.ts
import { ObjectType, Field, Int } from '@nestjs/graphql';
@ObjectType() // 이 클래스가 GraphQL의 타입임을 선언
export class Movie {
@Field(() => Int)
id: number;
@Field()
title: string;
@Field(() => Int)
year: number;
}
리졸버는 특정 GraphQL 쿼리나 뮤테이션에 대한 실제 처리 로직을 담고 있는 클래스입니다. REST의 컨트롤러와 유사한 역할을 합니다.
@Resolver(): 이 클래스가 리졸버임을 선언합니다.
@Query(): 쿼리 핸들러임을 나타냅니다.
@Mutation(): 뮤테이션 핸들러임을 나타냅니다.
@Args(): 쿼리나 뮤테이션에 전달된 인자(arguments)를 가져옵니다.
// movies.resolver.ts
import { Resolver, Query, Args, Mutation } from '@nestjs/graphql';
import { Movie } from './dto/movie.dto';
import { MoviesService } from './movies.service';
@Resolver()
export class MoviesResolver {
constructor(private readonly moviesService: MoviesService) {}
@Query(() => [Movie]) // 이 메서드가 [Movie] 타입을 반환하는 쿼리임을 선언
movies(): Movie[] {
return this.moviesService.getAll();
}
@Mutation(() => Boolean)
createMovie(@Args('title') title: string): boolean {
// ... 영화 생성 로직 ...
return true;
}
}
Query(읽기), Mutation(쓰기), Subscription(실시간)으로 나뉩니다.@ObjectType, @Field)로 스키마를 정의하면, GraphQL 스키마 파일이 자동으로 생성됩니다.@Resolver)는 REST의 컨트롤러와 유사한 역할을 하며, @Query와 @Mutation 데코레이터가 붙은 메서드에서 실제 데이터 처리 로직을 구현합니다.