회사에서 사내용 SDK를 갈아엎고 있는 중이다. 그 당시엔 사내 전체 프로젝트가 HTTP통신 라이브러리로 Axios를 쓰고 있었기 때문에, SDK도 Axios를 기반으로 만들었다. 하지만 시간이 지나고,, ky를 쓰는 팀이 생기고, 순수 fetch 에 대한 지원 요청도 들어왔다.
모든 프로젝트에 대응 가능하게 만들려면, 각 라이브러리의 특징도 알아야겠더라. Axios를 오랫동안 써오면서 'API 통신 라이브러리' 정도로만 이해하며 사용하고 있었는데, 이번 기회에 확실히 머릿속에 개념을 새기고 가보려고 한다.
웹 서버와 통신할 수 있는 방법에는 위 마인드맵에서 처럼 4가지가 있다. 그런데 gpt한테 다시 물어보니 정확히는 저런 계층은 아니다
📂 웹 서버 통신 방식
├── 📂 HTTP
│ ├── 📄 일반 HTTP 요청 (Request-Response)
│ │ ├── ✅ Axios, Ky, Fetch 지원
│ │ ├── ✅ 단일 요청 - 단일 응답 방식
│ │ └── ✅ REST API 요청 처리
│ ├── 📂 SSE (Server-Sent Events)
│ │ ├── ✅ 단방향 스트리밍 (서버 → 클라이언트)
│ │ ├── ✅ HTTP 기반 (text/event-stream)
│ │ ├── ✅ EventSource API 사용
│ │ └── ✅ Fetch Stream 활용 가능
│ └── 📄 gRPC (HTTP/2 기반)
│ ├── ✅ RPC(Remote Procedure Call) 방식
│ ├── ✅ 다양한 통신 패턴 지원
│ │ ├── Unary (단일 요청-응답)
│ │ ├── Server Streaming (서버 → 클라이언트 다중 응답)
│ │ ├── Client Streaming (클라이언트 → 서버 다중 요청)
│ │ ├── Bidirectional Streaming (양방향 스트리밍)
│ ├── ✅ gRPC 라이브러리 사용
│ └── ✅ HTTP/2 최적화
├── 📂 WebSocket
│ ├── ✅ 양방향 실시간 통신 (Full-Duplex)
│ ├── ✅ ws:// 또는 wss:// 프로토콜 사용
│ ├── ✅ 상태 유지 (Persistent Connection)
│ ├── ✅ Binary 데이터 전송 가능
│ ├── ✅ 실시간 채팅, 게임, 스트리밍에 활용
│ └── ✅ WebSocket API 또는 Socket.io 사용
웹소켓/ HTTP 통신 방식으로 먼저 나뉘고, HTTP 통신 방식 하위에 일반 HTTP 요청, SSE(Server-Sent Events), gRPC 가 있는 형태이다. 나는 오늘 통신방식을 파볼 건 아니기 때문에 가볍게 넘어가본다.
우리가 보통 웹 개발할 때 라이브러리를 사용해서 API통신을 하는 부분은 '일반 HTTP 요청' 에 한한다.
'일반 HTTP 요청' 이 무엇인가 하면 단일 요청-응답(One-time Request-Response) 방식을 이라는 거다.
즉 클라가 서버한테 한 번 요청! 하면, 응 여기있어 응답~ 하고 끝이라는 거다. 연결 종료다. 그 정반대인 웹소켓 방식은 양방향 실시간 통신이기 때문에 연결 종료가 아니다. 아 연결이 안끊어지는 것도 있구나~ 이해했다.
요 HTTP 통신을 기본적으로 fetch API가 해준다. fetch API 는 브라우저 내장 API 여서 별도로 설치하지 않고 사용할 수 있다.
Fetch
fetch("url",option)
.then((response) => response.json())
.then((data) => console.log(data));
fetch는 인자로 url과 option을 받는데, 첫번째에는 데이터를 전송할 url이고, option에는 설정들을 넣어 줄 수 있다.
fetch의 반환값은 Promise객체라서 `Promise<Response>` 타입이다. .then()에 들어오는 response 객체는 string형태의 JSON 텍스트로 내려온다. 그래서 자바스크립트 객체로 다루려면 response.json()으로 변환해주는 코드를 넣는다.
response.json() 은 또 다른 Promise객체를 반환한다. 다시 .then을 이용해 data를 console에 출력하는 형식이다.
fetch는 기본적으로 GET방식으로 작동하고, 그 외의 요청은 option에 추가한다
fetch("url", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title: "Title",
description: "description",
}),
}).then((response) => console.log(response));
위의 코드처럼 option위치에 객체를 만들어서 method, headers, body를 넣어줄 수 있다.
Axios
Axios는 사내 개발팀에서 가장 많은 프로젝트에 쓰이고 있는 http통신 라이브러리이다. 밑에서의 특징처럼 인터셉터로 전역 설정을 해줄 수 있어서 편하고, json데이터도 자동으로 변환해주니까 .json()하지 않아도 된다.
공식문서를 보면 브라우저를 위해 XMLHttpRequest(이하 XHR) 을 생성한다고 나와있는데, fetch이전에는 XHR을 사용해서 API 통신을 사용했다고 한다. Axios는 fetch가 나오기 이전에 만들어져서 자연스럽게 XHR을 생성하도록 만든것.
또한 Promise를 지원한다는 말은 내부적으로 XHR을 쓰긴 하지만, 외부로는 항상 Promise를 반환한다는 뜻이다.
// 초기설정
export const axiosInstance = axios.create({
baseURL: process.env.BASE_URL,
headers: {
'Content-Type': 'application/json',
},
withCredentials: true,
timeout: 0,
});
// 인터셉터
axiosInstance.interceptors.request.use(
(response)=> {
if (response.data.status !== 'success') {
throw new Error('Response status failed');
}
return response;
},
(error)=> {
return Promise.reject(error);
},
);
axiosInstance.interceptors.response.use(
(response)=> {
if (response.data.status !== 'success') {
throw new Error('Response status failed');
}
return response;
},
(error)=> {
return Promise.reject(error);
},
);
사용할때는 axios.create로 초기 설정을 해준다.
생성한 instance에 대해서 통신할 때 공통된 특별 속성을 지정하고 싶다면 interceptors를 사용해 요청 전, 후의 특정한 로직을 설정할 수 있다.
Ky
ky는 2016년에 나온 Axios보다 3년 이후에(2019년) 나온 통신 라이브러리다. '케이와이'로 읽어야 하나 고민했는데, 보통 '카이' 라고 읽는것 같다. 번들사이즈는 Axios는 14kb로 이것도 가볍다 생각했는데, ky는 그보다 훨씬 가벼운 3kb정도이다.
fetch API를 기반으로 해서 가벼운것으로 알고 있다 .
import ky from 'ky';
const api = ky.create({
prefixUrl: '/api',
hooks: {
beforeRequest: [
(request) => {
const token = localStorage.getItem('token');
if (token) {
request.headers.set('Authorization', `Bearer ${token}`);
}
}
],
afterResponse: [
async (request, options, response) => {
if (response.status === 401) {
// 토큰 만료 등의 후처리
}
}
]
}
});
// 사용 예
const data = await api.get('user').json();
Axios와는 다르게 beforeRequest, afterResponse를 사용해서 전,후 처리를 해줄 수 있다.
'frontend' 카테고리의 다른 글
리액트 프로젝트에서 테스팅을 적용하며 했던 생각(jest, react-testing-library, msw) (0) | 2025.02.19 |
---|