프로그래밍 공부하기

GraphQL 1 - 소개 본문

Web/[JS] Common

GraphQL 1 - 소개

ihl 2021. 2. 12. 22:26

  웹에서 데이터를 요청하고 처리하는 가장 대표적인 방식은 REST이다. RESTful 아키텍처란 데이터 처리를 크게 GET, PUT, POST, DELETE로 나누고(Method) 사용자가 어떤 데이터(URL)에 어떤 처리(Method)를 원하는지 요청하여 서버가 이를 제공하는 방식이다. 사용자가 요청할 때마다 필요한 정보를 제공하므로 쿠키, 세션에 정보를 저장할 필요가 없다. 최근 데이터 처리량이 증가하면서 REST 방식을 대체할 수 있는 Graph QL이라는 방식이 대두되고 있다.

 

1. REST와 GraphQL

  최근 컴퓨터 뿐만 아니라 모바일, 모든 사물에서 웹에 접근 가능해 지면서 서버에는 점점 많은 데이터 요청이 들어오게 되었다. 이 때 REST 방식의 경우 데이터 요청방식과 응답방식이 정해져 있기 때문에 오버페칭과 언더페칭이 발생한다.

 

  오버페칭이란 서버가 사용자가 요청한 데이터 범위를 초과하는 데이터를 제공하는 것이다. 예를 들어 사용자가 오늘 날씨를 조회한다고 생각해보자. 이 요청에 대해 REST는 날씨 뿐만 아니라 습도, 풍향, 기압 등 불필요한 정보도 제공해준다. 반대로 언더페칭은 원하는 데이터를 얻기 위해 데이터 요청을 2번 해야하는 상황이다. 예를 들어 우리 동네 관광지와 관광지에 가는 교통수단을 조회한다고 생각해보자. 이 요청을 처리하기 위해선 먼저 우리 동네 관광지에 대한 요청을 한 후 교통수단에 대한 요청을 추가적으로 수행해주어야 할 것이다.

 

  GraphQL은 마치 DataBase에 SQL 쿼리문으로 필요한 정보만 한 번에 가져오는 것 처럼 서버에 필요한 정보만 한 번에 요청할 수 있다. 따라서 REST와 달리 불필요한 데이터 혹은 추가적인 요청 없이 한 번에 데이터를 처리할 수 있는 것이다.

 

  REST에서는 URL을 통해 특정 데이터에 접근하게 된다. 즉, 같은 데이터에 대해 추가할 때와 조회할 때 같은 URL을 사용한다는 것이다. 이 때 같은 URL에 대해서라도 다른 처리(Get, Put, Post, Delete)를 하게끔 구별해주는 것이 EndPoint이다. 따라서 REST 에서는 여러 EndPoint를 갖게 된다. 또한 사용자의 요구에 따라 새로운 엔드포인트를 만들어야 하는 상황이 발생한다. 그러나 GraphQL은 필요한 정보만 추출할 수 있으므로 하나의 엔드포인트에서 모든 요청을 처리할 수 있다.

 

  서버를 구성할 때 REST와 GraphQL 둘 중의 하나로만 구성할 필요는 없다. 각자의 장점이 있기 때문에 요청이 서로 다른 모양으로 올 가능성이 높은 경우는 GraphQL 그렇지 않은 경우는 REST를 사용하면 된다. 단, 하나의 리소스 처리를 위해 두 구조를 섞어놓는 것을 지양하여야 한다. 예를 들어 사용자 정보 등록은 RESTful API로, 사용자 정보 수정은 GraphQL API를 사용하는 것과 같이 말이다.

 

 

2. 간단한 실습

npm install graphql-yoga
npm install @babel/core @babel/cli @babel/node @babel/preset-env --save-dev

간단한 GraphQL 서버를 만들어보자. GraphQL을 사용하기 위해서 graphql-yoga를 설치하고, es6 문법을 사용하기 위해 babel을 설치한다.

 

{
  "presets": ["@babel/preset-env"]
}

프로젝트 내에 .babelrc 파일을 생성하여 위와 같이 설정한다.

 

"scripts": {
    "start": "nodemon --exec babel-node index.js",
  }

