REST API와 GraphQL 차이점

 

01. REST API

REST API는 자원을 조작하는 방법(Method)와 URI를 통해 정의한다. 즉, HTTP 요청 방식(GET, POST, PUT, DELETE)을 사용하여 데이터를 요청하고 응답받는다. 이때, 상황에 따른 Method를 사용해야 하고 api 별로 각각의 end point를 갖는다.

 

 

#1. REST API의 2가지 구성요소

◼︎ Method

: 동사(어떤 행위를 할 것인지). 자원에 대한 작업을 정의(GET, POST, PUT...)

 

◼︎ URI(URL)

: 명사(어떤 자원에 대해). 자원을 고유하게 식별하는 주소

URI와 URL 차이점
- URI : 자원이 실제로 존재하는 위치, 장소를 가리킴. (https://example.com)
- URL: URI의 하위 개념으로, 정확한 위치 정보를 표시. (https://example.com/users/resources)

 

 

<URI 구성>

/collection/document(id)/store/ - 총 4가지 요소로 구성

 

  • Collection: Document의 상위 디렉터리 리소스
  • Document: Collection 내 단일 리소스
  • Store: 리소스의 다른 표현
  • Controller: 표현 가능한 Method(CRUD) 제외한 행위 명시. /register와 같이 post 표현을 강화하는 것처럼 Method 의미를 강화하기 위해 사용

controller 등으로 표현할 수 없을 때는 uri 변수(가변 변수)를 사용한다. 예를 들어, 카테고리의 경우 언제든지 변경 가능하므로 변수로 사용하기에 적합하다. 변수에는 아래와 같이 두가지가 존재한다.

  • Path 변수 : /hello/word
  • Query Parameter : /hello?next=world와 같이 ?로 표현

 

 

#2. HTTP 상태 코드

1xx 정보성 응답
2xx 성공
3xx 리다이렉션
4xx 권한 혹은 잘못된 접근
5xx 서버 내부 문제

 

 

 

#3. REST API 단점

◼︎ Data under-fetching / n+1 fetching

한 번의 요청으로 필요한 데이터를 가져오지 못해 여러 번 요청해야 하는 문제점이 있다.

 

◼︎ Data over-fetching

필요한 데이터 이상의 데이터를 가져오게 되는 단점이 있다.

 

◼︎ All-or-nothing 응답

에러가 발생하면 어떤 데이터도 받을 수 없다. 데이터를 요청하면 데이터를 응답받거나 아예 응답받지 못하는 경우 둘 중 하나이다.

에러에 대한 상태 코드 메시지는 받아도 데이터를 받을 수는 없다.

 

◼︎ 일괄 처리 어려움

 

 

 

02. Graph QL

GraphQL은 앞선 REST API의 단점 및 REST API의 각 비즈니스 도메인마다 수많은 API를 일일이 만들어야 하는 단점을 해결한다.

GraphQL은 필요한 데이터를 정확하게 요청하고 엔티티 사이 연결을 활용해 한 번의 요청만으로 관계를 확인한다.

어떤 데이터를 가져오는데 실패해도 GraphQL은 가져오는데 성공한 데이터는 보여준다.

또한 한 번의 요청만으로 여러 개의 연산을 그룹화하는 것을 가능하게 하여 모든 데이터를 가져오게 될 경우 왕복 통신 횟수를 줄여 어플리케이션의 속도를 높인다.

 

클라이언트를 위해 단일 게이트웨이를 생성하여 데이터를 가져오는 방법에 대한 팀 통신 장애를 줄이기도 한다. 이때 단일 게이트웨이는 하나의 GraphQL 엔드포인트를 통해 데이터를 가져올 수 있다는 의미이다.

즉, HTTP 요청 방식 사용하지만 POST만 사용하고 단일 end point를 사용한다. 이때 요청시 body에 스키마에 맞춰 쿼리를 사용해 요청하기 때문에 일관성 있는 통신이 가능하다.

 

장점)

클라이언트는 GraphQL 서버로 쿼리를 전송하면 서버는 해당 쿼리를 해석하고 데이터를 변환한다.

이때 클라이언트가 요청한 필드만 반환되므로 overfetching을 줄여 효율적이다.

GraphQL은 스키마를 사용하여 데이터 모델을 정의하기 때문에 클라이언트와 서버간 일관성 있는 데이터 통신을 보장한다.

 

 

 

 

03. REST API vs. GraphQL

앞선 REST API와 GraphQL의 호출 방식 및 차이점을 요약하면 다음과 같다.

 

💡REST API

  • 각 CRUD 작업마다 고유의 엔드포인트가 필요하며, 각 작업은 해당 엔드포인트를 통해 수행된다.
  • 클라이언트는 엔드포인트별로 요청을 전송하고, 서버는 해당 엔드포인트에서 처리된 결과를 반환한다.
  • 데이터 타입, 반환되는 데이터 구조를 명시적으로 통제하기 어렵고, 요청된 데이터 외에도 추가 데이터를 반환할 수 있는 overfetching이 발생되는 문제점이 있다.

💡GraphQL

  • 단일 엔드포인트(/graphql)을 통해 모든 CRUD 작업이 이루어진다.
  • 클라이언트는 쿼리 또는 뮤테이션을 사용하여 요청을 정의하고, 서버는 명세된 데이터만 반환한다.
  • 클라이언트는 요청할 데이터의 구조와 타입을 명확히 정의하여 데이터 일관성을 유지할 수 있다.
GraphQL에서의 작업 종류
- 쿼리(Query): 데이터를 읽어오는 작업을 수행한다. 
- 뮤테이션(Mutation): 데이터를 변경하는 작업을 수행한다. 예를 들어, 데이터를 추가, 데이터 정보를 수정, 특정 데이터를 삭제할 때 사용된다.

 

 

다음으로 프론트엔드에서 rest api와 graphql을 호출할 때 요청 방식이 어떻게 다른지 알아보아 두 방식의 차이점을 알아보고자 한다.

이때 User라는 data에 대해 CRUD API를 호출하는 방식으로 간단한 예시를 보고자 한다.

  • REST API의 경우 아래와 같은 4개의 end point가 필요하고 client <-> server 간 data type을 명시적으로 보여줄 수 없다.
    • [GET] /api/v1/user
    • [POST] /api/v1/user
    • [PUT] /api/v1/user/:id
    • [DELETE] /api/v1/user/:id
  • GraphQL의 경우 아래와 같은 1개의 end point만 사용하고 client <-> server간의 data 일관성을 유지할 수 있다.
    • [POST] /graphql

 

 

#1. REST API 호출 방식

REST API에서는 각 CRUD 작업에 대한 별도의 엔드포인트가 필요하다. 각각의 엔드포인트는 특정 작업을 수행하며, 클라이언트는 각 작업에 대한 명시적인 요청을 서버에 보내야 한다.

 

◼︎ get 요청

fetch('/api/v1/user') //get 요청을 보낼 api 주소 지정
  .then(response => response.json())  // get 요청으로 데이터 json으로 받아오기
  .then(data => console.log(data))  //get 요청으로 받은 데이터 콘솔에 출력
  .catch(error => console.error('Error:', error));  //get 요청 실패시 발생되는 에러 출력

 

 

◼︎ post 요청

fetch('/api/v1/user', {		//post 요청 보낼 api 주소 지정
  method: 'POST',	//post요청
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({	// post요청으로 보낼 데이터
    name: 'guswjd',
    email: 'guswjd@example.com',
  }),
})
  .then(response => response.json())
  .then(data => console.log('User Created:', data))  //post 요청 보낸 데이터 출력
  .catch(error => console.error('Error:', error));  //에러 발생시 출력

 

 

 

#2. GraphQL 호출 방식

GraphQL에서는 단일 엔드포인트(/graphql)를 사용하여 모든 CRUD 작업을 수행할 수 있다. 클라이언트는 어떤 데이터를 요청하거나 수정할지 명시적으로 쿼리 혹은 뮤테이션을 정의하면 된다.

 

◼︎ READ - 정보 조회

const query = `  //사용자 데이터 중 id, name 데이터만 조회하기 위한 쿼리 작성
  query {
    users {
      id
      name
    }
  }
`;

fetch('/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ query }),
})
  .then(response => response.json())
  .then(data => console.log(data.data.users))
  .catch(error => console.error('Error:', error));

 

 

