๐Ÿš€ GraphQL APIs ์„ค๋ช… (์‹ค์ œ Node.js ์˜ˆ์ œ์™€ ํ•จ๊ป˜)

๋ฐœํ–‰: (2025๋…„ 12์›” 25์ผ ์˜คํ›„ 02:33 GMT+9)
7 min read
์›๋ฌธ: Dev.to

Source: Dev.to

REST๋Š” ์–ด๋””์—๋‚˜ ์กด์žฌํ•˜์ง€๋งŒ, GraphQL์€ ํ˜„๋Œ€ API๊ฐ€ ๊ตฌ์ถ•๋˜๋Š” ๋ฐฉ์‹์„ ๋ฐ”๊พธ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๊ธ€์—์„œ ๋ฐฐ์šฐ๊ฒŒ ๋  ๋‚ด์šฉ:

  • GraphQL์ด ์‹ค์ œ๋กœ ๋ฌด์—‡์ธ์ง€
  • ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ (์ „๋ฌธ ์šฉ์–ด ์—†์ด)
  • ์‹ค์ œ Node.js GraphQL API ์˜ˆ์ œ
  • ์žฅ์ ๊ณผ ๋‹จ์  (๋งˆ์ผ€ํŒ… ๊ณผ๋Œ€๊ด‘๊ณ  ์—†์ด)
  • NOT ์‚ฌ์šฉํ•ด์•ผ ํ•  ๊ฒฝ์šฐ

๐Ÿค” GraphQL์ด๋ž€?

GraphQL์€ API๋ฅผ ์œ„ํ•œ ์ฟผ๋ฆฌ ์–ธ์–ด์ด๋ฉฐ, ํ•ด๋‹น ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ๋Ÿฐํƒ€์ž„์ž…๋‹ˆ๋‹ค.
REST์™€ ๊ฐ™์ด ์—ฌ๋Ÿฌ ์—”๋“œํฌ์ธํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹ , GraphQL์€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ •ํ™•ํžˆ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋Š” ๋‹จ์ผ ์—”๋“œํฌ์ธํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค โ€” ๋” ๋งŽ์ง€๋„, ์ ์ง€๋„ ์•Š๊ฒŒ.

REST ์˜ˆ์‹œ

GET /users/1
GET /users/1/posts
GET /users/1/followers

GraphQL ์˜ˆ์‹œ

query {
  user(id: 1) {
    name
    posts {
      title
    }
    followers {
      name
    }
  }
}

ํ•˜๋‚˜์˜ ์š”์ฒญ. ํ•˜๋‚˜์˜ ์‘๋‹ต. ์ •ํ™•ํ•œ ๋ฐ์ดํ„ฐ.

๐Ÿง  GraphQL์ด ์ธ๊ธฐ๋ฅผ ๋ˆ ์ด์œ 

์ „ํ†ต์ ์ธ REST API๋Š” ์˜ค๋ฒ„ํŒจ์นญ(๋ฐ ์–ธ๋”ํŒจ์นญ) ๋ฌธ์ œ๋ฅผ ๊ฒช์Šต๋‹ˆ๋‹ค. GraphQL์€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์‘๋‹ต ํ˜•ํƒœ๋ฅผ ์ œ์–ดํ•˜๋„๋ก ํ•จ์œผ๋กœ์จ ์ด๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

โš™๏ธ GraphQL ์ž‘๋™ ๋ฐฉ์‹ (๊ฐ„๋‹จ ์„ค๋ช…)

GraphQL์—๋Š” ์„ธ ๊ฐ€์ง€ ํ•ต์‹ฌ ๋ถ€๋ถ„์ด ์žˆ์Šต๋‹ˆ๋‹ค:

  1. Schema โ€“ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค (๊ณ„์•ฝ)
  2. Queries / Mutations โ€“ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•
  3. Resolvers โ€“ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ํ•จ์ˆ˜

๐Ÿงฉ GraphQL vsโ€ฏREST (๋น ๋ฅธ ๋น„๊ต)

FeatureGraphQLREST
Endpoint countSingle endpointMultiple endpoints
Data fetchingClientโ€‘specified shapeFixed responses per endpoint
Over/underโ€‘fetchingEliminatedCommon issue
Tooling & typingStrongly typed schema, autoโ€‘completeVaries per implementation

Source:

๐Ÿงช ์‹ค์ œ GraphQL API ์˜ˆ์ œ (Node.js)

๐Ÿ“ฆ ์˜์กด์„ฑ ์„ค์น˜

npm init -y
npm install @apollo/server graphql

๐Ÿ—‚๏ธ index.js ๋งŒ๋“ค๊ธฐ

import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';

const users = [
  { id: "1", name: "Anshul", role: "Full Stack Developer" },
  { id: "2", name: "Rohit", role: "Backend Developer" }
];

// 1๏ธโƒฃ ์Šคํ‚ค๋งˆ
const typeDefs = `#graphql
  type User {
    id: ID!
    name: String!
    role: String!
  }

  type Query {
    users: [User]
    user(id: ID!): User
  }
`;

