LabHub

블로그

GraphQL 생태계 2026 — Apollo / GraphOS / Yoga / urql / Relay / Pothos / Hasura DDN 심층 비교

한국어English日本語

프롤로그 — "GraphQL은 죽었다"가 죽었다

2023년쯤부터 X(구 Twitter)와 Reddit, HN에는 주기적으로 "GraphQL is dead" 류의 글이 올라왔다. tRPC가 빠르게 떠오르고, Netflix의 Federation 사례에 대한 회의론이 늘어나고, Shopify가 일부 신규 API를 REST로 회귀한 것이 자주 인용됐다. 2024년에는 한 컨퍼런스 키노트가 "GraphQL은 마이크로서비스처럼 과도하게 쓰인 도구다"라고 말하면서 다시 한 번 논쟁이 불붙었다.

2026년 5월 현재, 그 논쟁의 결말은 비교적 명확해졌다.

이 글은 그 시장 위에 어떤 도구들이 어떻게 자리잡았는지, 그리고 2026년에 새 프로젝트를 시작할 때 무엇을 골라야 하는지를 정리한다. Apollo / GraphOS 같은 매니지드 진영, Yoga / Mesh / urql / Pothos 같은 The Guild 진영, Relay / Pothos / Nexus 같은 코드 우선 진영, Hasura DDN / Hot Chocolate / gqlgen / Strawberry / graphql-rust 같은 언어별 서버, Stellate 같은 인프라 — 한 글에서 다 본다.


1장 · 2026년 GraphQL 생태계 — "GraphQL은 죽었다" 논쟁 이후

먼저 2025~2026 사이의 사실관계를 정리하자.

큰 흐름은 세 가지다.

  1. 페더레이션의 일반화 — 회사 1곳 = 그래프 1개의 단일 거대 스키마는 사라졌다. 도메인별 subgraph + 게이트웨이가 표준.
  2. 코드 우선의 부상 — SDL 우선이 아니라 코드(TypeScript/Python/.NET)에서 스키마를 추론. Pothos, Strawberry, Hot Chocolate, gqlgen 모두 같은 흐름.
  3. REST/tRPC와의 공존 — GraphQL은 BFF·집계·페더레이션 계층, tRPC/REST는 내부·단일 서버. 종교 전쟁은 끝났다.

이 책 같은 글의 출발점은 이 셋이다.


2장 · GraphQL vs tRPC vs REST — 언제 무엇을 골라야 하나

가장 흔한 질문 먼저 풀자. 셋의 차이를 한 표로.

항목GraphQLtRPCREST(OpenAPI)
스키마SDL, 명시적TS 타입에서 추론OpenAPI/JSON Schema
호출 모델쿼리/뮤테이션/서브스크립션함수 호출HTTP 메서드 + URL
타입 안전강함(코드젠)매우 강함(타입 추론)도구에 따름
언어모든 언어 클라이언트TS 전용모든 언어
캐싱정규화 캐시, CDN(Stellate)단순(앱 캐시)HTTP 캐시 친화
사용 시점모바일, BFF, 페더레이션단일 TS 풀스택공개·내부 RPC, 단순 CRUD
학습 곡선가파름거의 없음낮음
페이로드클라이언트 정의함수 시그니처서버 정의

핵심 의사 결정 트리.

  1. 프런트와 백이 같은 TS 모노레포고 다른 언어가 안 끼면 tRPC가 가장 빠르다.
  2. 모바일 또는 다중 클라이언트(iOS/Android/Web/임베디드)가 있고, 각자 필요한 필드가 다르면 GraphQL.
  3. 다른 팀의 백엔드(여러 서비스)를 하나로 합쳐 보여줘야 하면 GraphQL Federation.
  4. 공개 API, 외부 파트너 통합, 단순 CRUD라면 REST(OpenAPI)가 안전.
  5. 내부 마이크로서비스 간 호출, 고성능이면 gRPC.

2026년 현실은 한 회사에 셋 다 있다. 외부 공개 API는 REST, 모바일·웹 BFF는 GraphQL, 내부 서비스 간은 gRPC, TS 단일 풀스택 서비스는 tRPC. "하나만 골라"라는 질문 자체가 옛날이야기.