◼︎ CREATE - 데이터 생성/추가

const mutation = ` // 새로운 name, email 데이터 값 추가
  mutation {
    createUser(input: { name: "guswjd", email: "guswjd@example.com" }) {
      id
      name
      email
    }
  }
`;

fetch('/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ query: mutation }),
})
  .then(response => response.json())
  .then(data => console.log('User Created:', data.data.createUser))
  .catch(error => console.error('Error:', error));

 

 

 

정보 조회, 생성할 때 api 호출만으로 예시를 보아도 rest api는 api 요청 주소가 다른 것을 알 수 있는데 graphql은 똑같은 주소로 요청한 것을 확인할 수 있다. 또한 graphql은 쿼리를 통해 원하는 데이터 정보만 요청하는 것도 가능하였다.

 

 

 

 

❓❓GraphQL를 호출할 때 REST API와 다르게 정보를 추가, 생성할 때만이 아닌 정보를 조회할 때도 post 요청 메소드를 쓰는 것 같은데 이 부분은 고민 후 나중에 정리하여 포스팅을 수정하겠다 ❓❓

 

 

 

 

 


이외에도 GraphQL의 스키마, 타입, resolver 등의 개념에 대해 더 깊게 알고싶다면 아래 블로그를 참고하는 것도 좋을 것 같다.

https://devocean.sk.com/blog/techBoardDetail.do?ID=164787#none

 

GraphQL에 대하여 (장점 & Schema & Type)

 

devocean.sk.com

https://tech.kakao.com/posts/364

 

GraphQL 개념잡기 - tech.kakao.com

GraphQL은 페이스북에서 만든 쿼리 언어입니다. GrpahQL은 요즘 개발자들...

tech.kakao.com

 

반응형