본문 바로가기
FE/Javascript

REST-API vs GraphQL-API

by ideal_string 2022. 9. 2.

API(Application programing interface)는 애플리케이션이나 디바이스 간 통신(연결) 방법을 정의하는 규칙(언어 혹은 메세지)이다. API는 프론트엔드든 백엔드든 빼놓을 수 없는 웹개발의 핵심이라 감히 불러본다. API가 없다면 프론트엔드는 껍데기뿐이고, 백엔드는 바퀴없는 자동차다. 서버 데이터베이스에서 값을 가져와 화면에 뿌리고, 화면에 있는 입력값을 다시 데이터베이스에 저장하는 사이에 API가 있기 때문이다. API 중에서는 REST-API가 오랜 기간, 많은 사람들이 사용해왔고, GraphQL-API는 비교적 최근에 등장했다.

REST-API

REST-API는 REST(REpresentational State Transfer) 아키텍처 스타일의 디자인 원칙을 준수하는 API다. 디자인을 강조하다보니 RESTful API라고도 불리며, 'RESTful하다'는 표현은 원칙에 따라 잘 작성한 API라고 하는 칭찬과 같다. REST의 기본 개념은 리소스다. 리소스는 잘 정의된 상태와 관계, 표준화된 작동 방식과 형식으로 전송되는 문서들이라고 볼 수 있다.

REST 디자인 원칙

디자인 원칙은 여섯가지다. 1️⃣ 동일한 인터페이스(Uniform Interface). 요청을 어디에서 하든 똑같은 리소스를 요청한다면 모든 API 요청은 동일하게 보여야한다. 2️⃣ 클라이언트-서버 디커플링. 클라이언트와 서버는 서로 완전히 독립적이어야 한다. 클라이언트는 URI만 알고 있으며 다른 방법으로는 서버와 상호작용할 수 없다. 3️⃣ 무상태(Stasteless). 각 요청에서 처리에 필요한 모든 정보를 포함해야한다. 쿠키와 세션을 필요로 하지 않기 때문이다. 직접 오브젝트에 접근해 서비스를 처리해 자유도가 높고 유연한 아키텍처를 적용할 수 있다. 4️⃣캐싱 가능성. 서버 응답 시 응답이 클라이언트가 캐시 가능 여부를 알려주어야 한다. 그 반대도 마찬가지. 이는 성능 향상을 얻고자 함이다. 5️⃣ 계층 구조 아키텍처. REST-API는 호출과 응답이 서로 다른 계층을 통과한다. 따라서 클라이언트와 서버가 무조건 직접 연결된다고 생각하는 건 무리(proxy, gateway 등을 사용할 수 있음). 중개자가 있더라도 서버와 클라이언트는 모르게 설계해야 한다. 6️⃣ 주문형 코드(Code on demand). 클라이언트가 서버에서 코드를 다운받아 기능을 확장하는 것으로 선택사항이다. REST-API는 보통 정적 리소스를 전송하지만, 응답에 실행 코드를 포함할 수도 있다. 이때 코드는 요청할 때만 실행하도록 할 수 있다.

REST-API 작동방식

REST-API는 HTTP 요청으로 서버(리소스)에 접근하며, 레코드를 생성(CREATE), 읽기(READ), 수정(UPDATE), 삭제(DELETE)해 표준 데이터베이스 기능을 수행한다. 앞글자를 따 CRUD라고 표현하기도 한다. 메서드로는 GET(검색 및 읽기), POST(생성 혹은 작성), PUT(수정), DELETE(삭제)가 있다. 

클라이언트와 서버가 데이터를 주고 받을 때 HTML, XLT, Python, PHP 또는 일반 텍스트를 포함하여 실제로 거의 모든 형식을 주고 받을 수 있다 다만, 그중 JSON(JavaScript Object Notation)이 기계와 사람이 모두 이해할 수 있어서 인기가 많아졌고, Rest-API로 이뤄지는 통신은 JSON으로 이루어지고 있다고 해도 무방할 정도다. 즉 클라이언트에서 서버에 보낼 정보를 JSON으로 전환해 서버에 보내고, 서버에서는 JSON으로 받아 다시 원상태로 돌려 사용한다. 서버에서 클라이언트로 보낼 때도 클라이언트는 JSON으로 받아 원상태로 돌려 사용한다. (JSON을 쉽게 말하면 문자열로 변환하는 기능이며, 정확하게는 Javascript 객체 문법으로 구조화된 데이터를 표현하기 위한 문자 기반의 표준 포맷이다.)