3장 · Apollo Server 5 / Client 4 — 표준의 자리

Apollo는 2025년에 Server 5, Client 4를 출시했다. 두 메이저 릴리스는 같이 가야 의미가 있다.

Apollo Server 5의 주요 변화

서버 부트스트랩의 모양.

// server.ts
import { ApolloServer } from '@apollo/server'
import { startStandaloneServer } from '@apollo/server/standalone'
import { typeDefs } from './schema'
import { resolvers } from './resolvers'

const server = new ApolloServer({
  typeDefs,
  resolvers,
  introspection: process.env.NODE_ENV !== 'production',
})

const { url } = await startStandaloneServer(server, {
  listen: { port: 4000 },
  context: async ({ req }) => ({
    user: await getUserFromToken(req.headers.authorization),
  }),
})

console.log(`Apollo Server ready at ${url}`)

Apollo Client 4의 주요 변화

// client.ts
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client'

export const client = new ApolloClient({
  link: new HttpLink({ uri: '/graphql' }),
  cache: new InMemoryCache(),
})

React에서 쓸 때.

import { useSuspenseQuery } from '@apollo/client/react'
import { gql } from '@apollo/client'

const ME = gql`
  query Me {
    me {
      id
      name
      email
    }
  }
`

export function Profile() {
  const { data } = useSuspenseQuery(ME)
  return <div>{data.me.name}</div>
}

강점

약점


4장 · GraphOS — Apollo의 매니지드 페더레이션

GraphOS는 Apollo가 만든 페더레이션 플랫폼이다. 핵심 컴포넌트는 셋.

  1. Apollo Router — Rust로 작성된 게이트웨이. subgraph 라우팅, 쿼리 플래닝, 캐싱.
  2. Schema Registry — subgraph 스키마의 중앙 저장소. 변경 감지, 호환성 체크.
  3. Studio(GraphOS UI) — 사용량 메트릭, 쿼리 분석, 운영 도구.

Apollo Router

Apollo Router는 이전의 Apollo Gateway(Node 기반)를 대체한 Rust 게이트웨이다. 처리량이 한 자릿수 배 이상 빠르고, 메모리 사용도 적다. 2026년 시점에서 페더레이션 게이트웨이를 새로 깐다면 거의 무조건 Router.

# router.yaml
supergraph:
  introspection: false
include_subgraph_errors:
  all: true
telemetry:
  exporters:
    metrics:
      prometheus:
        enabled: true
    tracing:
      otlp:
        enabled: true
        endpoint: http://otel:4317

비용 모델

GraphOS는 무료(Serverless), 유료(Dedicated), 엔터프라이즈로 나뉜다. 무료 티어로도 작은 팀은 충분히 돌아가지만, 운영 트래픽이 늘어나면 빠르게 유료로 넘어가야 한다. Apollo의 비즈니스 모델이 GraphOS에 묶여 있어, 2024~2025 사이에 가격 인상이 한 번 있었다.

대안

GraphOS의 대안으로는 GraphQL Hive(The Guild), Inigo, Stellate(주로 캐싱)가 있다. Hive는 OSS로도 셀프 호스팅이 가능하고, 더 가벼운 페더레이션 운영을 원하는 팀이 많이 본다. 2026년에 신규로 시작한다면 Apollo Router + Hive 조합도 충분히 합리적.


5장 · GraphQL Yoga 5 + Mesh 1 (The Guild) — 가벼운 진영

The Guild는 GraphQL OSS 생태계를 사실상 주도하는 컬렉티브다. 2026년에 주력 프로젝트는 다음.

GraphQL Yoga 5

Yoga는 "Express와 Apollo Server의 좋은 점만 모아 가볍게"라는 컨셉으로 시작했다. 5에서는 Node 18+, Fetch API 기반, Bun/Deno 호환, 엣지 런타임(Vercel/Cloudflare) 1차 시민.

// yoga.ts
import { createYoga, createSchema } from 'graphql-yoga'
import { createServer } from 'node:http'

