Back-End/GraphQL

[GraphQL] 1장. GraphQL의 탄생

Tinkies 2025. 2. 10. 01:01

 

2015년 마크 저키버그가 개발한 페이스북에서 GraphQL이 공개됩니다. 당시 공개적으로 발표된 데이터 질의어로 Rest 및 부속 웹서비스 아키텍처를 대체할 수 있습니다. GraphQL은 API를 더욱 빠르고 유연하고 개발자에게 친화적으로 만들기 위해 설계되었습니다.

https://2018.stateofjs.com/data-layer/graphql/

 

API 개발자는 GraphQL을 사용해 클라이언트가 서비스를 통해 쿼리할 가능성이 있는 모든 데이터를 설명하는 Schema(스키마)를 생성합니다 스키마는는 개체 유형으로 구성되어 어떤 종류의 개체를 요청할 수 있으며 어떠한 필드가 있는지 정의합니다. 

 

쿼리가 수신되면 GraphQL은 스키마에 대해 쿼리를 검증하고 그 다음 검증된 쿼리를 실행합니다. API 개발자는 스키마의 각 필드를 Resolver(리졸버)라고 불리는 기능에 첨부합니다. 실행 중 값을 생산하기 위해 리졸버가 호출됩니다.

 

GraphQL의 주요 특징

  • 단일 엔드 포인트
    • REST API는 각 리소스마다 별도의 엔드포인트가 필요하나, GraphQL은 단일 엔드포인트(/graphql)를 통해 모든 요청을 처리할 수 있다
  • 클라이언트 중심 데이터 요청
    • 클라이언트가 필요한 데이터의 구조와 필드를 정확하게 지정할 수 있다, 이를 통해 오버페칭(Over-fetching)과 언더페칭(Under-fatching) 문제를 해결
      • 오버페칭: 필요하지 않는 데이터까지 받는 문제
      • 언더페칭: 필요한 데이터를 얻기 위해 여러 번 요청해야 하는 문제 
  • 강력한 타입 시스템
    • GraphQL에서는 스키마를 통한 데이터의 타입을 명확하게 정의한다, 이를 통해서 개발자는 API의 구조를 쉽게 이해하고, 잘못된 요청을 방지할 수 있음
  • 실시간 데이터
    • 구독 기능(Subscription) 기능을 통한 실시간 데이터 업데이트를 지원함 (예: 실시간 채팅, 주식 시세)
  • 자동 문서화
    • GraphQL 스키마는 자동으로 문서화되고, 이를 통해서 개발자는 API 구조를 쉽게 탐색할 수 있음

GraphQL vs REST API

특징 GraphQL Rest API
엔드포인트 단일 엔드포인트( /graphql ) 리소스마다 별도 엔드포인트
데이터 요청 클라이언트가 필요한 데이터만 요청 고정된 데이터 구조
오버페칭 / 언더페칭 해결됨 발생 가능성 있음
실시간 데이터 구독(Subscription) 지원 일반적으로 미지원
타입 시스템 강력한 타입 시스템 타입 시스템 X

 

GraphQL을 사용하는 경우

  • 복잡한 데이터 요청
    • 여러 리소스의 데이터를 한 번에 요청할 때 유용
    • 예: 사용자 정보와 해당 사용자의 게시물, 댓글 등 
  • 모바일 애플리케이션의 경우
    • 네트워크 비용을 절약하기 위한 필요한 데이터만 요청
  • 실시간 애플리케이션
    • 실시간 채팅, 알림, 주식 시세 등 실시간 데이터 업데이트 시
  • 마이크로서비스 아키텍쳐
    • 여러 마으크로서비스의 데이터를 하나의 GraphQL API로 통합할 수 있음

