웹 프론트엔드와 백엔드가 데이터를 주고받기 위한 소통 수단이 바로 API(Application Programming Interface)다.
API는 클라이언트의 HTTP 요청을 백엔드 서버에 전달하고, 백엔드가 비즈니스 로직을 수행한 후 처리 결과를 다시 클라이언트에 돌려주는 연결 통로다.
함수에 비유하자면 다음과 같다.
| 비교 항목 | REST API | GraphQL API |
|---|---|---|
| 엔드포인트(URI) | 자원(Resource)마다 고유한 URI 엔드포인트 존재 (/users/1, /boards/10) | 단 하나의 엔드포인트(POST /graphql)로 모든 요청 처리 |
| 요청 구조 | HTTP Method(GET, POST, PUT, DELETE 등)로 행위 표현 | 일반 함수 호출 형태의 쿼리(query, mutation) 사용 |
| 응답 데이터 형태 | 백엔드에서 사전에 정의한 고정된 데이터 스키마 전부 수신 | 클라이언트가 쿼리에 명시한 필드만 선택적으로 수신 |
| 대표 통신 라이브러리 | axios, fetch | @apollo/client, urql, relay |
| 네트워크 캐싱 | HTTP 표준 캐싱 헤더(Cache-Control, ETag 등) 완벽 지원 | 대부분 단일 POST 요청이므로 별도의 클라이언트 정규화 캐시 필요 |
REST API
GET [https://api.example.com/users/1](https://api.example.com/users/1){
"name": "nate",
"height": "187",
"hair_color": "blond",
"skin_color": "fair",
"eye_color": "blue",
"gender": "male",
"study": [3, 4, 21, 23, 31],
"created": "2014-12-09T13:50:51.644000Z",
"edited": "2014-12-20T21:17:56.891000Z"
}
GraphQL API
POST [https://api.example.com/graphql](https://api.example.com/graphql)query {
user(userId: 1) {
name
height
gender
}
}
name, height, gender 필드만 정확히 반환된다.{
"data": {
"user": {
"name": "nate",
"height": 187,
"gender": "male"
}
}
}
GraphQL이 탄생하게 된 배경은 REST API의 오버패칭(Over-fetching)과 언더패칭(Under-fetching) 문제를 해결하기 위함이다.
name과 profileImage 두 개만 띄우면 되는데, /users/1 엔드포인트가 계좌번호, 주소, 생성일자 등 수십 개의 필드를 불필요하게 묶어서 반환하는 현상이다./users/1 호출로 유저 기본 정보 조회/users/1/posts를 다시 호출하여 게시글 목록 조회query {
user(userId: 1) {
name
email
boards {
id
title
contents
}
}
}
Type! : 해당 인자는 반드시 넘겨주어야 하는 필수값(Non-nullable)이다.[Type!] : 배열 내부의 요소가 존재한다면 반드시 null이 아닌 유효한 값이어야 함을 의미한다.query데이터를 순수하게 읽어올 때는 query 문을 사용한다. 실행할 쿼리 함수명 뒤에 인자값을 전달하고, 중괄호 안에 응답받고 싶은 필드 목록을 지정한다.
query fetchBoardsWithPage {
fetchBoards(page: 1) {
_id
writer
title
createdAt
}
}
mutation서버의 상태를 변경하는 작업(CUD: Create, Update, Delete)을 수행할 때는 mutation 문을 사용한다.
mutation createBoardInput {
createBoard(
createBoardInput: {
writer: "철수"
password: "password123"
title: "제목입니다"
contents: "내용입니다"
}
) {
_id
title
message
}
}
Cache-Control, 304 Not Modified)을 적극적으로 활용해야 할 때.