const yoga = createYoga({
  schema: createSchema({
    typeDefs: /* GraphQL */ `
      type Query {
        hello: String!
      }
    `,
    resolvers: {
      Query: {
        hello: () => 'Hello from Yoga 5',
      },
    },
  }),
})

createServer(yoga).listen(4000)

GraphQL Mesh 1

Mesh는 여러 소스(REST, gRPC, OpenAPI, JSON Schema, Postgres, MongoDB)를 자동으로 GraphQL로 합쳐주는 도구다. 1.x에서 구성 파일이 단순해지고, 페더레이션 통합이 강화됐다. Apollo Router 뒤에 Mesh subgraph를 놓는 패턴이 흔하다.

강점

약점


6장 · urql 5 (Formidable) — Apollo Client 대안

urql은 Formidable이 만든 가벼운 클라이언트로, "Apollo가 무겁다"는 사람이 가장 먼저 보는 대안이다. 5에서 React 19, Suspense, Server Component를 1차 지원한다.

핵심 차이

import { Client, fetchExchange, cacheExchange, Provider } from 'urql'

const client = new Client({
  url: '/graphql',
  exchanges: [cacheExchange, fetchExchange],
})

function App() {
  return (
    <Provider value={client}>
      <Profile />
    </Provider>
  )
}

React 컴포넌트에서.

import { useQuery } from 'urql'

const ME = `
  query Me {
    me { id name }
  }
`

function Profile() {
  const [result] = useQuery({ query: ME })
  if (result.fetching) return <p>Loading...</p>
  if (result.error) return <p>Error</p>
  return <p>{result.data.me.name}</p>
}

강점

약점

언제 urql인가


7장 · Relay 18 (Meta) — 페이스북 내부 표준

Relay는 Meta가 만들고 사내에서 쓰는 GraphQL 클라이언트다. Apollo/urql과는 철학이 다르다. "성능을 위해 컴파일 타임에 최대한 보장한다"는 입장.

핵심 개념

// UserProfile.tsx
import { useFragment, graphql } from 'react-relay'

const UserProfileFragment = graphql`
  fragment UserProfile_user on User {
    name
    avatarUrl
  }
`

export function UserProfile({ user }: { user: UserProfile_user$key }) {
  const data = useFragment(UserProfileFragment, user)
  return <h1>{data.name}</h1>
}

Relay 18의 새 점

강점

약점

언제 Relay인가


8장 · Pothos — TypeScript 코드 우선 스키마 빌더

Pothos(이전 GiraphQL)는 TypeScript에서 GraphQL 스키마를 코드 우선으로 정의하는 라이브러리다. 2024~2025 사이에 Nexus를 밀어내고 사실상 표준이 됐다.

코드 우선이 뭐고 왜 좋은가

전통적인 SDL 우선 워크플로는 이렇다.

  1. schema.graphql에 타입을 SDL로 작성.
  2. graphql-codegen으로 TS 타입 생성.
  3. 리졸버에 그 타입을 import.

이게 한 번의 변경에 두 단계가 필요하다. 코드 우선은 거꾸로.

  1. TS로 스키마를 빌더 API로 작성.
  2. 빌더가 SDL을 자동 생성.

Pothos 예시

// schema.ts
import SchemaBuilder from '@pothos/core'

const builder = new SchemaBuilder({})

const User = builder.objectRef<{ id: string; name: string }>('User')

builder.objectType(User, {
  fields: (t) => ({
    id: t.exposeID('id'),
    name: t.exposeString('name'),
  }),
})

builder.queryType({
  fields: (t) => ({
    me: t.field({
      type: User,
      resolve: () => ({ id: '1', name: 'Alice' }),
    }),
  }),
})

export const schema = builder.toSchema()

Pothos의 강점

Nexus와의 비교

Nexus는 Pothos보다 먼저 나왔고 한때 표준이었다. 하지만 타입 추론에서 Pothos가 더 강하고, Nexus 메인테이너의 활동이 줄면서 사실상 자리를 넘겨줬다. 신규는 거의 Pothos.

Prisma 통합 예시

import SchemaBuilder from '@pothos/core'
import PrismaPlugin from '@pothos/plugin-prisma'
import { prisma } from './prisma'