async function postData(url = '', data = {}) {
  const response = await fetch(url, {
    method: 'POST', 
    headers: {
      'Content-Type': 'application/json',
      // 'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: JSON.stringify(data), // body의 데이터 유형은 반드시 "Content-Type" 헤더와 일치해야 함
  });
  return response.json(); // JSON 응답을 네이티브 JavaScript 객체로 파싱
}

postData('https://example.com/answer', { answer: 42 }).then((data) => {
  console.log(data); // JSON 데이터가 `data.json()` 호출에 의해 파싱됨
});

위는 fetch를 이용해 Rest-API를 통신하는 코드다. 먼저 헤드를 보자. method가 post로 서버에 데이터를 등록해달라고 요구한 것을 볼 수 있다. content-type은 데이터를 어떤 유형으로 주고 받을 것인가를 설정하는 것으로 여기서는 JSON으로 하겠다고 설정한 것. 바디에서 JSON.stringify(data)는 data를 JSON 형식으로 바꿔 보내겠다는 의미다. 리턴에서 response.json()은 서버로부터 JSON 형식으로 받은 값을 다시 원상태로 파싱함을 뜻한다. 

REST-API는 데이터 요청 시 요청에 관한 모든 데이터를 다 받아야 한다. 특정 데이터만 골라 받을 수 없다. 이는 불필요한 데이터까지 주고받을 수 있는 여지가 생긴다.

장점 단점
# HTTP 프로토콜 인프라를 그대로 사용하기 때문에  REST API 사용을 위한 별도 인프라 구축이 필요 없다.
# HTTP 프로토콜 표준을 최대한 활용해 추가 장점을 함께 사용할 수 있다.
# HTTP 표준 프로토콜을 따르는 모든 플랫폼에서 사용할 수 있다.
# Hypermedia API 기본에 충실하면서 범용성을 보장한다.
# REST-API 메세지가 의도하는 바를 명확하게 나타내 의도하는 바를 쉽게 파악할 수 있다.
# 여러가지 서비스 디자인에서 생길 수 있는 문제를 최소화 한다.
# 서버와 클라이언트를 명확하게 분리한다.
# 표준이 없다.
# 사용할 수 있는 메소드가 4가지다(메소트 형태가 제한적).
# 브라우저 테스트가 많다면 URL보다 HEADER값이 더 어려울 수 있다.
#PUT, DELETE 혹은 pushState를 사용하지 못하거나 지원하지 않는 브라우저도 있다.

 

GraphQL-API

GraphQL-API는 페이스북에서 수많은 데이터 처리 시 REST-API보다 더 빠르게 정보를 주고받고자 만든 쿼리 언어다. 프론트엔드 입장에서 보자면 REST-API 대비 처리 방법이 쿼리(QUERY)와 변형(MUTATION) 두 가지로 단순하다는 게 먼저 다가온다. 더불어 한 번의 요청으로 가져오고 싶은 데이터만 정확하게 가져올 수 있는 쿼리를 보낼 수 있어 편리하다.

JSON으로 데이터를 주고 받는다는 점에서는 REST-API와 동일하다. 다만 GrapQL-API이 최근에 나온만큼 REST-API의 아쉬운 점을 보완하고 있다. 정적으로 타입을 지정하기 때문에 사용 전에 변수를 정의하지 않아도되고, 데이터를 과도 혹은 과소하게 가져올 필요가 없기에 대역폭을 절약할 수 있다. 긴 주소 대신 함수로 단순하게 쿼리를 작성할 수 있다.

작동방식

GraphQl-API는 REST-API와 마찬가지로 HTTP 요청으로 서버에 접근한다. 위에서 언급한 바 메소드가 쿼리와 변형 뿐이다. REST-API와 비교 시 QUERY는 GET, MUTATION은 POST, PUT, DELETE와 같다.

const CREATE_BOARD = gql`
  mutation createBoard($writer: String, $title: String, $contents: String) {
    createBoard(writer: $writer, title: $title, contents: $contents) {
      _id
      number
      message
    }
  }
`;

위 코드는 React에서 apollo를 이용해 GraphQL-API하는 일부분이다. mutataion으로 데이터를 주고 받고 있다. 서버에 만들어 둔 createBoard라는 함수를 mutation을 통해 게시글을 등록하고, 반환 값으로 여러가지중 _id, number, message만 받겠다고 선언한 모습이다. 글을 수정하고 싶다면  'mutation updateBoard...'처럼 서버에서 만들어둔 글 수정함수를 다시 요청하면 된다.

const FETCH_BOARD = gql`
  query fetchBoard($number: Int) {
    fetchBoard(number: $number) {
      writer
      title
      contents
    }
  }
`;

데이터를 불러올 때는 query로 불러오며, 반환 값을 기재해 클라이언트측에서 원하는 값만 가져왔다. 

장점 단점
# 릴레이 및 클라이언트 프레임워크 제공
# 모바일 앱 성능 향상에 도움
# 한번의 요청으로 원하는 데이터 가져올 수 있어서 overfetching이나, underfetching 문제가 없음
# 기종과 상관없이 사용할 수 있음
# 하나의 URL로 처리하기에 HTTP에서 제공하는 캐싱 전략을 그대로 쓸 수 없음
# file 전송 등 text 이외 내용 처리가 복잡
# 재귀적인 Query가 불가능하다

 

 

비교

REST-API Graph-API
 - 읽기(READ), 생성(CREATE), 수정(UPDATE), 삭제(DELETE)를 각각 메소드 사용 - 쿼리(QUERY)와 변형(MUTATION) 두 가지 메소드
- API 주소별 접근 - API 함수로 접근
- 서버 중심 아키텍처 - 클라이언트 중심 아키텍처
- 모든 플랫폼에서 일관성을 유지하기 어려움 - 모든 플랫폼에서 높은 일관성을 제공함
- 엔드포인트가 여러개 - 엔드포인트는 하나
- 기계가 읽을 수 있는 메타데이터를 캐시할 수 없음 - 쿼리 유효성 검사를 위해 메타데이터 사용
- API 문서 별도 기술 - API 변경 사항과 동기화된 문서를 자동으로 유지
- 구축하고 적용하기 쉬움 - 작은 응용프로그램에는 과도할 수 있음
- 디자인 원칙만 있고, 구체적인 지침은 없음 - 사용 지침서 있음

REST API와 GraphQL API의 사용 (이미지 출처 : https://blog.apollographql.com/graphql-vs-rest-5d425123e34b)

결론

페이스북, 인스타, 유튜브 같이 대용량 데이터를 주고 받는 서비스가 아니라면, 일반인이 두 API의 속도차이를 느끼기 어렵다. 무엇이 무조건 낫다고 볼 수 없는 점이다. 다만, REST-API에서는 프론트엔드 프로그래머가 백엔드 프로그래머가 작성해 전달한 API 문서의 request와 reponse형식을 의존해야만 하고, GraphQL-API 사용 시 해당 의존도는 낮아진다. 프론트엔드 프로그래머 입장에선 약간의 자유가 생긴 느낌이라고 볼 수 있다. 그런 점에서 데이터를 사용하기에 GraphQL-API가 수월해 보인다. 그렇다고 벡엔드 프로그래머가 작성한 스키마를 무시할 수 없음을 기억해야 한다.

 

※ 잘못된 내용이 있을 경우 댓글로 알려주세요. 배우고 익히고 수정하겠습니다:)

'FE > Javascript' 카테고리의 다른 글

try & catch  (0) 2022.09.06
async & await  (0) 2022.09.05
Template literals  (0) 2022.08.31
함수 선언식, 표현식, 화살표 함수의 공통점과 차이점  (0) 2022.08.14
'getElementById' VS 'querySelector'  (0) 2022.08.08