서버를 실행할 때 babel-node를 사용하여 프로그램을 실행시켜야 한다. 명령어가 너무 길다면 위와 같이 package.json에 설정하고 npm start 로 실행할 수 있다. 나의 경우 node.js의 변동사항을 바로 적용하여 재실행 시켜주는 nodemon 도 설치하여 package.json에 설정하였다.

 

 

#graphql > schema.graphql
type Query {
  name: String!
}

먼저 GraphQL로 어떤 타입의 데이터를 줄 것인지 스키마를 설계해보자. 프로젝트 내에 graphql이라는 폴더를 만들고 아래 schema.graphql 이라는 파일을 만든 뒤 위와 같이 적는다. 위 코드에서 Query라는 것은 그래프에서 root 노드와 비슷한 의미이다. 따라서 보통 루트와 다양한 데이터 영역들과 일대다 관계를 갖고 있으며 GraphQL에서 반드시 필요한 타입이다. (없으면 오류가 발생한다) 

 

나는 name이라는 쿼리 요청을 만들기 위해 root인 Query에 name이라는 필드를 추가하였고, String타입으로 주었으며, 마지막에 !를 붙여 null 값을 허용하지 않는다는 것을 명시하였다. String 외에도 Int, Float, Boolean, ID 타입이 있으며, 사용자가 커스텀하여 타입을 만들 수도 있다. 또한 보편적으로 사용되는 커스텀 데이터 타입을 정의한 graphql-custom-type라는 npm 모듈을 설치하여 사용할 수도 있다.

 

 

//graphql > resolvers.js
const resolvers = {
  Query: {
    name: () => "ImHyeLim!"
  }
}

export default resolvers;

이제 요청에 대한 실제 값을 반환하는 리졸버를 만들어보자. graphql 폴더 내에 resolvers.js 파일을 만든 후 위와 같이 작성한다. 리졸버는 스키마에 정의된 타입과 형태에 따라 데이터를 반환해야한다. 리졸버를 별개의 파일에 만든 경우 export를 통해 다른 파일에서 쓸 수 있도록 해야한다.

 

 

//es6 문법
import { GraphQLServer } from "graphql-yoga"
import resolvers from "./graphql/resolvers"

const server = new GraphQLServer({
  typeDefs: "graphql/schema.graphql",
  resolvers
});
server.start(() => console.log('Server is running on localhost:4000'));

마지막으로 서버를 작성해보자. 프로젝트에 index.js 를 만든 후 위와 같이 작성한다. 먼저 설치한 graphql-yoga 를 이용하여 GraphQLServer를 만든 후, 이전에 작성한 스키마와 리졸버 파일을 가져와 서버 작성 시 인자로 넣어준다. 이제 서버를실행시킨 후 localhost:4000 에 접속해보자.

 

 

localhost:4000

localhost:4000에 가면 playground라는 페이지가 보인다. playground는 postman과 비슷한 툴로, GraphQL 쿼리를 보내면 서버로부터 응답을 받을 수 있다. 위와 같이 쿼리를 날려보면 내가 정의한 데이터 응답을 받을 수 있다.

 

 


 

참고 사이트

www.holaxprogramming.com/2018/01/20/graphql-vs-restful-api/

 

GraphQL과 RESTful API

GraphQL vs Restful API?

www.holaxprogramming.com

 

 

graphql-yoga로 GraphQL 시작하기

이번 포스팅은 GraphQL에 대한 심도있는 이야기보다 GraphQL을 이용한 back-end setup에 대한 부분을 다루고 있습니다. GraphQL과 graphql-yoga에 대해 좀더 자세히 알고 싶으신 분은 하단의 GraphQL 공식 웹사이

code0xff.tistory.com

youtu.be/3PZGW5Iwtv4

'Web > [JS] Common' 카테고리의 다른 글

GraphQL 3 - Mutation  (0) 2021.02.13
GraphQL 2 - 데이터 조회  (0) 2021.02.13
Callback / Promise / Async & Await  (0) 2021.02.06
정규표현식  (0) 2021.01.31
VS에서 JavaScript 디버깅하기(Console)  (0) 2021.01.19
Comments