FE-StudyWithMe / FE-without-framework

프레임워크 없는 프론트엔드 개발을 위한 레포지토리🔥
28 stars 0 forks source link

[5장] 또 다른 HTTP 클라이언트 라이브러리를 소개합니다! #29

Closed jasongoose closed 2 weeks ago

jasongoose commented 2 weeks ago

🧐 Question

지금까지 실무에서 접한 HTTP 클라이언트 라이브러리는 axios 외에는 없었는데, 예전에 한번 사용해보고 싶었던 라이브러리인 wretch에 대해서 한번 소개하려고 합니다.

우선 Axios가 XMLHttpRequest 기반이라면 wretch는 Fetch API 기반으로 동작합니다.

그리고 Fetch API, Axios에서 HTTP 요청 설정은 config라는 이름의 객체 단위로 지정하고 프로미스 체이닝 방식으로 응답과 에러 핸들링을 처리하는 반면에,

// Fetch API
const requestConfig = {
    method: "POST",
    body: JSON.stringify({
        data: "to",
        send: "here",
    }),
    headers: {
        "Authorization": "Bearer token-here",
        "Content-Type": "application/json",
        "Accept": "application/json",
    },
};

fetch('https://jsonplaceholder.typicode.com/todos', requestConfig)
    .then((response) => response.json())
    .then((data) => console.log(data));
    .catch((reason) => console.error(reason));
// Axios API
const axios = require('axios');

const url = 'https://jsonplaceholder.typicode.com/posts';

const data = {
  title: 'Hello World',
  body: 'This is a test post.',
  userId: 1,
};

const requestConfig = {
    headers: {
      "Accept": "application/json",
      "Content-Type": "application/json;charset=UTF-8",
    },
}

axios
  .post(url, data, requestConfig)
  .then(({ data }) => {
    console.log("POST request successful. Response:", data);
  })
  .catch(error => {
    console.error("Error:", error);
  });

wretch에서는 모든 작업들을 함수형 체이닝으로 구현합니다.

// Wretch API
import wretch from "wretch";

wretch.options({ mode: "cors" });

const w = wretch("http://domain.com/", { cache: "default" })
  .headers({ "Cache-Control": "no-cache" })
  .content("text/html");

w.get("/resource/1")
  .notFound(error => { /* ... */ })
  .unauthorized(error => { /* ... */ })
  .error(418, error => { /* ... */ })
  .res(response => /* ... */)
  .catch(error => { /* uncaught errors */ });

또한 커스텀 미들웨어 구성을 지원하기 때문에 로깅, 토큰 갱신 등 공통 로직을 일관된 방식으로 구현할 수 있습니다.

import wretch from 'wretch'
import { retry, dedupe } from 'wretch/middlewares'

wretch().middlewares([
  retry({
    /* Options - defaults below */
    delayTimer: 500,
    delayRamp: (delay, nbOfAttempts) => delay * nbOfAttempts,
    maxAttempts: 10,
    until: (response, error) => response && response.ok,
    onRetry: null,
    retryOnNetworkError: false,
    resolveWithLatestResponse: false
  }),
 dedupe({
    /* Options - defaults below */
    skip: (url, opts) => opts.skipDedupe || opts.method !== 'GET',
    key: (url, opts) => opts.method + '@' + url,
    resolver: response => response.clone()
  }),
])./* ... */

함수 체이닝으로 반환된 wretch 인스턴스는 불변객체이기 때문에 사이드 이펙트 없이 쉽게 재사용할 수 있고 요청 흐름을 간결하게 파악할 수 있다는 장점이 있습니다.

다만 함수형 체이닝 방식이 혹자에게는 가독성이 안 좋은 방식이 될 수도 있고 Fetch API를 지원하지 않는 런타임 환경에서는 v1을 사용하거나 폴리필 적용이 필요합니다.

📝 Reference

https://www.npmjs.com/package/wretch

chhw130 commented 2 weeks ago

나름 최근까지 업데이트가 되고 있고, 일반적인 후속처리(then, catch, finally)보다 직관적인 체이닝을 제공하는게 눈에 띄네요!