OPEN HYPER STEP
← 목록으로 (stack-analysis)
STACK-ANALYSIS · 38 / 90
stack-analysis
CHAPTER 38 / 90
읽기 약 2
FUNCTION

GraphQL vs REST: 실전 선택 기준


핵심 개념

over/under-fetching·N+1·DataLoader·실전 도입 기준 — 무엇이 적합한가.

본문

REST vs GraphQL 비교

📋 코드 (9줄)
| 측면 | REST | GraphQL |
|---|---|---|
| 페치 | 여러 요청 | 단일 요청 |
| 응답 | 고정 | 클라이언트 선택 |
| 캐싱 | HTTP 자동 | 자체 구현 |
| 학습 곡선 | 낮음 | 중 |
| 도구 | 풍부 | 풍부 |
| 파일 업로드 | 표준 | 비표준 |
| 적합 | 공개 API·간단 | 복잡 UI·여러 리소스 |

REST의 over-fetching 문제

TYPESCRIPT📋 코드 (18줄)
// 클라이언트는 user.name만 필요한데 전체 받음
GET /users/123
{
  "id": "123",
  "name": "Alice",
  "email": "...",          // 불필요
  "phone": "...",          // 불필요
  "address": {...},        // 불필요
  "preferences": {...},    // 불필요
}


// 또는 under-fetching — 여러 요청 필요
GET /users/123          // 사용자
GET /users/123/posts    // 포스트
GET /users/123/followers  // 팔로워

→ 3번의 round trip

GraphQL — 한 번에

GRAPHQL📋 코드 (23줄)
query {
  user(id: "123") {
    name
    posts(limit: 5) {
      title
      likes
    }
    followers(limit: 10) {
      name
      avatar
    }
  }
}


# 응답 — 정확히 요청한 데이터만
{
  "user": {
    "name": "Alice",
    "posts": [{"title": "...", "likes": 42}, ...],
    "followers": [{"name": "Bob", "avatar": "..."}, ...]
  }
}

GraphQL 서버 (Apollo)

TYPESCRIPT📋 코드 (51줄)
import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';

const typeDefs = `#graphql
  type User {
    id: ID!
    name: String!
    email: String!
    posts(limit: Int = 10): [Post!]!
  }

  type Post {
    id: ID!
    title: String!
    content: String!
    author: User!
  }

  type Query {
    user(id: ID!): User
    posts(limit: Int = 20, cursor: String): [Post!]!
  }

  type Mutation {
    createPost(title: String!, content: String!): Post!
  }
`;

const resolvers = {
  Query: {
    user: async (_: any, { id }: { id: string }, ctx: Context) => {
      return ctx.userRepo.findById(id);
    },
    posts: async (_: any, { limit, cursor }: any, ctx: Context) => {
      return ctx.postRepo.findMany({ limit, cursor });
    },
  },
  User: {
    posts: async (user: User, { limit }: { limit: number }, ctx: Context) => {
      return ctx.postLoader.load(user.id);  // DataLoader로 N+1 방지
    },
  },
  Mutation: {
    createPost: async (_: any, args: any, ctx: Context) => {
      if (!ctx.userId) throw new GraphQLError('Unauthorized');
      return ctx.postRepo.create({ ...args, authorId: ctx.userId });
    },
  },
};

const server = new ApolloServer({ typeDefs, resolvers });

DataLoader — N+1 방지

TYPESCRIPT📋 코드 (26줄)
import DataLoader from 'dataloader';

// 사용자별 포스트 배치 로더
function createPostLoader() {
  return new DataLoader<string, Post[]>(async (userIds) => {
    const posts = await db.post.findMany({
      where: { authorId: { in: [...userIds] } },
    });
    return userIds.map(id => posts.filter(p => p.authorId === id));
  });
}


// Context에 로더 주입
const server = new ApolloServer({
  typeDefs, resolvers,
  context: ({ req }) => ({
    userId: getUserId(req),
    postLoader: createPostLoader(),  // 요청별 새 인스턴스
  }),
});


// 효과:
// 100명 사용자 → 100번 쿼리 (N+1)
// DataLoader → 1번 쿼리 (배치 + 캐싱)

언제 무엇을 선택?

📋 코드 (17줄)
GraphQL 적합:
- 모바일 앱 (대역폭 제한)
- 복잡한 UI (대시보드·관리자)
- 여러 리소스 동시 페치
- BFF (Backend For Frontend) 패턴

REST 적합:
- 공개 API (생태계 풍부)
- 캐싱이 중요 (CDN)
- 단순 CRUD
- 마이크로서비스 간 통신
- 파일 업로드


하이브리드 (가장 흔함):
- GraphQL: 프론트엔드 → BFF
- REST/gRPC: 서비스 간

한국 시장 채택률

📋 코드 (8줄)
2026년 한국 백엔드:
- REST: 80% (압도적)
- GraphQL: 15% (당근·토스·쿠팡 일부)
- gRPC: 5% (서비스 간 내부)


스타트업: REST 우선
대규모 (네카라쿠배): 혼합

다음 챕터

CH.39 "PostgreSQL 성능 튜닝: EXPLAIN ANALYZE".


AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude

무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6

내 코드의 GraphQL vs REST 부분을 분석해서
실전 분석 + 개선 우선순위를 알려줘.
ChatGPT

무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro

GraphQL vs REST 관련 인기 라이브러리/패턴 5개를
비교 분석해서 패턴 추출를 알려줘.
Gemini

무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro

내 프로젝트 전체에서 GraphQL vs REST
최적화 가능 위치를 보고해줘.
Grok

무료: Grok 4.1 / SuperGrok $30/mo

2026년 한국 백엔드 시장의
GraphQL vs REST 트렌드를 솔직히 알려줘.

⭐ 이것만 기억하세요
GraphQL vs REST: 실전 선택 기준 이 3가지만 확실히 잡으세요
1.GraphQL은 over/under-fetching 해결 — 복잡 UI에 적합
2.DataLoader로 N+1 방지 — 배치 + 요청별 캐싱
3.REST는 여전히 표준 — 공개 API·캐싱·생태계


공유하기
진행도 38 / 90