// 2๏ธโƒฃ ๋ฆฌ์กธ๋ฒ„
const resolvers = {
  Query: {
    users: () => users,
    user: (_, { id }) => users.find(u => u.id === id)
  }
};

// 3๏ธโƒฃ ์„œ๋ฒ„
const server = new ApolloServer({
  typeDefs,
  resolvers
});

const { url } = await startStandaloneServer(server, {
  listen: { port: 4000 }
});

console.log(`๐Ÿš€ GraphQL Server ready at ${url}`);

๐Ÿ” API ์ฟผ๋ฆฌํ•˜๊ธฐ

๋ธŒ๋ผ์šฐ์ €์—์„œ http://localhost:4000 ๋ฅผ ์—ด๊ณ  ๋‹ค์Œ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค:

query {
  users {
    name
    role
  }
}

๊ฒฐ๊ณผ: ์š”์ฒญํ•œ ํ•„๋“œ๋งŒ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹คโ€”์ถ”๊ฐ€ ๋ฐ์ดํ„ฐ๋Š” ์—†์Šต๋‹ˆ๋‹ค.

โœ๏ธ ๋ฎคํ…Œ์ด์…˜ (๋ฐ์ดํ„ฐ ์ƒ์„ฑ / ์—…๋ฐ์ดํŠธ)

mutation {
  createUser(name: "Amit", role: "Frontend Dev") {
    id
    name
  }
}

๋ฎคํ…Œ์ด์…˜์€ GraphQL์—์„œ POST/PUT/DELETE์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ…ฐ๏ธ GraphQL with Angular (ํ”„๋ก ํŠธ์—”๋“œ๊ฐ€ ์‚ฌ๋ž‘ํ•˜๋Š” ์ด์œ )

  • ํ•„์š”ํ•œ ํ•„๋“œ๋งŒ ๊ฐ€์ ธ์˜ค๊ธฐ
  • API ํ˜ธ์ถœ ์ˆ˜ ๊ฐ์†Œ โ†’ UI ๋ Œ๋”๋ง ์†๋„ ํ–ฅ์ƒ
  • ๋ชจ๋ฐ”์ผ ์•ฑ ๋ฐ ๋ณต์žกํ•œ ๋Œ€์‹œ๋ณด๋“œ์— ์ด์ƒ์ 

์ธ๊ธฐ ์žˆ๋Š” Angular GraphQL ๋„๊ตฌ

  • Apollo Angular
  • GraphQL Code Generator
  • ๊ฐ•๋ ฅํ•œ TypeScript ์ง€์›

โœ… GraphQL์˜ ์žฅ์ 

  1. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ œ์–ดํ•˜๋Š” ๋ฐ์ดํ„ฐ โ€“ ํ•„์š”ํ•œ ๊ฒƒ๋งŒ ์ •ํ™•ํžˆ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
  2. ๋‹จ์ผ ์—”๋“œํฌ์ธํŠธ โ€“ ์—”๋“œํฌ์ธํŠธ ํญ๋ฐœ์ด ์—†์Šต๋‹ˆ๋‹ค.
  3. ๊ฐ•๋ ฅํ•œ ํƒ€์ž… ์Šคํ‚ค๋งˆ โ€“ ์ž๋™ ์™„์„ฑ, ๊ฒ€์ฆ, ํ–ฅ์ƒ๋œ ๊ฐœ๋ฐœ์ž ๊ฒฝํ—˜.
  4. ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ ์†๋„ ํ–ฅ์ƒ โ€“ ํ”„๋ก ํŠธ์—”๋“œ์™€ ๋ฐฑ์—”๋“œ๊ฐ€ ๋…๋ฆฝ์ ์œผ๋กœ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  5. ๋ณต์žกํ•œ UI์— ์ตœ์  โ€“ ๋Œ€์‹œ๋ณด๋“œ, ๋ชจ๋ฐ”์ผ ์•ฑ, ์‹ค์‹œ๊ฐ„ ์‹œ์Šคํ…œ ๋“ฑ์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

โŒ GraphQL์˜ ๋‹จ์  (์ค‘์š”!)

  1. ํ•™์Šต ๊ณก์„ ์ด ๊ฐ€ํŒŒ๋ฆ„ โ€“ ์Šคํ‚ค๋งˆ, ๋ฆฌ์กธ๋ฒ„, ์ฟผ๋ฆฌ ๋ฌธ๋ฒ•์ด ์ดˆ๋ณด์ž์—๊ฒŒ ์นœ์ˆ™ํ•˜์ง€ ์•Š์Œ.
  2. ์บ์‹ฑ์ด ์–ด๋ ค์›€ โ€“ REST๋Š” ๋‚ด์žฅ๋œ HTTP ์บ์‹ฑ์„ ํ™œ์šฉํ•˜์ง€๋งŒ, GraphQL์€ ๋งž์ถคํ˜• ์†”๋ฃจ์…˜์ด ํ•„์š”ํ•จ.
  3. ์ฟผ๋ฆฌ ๋ณต์žก๋„ โ€“ ๋ชจ๋‹ˆํ„ฐ๋ง๋˜์ง€ ์•Š์€ ์ž˜๋ชป๋œ ์ฟผ๋ฆฌ๋Š” ์„œ๋ฒ„์— ๊ณผ๋ถ€ํ•˜๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ์Œ.
  4. ๋‹จ์ˆœ CRUD API์— ์ ํ•ฉํ•˜์ง€ ์•Š์Œ โ€“ ๋‹จ์ˆœํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€์—์„œ๋Š” ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์ด์ ์„ ์ƒ์‡„ํ•  ์ˆ˜ ์žˆ์Œ.