GraphQL 장단점

  • 장점
    • 유연한 데이터 요청: 클라이언트가 필요한 데이터만 요청 가능 
    • 단일 엔드포인터: 모든 요청을 하나의 엔드포인트로 처리
    • 강력한 타입 시스템: API의 구조를 명확하게 정의
    • 실시간 데이터: 구독 기능을 통한 실시간 데이터 지원
  • 단점
    • 학습 곡선: REST API에 대한 기본적 이해 필요
    • 캐싱: REST API에 비해 캐싱이 복잡할 가능성 있음
    • 복잡한 쿼리: 너무 복잡한 쿼리는 성능 저하의 가능성

GraphQL 세팅하기

 

GraphQL을 기본적으로 세팅해보겠습니다. 환경은 Node.js를 기준으로 실행합니다. 우선 GraphQL을 세팅할 폴더를 하나 만들어줍니다. 

mkdir graphql-server 
cd graphql-server 
code .

 

GraphQL 서버를 구축하기 위해 필요한 패키지를 설치해줍니다. cmd를 열어서 아래 코드로 설치해줍니다.

npm install express-graphql graphql && yarn add express-graphql graphql
  • express: 웹 서버를 만들기 위한 프레임 워크
  • express-graphql: Express와 GraphQL을 연결해주는 미들웨어 서비스
  • graphql: GraphQL의 핵심 라이브러리

다음은 index.js를 생성해주고 아래 코드를 작성해 기본 서버 코드를 작성해줍니다.

const express = require("express");
const { graphqlHTTP } = require("express-graphql");
const { buildSchema } = require("graphql");

// GraphQL 스키마 정의
const schema = buildSchema(`
    type Query {
        hello: String  
    }    
`);

// Resolver 함수 정의
const root = {
  hello: () => "Hello World GraphQL!",
};

// Express 서버 생성
const app = express();

// GraphQL 미들웽 ㅓ 생성
app.use(
  "/graphql",
  graphqlHTTP({
    schema: schema,
    rootValue: root,
    graphiql: true, // GraphQL 도구 활성화
  })
);

// 서버 실행
app.listen(4000, () => {
  console.log("GraphQL Server http://localhost:4000/graphQL ! Success");
});
const express = require("express");
const { graphqlHTTP } = require("express-graphql");
const { buildSchema } = require("graphql");

// GraphQL 스키마 정의
const schema = buildSchema(`
    type Query {
        hello: String  
    }    
`);

// Resolver 함수 정의
const root = {
  hello: () => "Hello World GraphQL!",
};

// Express 서버 생성
const app = express();

// GraphQL 미들웽 ㅓ 생성
app.use(
  "/graphql",
  graphqlHTTP({
    schema: schema,
    rootValue: root,
    graphql: true, // GraphQL 도구 활성화
  })
);

// 서버 실행
app.listen(4000, () => {
  console.log("GraphQL Server http://localhost:4000/graphQL ! Success");
});

 

node를 사용해서 서버를 실행해봅니다. 실행하면 http://localhost:4000/graphql로 접속하면 GraphQL 인터페이스가 나타납니다

 

localhost:4000 으로가면 grpahql playground 가 실행됩니다. hello를 입력해서 재생버든을 클릭하면 "Hello World GraphQL!"을 반환합니다.

 

GraphQL 스키마 확장

기본적인 hello 쿼리 외 더 복잡한 스키마를 정의할 수 있습니다. vsCode로 돌아가서 다음과 같은 코드를 작성해줍니다.

const schema = buildSchema(`
    type Query {
        hello: String  
        user(id: ID!): User
    }   
    type User {
        id: ID!
        name: String!
        age: Int!
    }
`);

const users = [
  { id: "1", name: "Koras02", age: 27 },
  { id: "2", name: "Bruce", age: 35 },
];

// Resolver 함수 정의
const root = {
  hello: () => "Hello World GraphQL!",
  user: ({ id }) => users.find((user) => user.id === id),
};

 

그다음 GraphQL에서 실행해봅니다.

{ 
   user(id: "1") {
    name 
    age
  }
}

 

LIST