const builder = new SchemaBuilder<{
  PrismaTypes: PrismaTypes
}>({
  plugins: [PrismaPlugin],
  prisma: { client: prisma },
})

builder.prismaObject('User', {
  fields: (t) => ({
    id: t.exposeID('id'),
    name: t.exposeString('name'),
    posts: t.relation('posts'),
  }),
})

Prisma 모델에서 GraphQL 타입을 거의 자동으로 생성한다. N+1 문제도 플러그인이 자동으로 풀어 준다.


9장 · Hasura DDN — 새 아키텍처

Hasura는 Postgres·SQL Server·BigQuery 같은 DB 위에 GraphQL API를 자동 생성해 주는 도구로 유명해졌다. 그런데 v2까지 가면서 몇 가지 문제가 생겼다.

DDN(Data Delivery Network)

2024년에 발표된 Hasura DDN은 v2의 한계를 정리한 새 아키텍처다.

강점

약점

언제 Hasura DDN인가


10장 · Hot Chocolate (.NET) / gqlgen (Go) / Strawberry (Python) / graphql-rust

JS/TS 바깥의 언어 생태계도 정리하자.

Hot Chocolate (.NET — ChilliCream)

public class Query
{
    public Book GetBook() =>
        new Book { Title = "C# in Depth", Author = new Author { Name = "Jon Skeet" } };
}

var builder = WebApplication.CreateBuilder(args);
builder.Services
    .AddGraphQLServer()
    .AddQueryType<Query>();

var app = builder.Build();
app.MapGraphQL();
app.Run();

gqlgen (Go — 99designs)

Strawberry (Python)

import strawberry

@strawberry.type
class User:
    id: strawberry.ID
    name: str

@strawberry.type
class Query:
    @strawberry.field
    def me(self) -> User:
        return User(id="1", name="Alice")

schema = strawberry.Schema(query=Query)

graphql-rust (async-graphql / juniper)

언어별 선택 가이드

언어1순위비고
TypeScript / NodeApollo Server 5 또는 GraphQL Yoga 5 + Pothos페더레이션이면 Apollo Router
PythonStrawberryGraphene은 레거시
Gogqlgen거의 독점
.NETHot Chocolate거의 독점
Rustasync-graphqljuniper는 보수적
Java/KotlinDGS(Netflix) 또는 graphql-javaSpring Boot면 DGS
Rubygraphql-ruby(GitHub 유지)Shopify·GitHub 사용
ElixirAbsinthe거의 독점

11장 · Stellate — GraphQL CDN 캐싱

GraphQL의 약점 중 하나는 캐싱이다. 같은 쿼리도 변수에 따라 다른 응답이 나오고, 모든 요청이 POST라 표준 HTTP 캐싱이 어렵다. Stellate는 그 문제를 위한 GraphQL 전용 CDN이다.

핵심 개념

사용 예시

Stellate에 GraphQL 엔드포인트를 등록하면, 그 앞에 CDN URL이 생긴다. 클라이언트는 원래 엔드포인트 대신 Stellate URL을 호출. 쿼리 응답은 5초~수 분 캐시되고, 뮤테이션이 발생하면 자동으로 관련 캐시가 무효화된다.

강점

약점


12장 · Federation 2 + subgraph composition 패턴

GraphQL Federation은 여러 subgraph(독립 서비스의 그래프)를 하나의 supergraph로 합치는 방식이다. Apollo가 표준을 정의했고, 2.x에서 안정화됐다.

핵심 디렉티브

Subgraph 예시 (Users)

type User @key(fields: "id") {
  id: ID!
  name: String!
  email: String!
}

type Query {
  me: User
  user(id: ID!): User
}

Subgraph 예시 (Orders)

extend type User @key(fields: "id") {
  id: ID! @external
  orders: [Order!]!
}

type Order @key(fields: "id") {
  id: ID!
  total: Float!
}

게이트웨이(Apollo Router)는 두 subgraph를 합쳐 supergraph를 만들고, 쿼리 플래너가 me { orders { total } }를 두 subgraph에 분할 요청한다.