๐Ÿšซ GraphQL์„ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ ๋˜๋Š” ๊ฒฝ์šฐ

  • ๋งค์šฐ ๊ฐ„๋‹จํ•œ CRUD API
  • HTTP ์บ์‹œ ์˜์กด๋„๊ฐ€ ๋†’์€ ๊ฒฝ์šฐ
  • ๊ทœ๋ชจ๊ฐ€ ์ž‘๊ฑฐ๋‚˜ ๊ฒฝํ—˜์ด ๋ถ€์กฑํ•œ ํŒ€
  • ๋ณต์žกํ•œ ํด๋ผ์ด์–ธํŠธโ€‘์‚ฌ์ด๋“œ ๋ฐ์ดํ„ฐ ์š”๊ตฌ์‚ฌํ•ญ์ด ์—†๋Š” ๊ฒฝ์šฐ

๐Ÿง  When GraphQL Is the BEST Choice

  • ์—ฌ๋Ÿฌ ํ”„๋ก ํŠธ์—”๋“œ ํด๋ผ์ด์–ธํŠธ(์›น, ๋ชจ๋ฐ”์ผ ๋“ฑ)
  • ๋‹ค์–‘ํ•œ ์†Œ์Šค์—์„œ ๋ฐ์ดํ„ฐ ์ง‘๊ณ„
  • ๋น ๋ฅธ UI ๊ฐœ๋ฐœ ํ•„์š”
  • ํ™•์žฅ ๊ฐ€๋Šฅํ•˜๊ณ  ๋ฐ์ดํ„ฐ ์ง‘์•ฝ์ ์ธ ์‹œ์Šคํ…œ ๊ตฌ์ถ•

๐Ÿ”ฅ GraphQL + Node.js ์Šคํƒ (ํŠธ๋ Œ๋”ฉ)

  • Node.js + TypeScript
  • NestJS / Apollo Server
  • Angular / React ํ”„๋ก ํŠธ์—”๋“œ
  • GraphQL Code Generator ๋ฅผ ์‚ฌ์šฉํ•œ ํƒ€์ž… ์•ˆ์ „์„ฑ
  • JWT + ์—ญํ•  ๊ธฐ๋ฐ˜ ์ธ์ฆ

Source: Source on Medium

๐Ÿ ์ตœ์ข… ์ƒ๊ฐ

GraphQL์€ REST๋ฅผ ๋Œ€์ฒดํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ์š”๊ตฌ์‚ฌํ•ญ๊ณผ ๋‹ค์ˆ˜์˜ ์†Œ๋น„์ž๊ฐ€ ์žˆ๋Š” ์ƒํ™ฉ์—์„œ ๋น›์„ ๋ฐœํ•˜๋Š” ๋ณด์™„์ ์ธ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

์ „์ฒด ์Šคํƒ Angularโ€ฏ+โ€ฏNode.js ๊ฐœ๋ฐœ์ž๋ผ๋ฉด, ํˆดํ‚ท์— GraphQL์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด ๋ณด์„ธ์š”.

์ด ๊ธ€์ด ๋งˆ์Œ์— ๋“œ์…จ๋‹ค๋ฉด, ๋ฐ•์ˆ˜๋ฅผ ์น˜๊ฑฐ๋‚˜, ๊ณต์œ ํ•˜๊ฑฐ๋‚˜, โ€œGRAPHQLโ€์ด๋ผ๊ณ  ๋Œ“๊ธ€์„ ๋‹ฌ์•„ ์ฃผ์„ธ์š”. ๋” ๊นŠ์€ Angularโ€ฏ+โ€ฏGraphQL ํŠœํ† ๋ฆฌ์–ผ์„ ์ œ๊ณตํ•ด ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

Back to Blog

๊ด€๋ จ ๊ธ€

๋” ๋ณด๊ธฐ ยป

์™œ GraphQL์€ ๋Œ€์ค‘ํ™”์— ์–ด๋ ค์›€์„ ๊ฒช๊ณ  ์žˆ์„๊นŒ? Under-Design์ธ๊ฐ€ Over-Design์ธ๊ฐ€?

I. GraphQL ์„œ๋น„์Šค ๊ฐœ๋ฐœ ๊ฐ„์†Œํ™” Zhipu Qingyan AI์—๊ฒŒ getBookById ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ GraphQL ์˜ˆ์ œ๋ฅผ ์ž‘์„ฑํ•ด ๋‹ฌ๋ผ๊ณ  ์š”์ฒญํ•˜๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค...