최근 한 달간 GraphQL을 사용해 본 경험을 공유하고자 합니다. 이번 글에서는 GraphQL의 성능과 안정성, 그리고 이를 통해 우리 프로젝트의 API 설계가 어떻게 변화했는지를 다뤄보겠습니다.
GraphQL 도입 배경
우리 팀은 기존 REST API를 사용해왔습니다. 하지만 클라이언트 애플리케이션의 요구 사항이 점점 복잡해지면서, 여러 엔드포인트를 호출해야 하는 번거로움과 데이터 중복, 오버페칭 문제가 발생하기 시작했습니다. 이에 따라 GraphQL을 도입하기로 결정했습니다. GraphQL은 단일 엔드포인트에서 다양한 데이터를 쿼리할 수 있게 해 주며, 필요한 데이터만 선택적으로 가져올 수 있는 장점이 있습니다.
GraphQL 기본 구조
GraphQL을 사용하기 위해 기본적인 스키마를 정의해야 합니다. 그래프의 구조는 다음과 같이 설정했습니다:
type User {
id: ID!
name: String!
email: String!
posts: [Post]
}
type Post {
id: ID!
title: String!
content: String!
author: User
}
type Query {
users: [User]
user(id: ID!): User
posts: [Post]
}
위와 같은 스키마를 기반으로, 클라이언트에서 요구하는 데이터의 형태에 맞춰 쿼리를 작성할 수 있습니다. 예를 들어, 특정 사용자의 포스트와 함께 정보를 요청하는 쿼리는 다음과 같습니다:
query {
user(id: "1") {
name
posts {
title
content
}
}
}
이렇게 요청하면 필요한 정보만을 가져올 수 있습니다.
성능 측면의 변화
GraphQL을 도입한 후, API 호출 수가 크게 줄어들었습니다. REST API에서는 사용자 정보를 가져오기 위해 여러 번의 호출이 필요했지만, GraphQL에서는 단일 쿼리로 원하는 모든 데이터를 가져올 수 있었습니다. 이를 통해 클라이언트의 응답 속도가 개선되었고, 서버의 부하도 줄어들었습니다.
하지만 GraphQL의 성능은 쿼리의 복잡성에 따라 달라질 수 있습니다. 복잡한 쿼리를 사용하면 서버의 처리 시간이 늘어나는 문제가 발생할 수 있었습니다. 이를 해결하기 위해 쿼리의 복잡성을 제한하는 방식으로 최적화를 진행했습니다. 특히, 깊은 중첩을 지양하고 필요한 필드만 요청하도록 유도했습니다.
안정성 측면의 변화
안정성 측면에서도 GraphQL은 큰 변화를 가져왔습니다. REST API에서는 각 엔드포인트가 독립적으로 관리되기 때문에, 인터페이스 변경 시 모든 클라이언트에 영향을 미쳤습니다. 하지만 GraphQL에서는 스키마 기반으로 개발이 이루어지기 때문에, 스키마의 진화를 통해 기존 클라이언트는 영향을 받지 않고 새로운 기능을 추가할 수 있었습니다.
또한 GraphQL의 유효성 검사 기능을 통해 클라이언트에서 의도하지 않은 잘못된 쿼리를 사전에 차단할 수 있었습니다. 다음은 GraphQL의 유효성 검사 예시입니다:
const { GraphQLObjectType, GraphQLString, GraphQLSchema, GraphQLNonNull } = require('graphql');
const UserType = new GraphQLObjectType({
name: 'User',
fields: () => ({
id: { type: GraphQLNonNull(GraphQLString) },
name: { type: GraphQLNonNull(GraphQLString) },
email: { type: GraphQLString },
}),
});
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
user: {
type: UserType,
args: { id: { type: GraphQLNonNull(GraphQLString) } },
resolve(parent, args) {
// 데이터베이스에서 사용자 정보 조회
},
},
},
});
module.exports = new GraphQLSchema({
query: RootQuery,
});
이를 통해 클라이언트와 서버 간의 의사소통이 더욱 원활해졌습니다.
마무리
한 달간의 GraphQL 사용 경험은 우리 팀에게 많은 교훈을 주었습니다. 데이터 요청의 효율성을 높이고, 안정성을 개선할 수 있었던 점은 큰 장점입니다. 그러나 GraphQL의 성능은 쿼리의 복잡성에 따라 좌우되므로, 적절한 쿼리 설계와 성능 관리가 필요합니다. 앞으로도 GraphQL의 다양한 기능을 탐색하며, 우리의 API 설계를 지속적으로 발전시켜 나갈 계획입니다.