Subgraph composition의 운영 패턴

안티패턴


13장 · persisted queries / defer / stream / live queries

2025~2026 사이에 안정화된 GraphQL 고급 기능들을 짚자.

Persisted Queries

클라이언트가 쿼리 전문 대신 해시만 보내고, 서버는 미리 등록된 쿼리를 실행한다. 효과는 둘.

  1. 네트워크 절약 — 모바일에서 큰 쿼리 페이로드를 매번 보내지 않아도 됨.
  2. 보안 — 클라이언트가 임의 쿼리를 못 보냄. 공격 표면 축소.

Apollo Persisted Queries, Hive Persisted Documents, Relay Persisted Queries 모두 같은 컨셉. 모바일·임베드 클라이언트에서는 사실상 의무.

@defer / @stream

큰 응답을 한 번에 보내지 말고, 일부를 먼저 보내고 나머지를 스트리밍.

query Profile {
  me {
    id
    name
    ... on User @defer {
      slowField
    }
  }
}

서버는 청크 응답(multipart/mixed)으로 일부 데이터를 먼저 보낸다. 큰 페이지에서 초기 렌더링 시간을 크게 줄일 수 있다. Apollo Server 5 / Yoga 5 / Hot Chocolate 모두 지원.

Live Queries

쿼리 결과가 바뀌면 자동으로 클라이언트에 업데이트가 푸시된다. Subscription과 비슷하지만 — Subscription은 명시적으로 채널을 구독하는 반면, Live Query는 그냥 쿼리를 보내면 서버가 변경을 감지해 재푸시.

Relay 18이 베타로 지원, Yoga·Hot Chocolate에도 실험 구현. 아직 표준화는 진행 중이지만 채팅·대시보드 같은 시나리오에서 매력적.

Subscriptions (다시 정리)


14장 · 한국 (카카오, 라인) / 일본 (Mercari, ZOZO) GraphQL 사용

한국과 일본의 큰 회사들이 GraphQL을 어떻게 쓰는지 공개 자료 기준으로 정리한다.

카카오

라인 / LINE (LY 그룹)

Mercari

ZOZO

공통 패턴

한국·일본 모두 "Apollo Server + 페더레이션 + Apollo Router + 사내 또는 SaaS 레지스트리"라는 큰 그림은 유사하다. 차이는 — 한국은 카카오·네이버 같은 거대 인하우스 백엔드 위주, 일본은 메르카리·ZOZO 같은 모바일 커머스 BFF가 메인.


결론 — 2026년에 GraphQL을 새로 고른다면

마지막으로 한 줄짜리 추천.

  1. Node/TS 신규 단일 서버 — Yoga 5 + Pothos + Prisma. 클라이언트는 urql 또는 Apollo.
  2. Node/TS 신규 페더레이션 — Apollo Server 5 + Apollo Router + GraphOS 또는 Hive. 클라이언트는 Apollo Client 4.
  3. Meta급 대형 SPA — Relay 18 + Pothos. 인프라는 자체 운영.
  4. 모바일 BFF — Apollo Server 5 + Apollo Client 4 + Persisted Queries + Stellate.
  5. Python — Strawberry + FastAPI/Django. 페더레이션이면 Apollo Router 뒤에 둠.
  6. Go — gqlgen + DataLoader. 클라이언트는 언어 무관.
  7. .NET — Hot Chocolate 14. 거의 다른 선택지가 없다.
  8. Rust — async-graphql + Axum. 성능이 진짜 중요하면.
  9. DB 위 자동 CRUD — Hasura DDN. 단, 자유도 높은 비즈니스 로직은 별도 서비스로.

그리고 가장 중요한 한 가지. "GraphQL이냐 아니냐"는 더 이상 단일 선택이 아니다. 한 회사에 GraphQL(모바일 BFF), tRPC(TS 풀스택), REST(공개 API), gRPC(내부 RPC)가 동시에 있는 게 정상이다. GraphQL은 죽지 않았다 — 적절한 자리를 찾았을 뿐.


참고 / References

댓글

아직 댓글이 없습니다.

로그인하면 댓글을 쓸 수 있습니다