axios 문법
axios는 fetch보다 문법이 조금 더 간단하고 다양한 편의기능을 제공하기 때문에 실무에서 많이 사용한다.
axios는 서드파티 모듈이기 때문에 설치를 해줘야 하는데 터미널을 키고 npm install axios 라고 입력해주면 된다.
axios는 HTTP 메소드 이름과 동일한 메소드를 사용하고 리스폰스 바디를 data 프로퍼티로 접근할 수 있다.
GET 리퀘스트
axios로 GET 리퀘스트를 보내려면 axios.get 메소드를 사용하면 된다.
// axios
import axios from 'axios'; //axios import하기
async function getColorSurvey(id) {
const res = await axios.get(`https://learn.codeit.kr/api/color-surveys/${id}`);
return res.data;
}
axios 역시 promise를 리턴하기 때문에 앞에 await을 적어줘야 한다. 그리고 axios에서는 바디 내용을 파싱할 필요 없이 그냥 data 프로퍼티로 가져오면 된다. 상태 코드 status나 헤더 headers를 가져올 수도 있다. 그리고 그걸 데이터 변수에 할당할 필요 없이 그냥 리턴해줄 수 있다.
// fetch
async function getColorSurvey(id) {
const res = await fetch(`https://learn.codeit.kr/api/color-surveys/${id}`);
const data = await res.json();
return data;
}
쿼리 파라미터도 조금더 쉽게 처리할 수 있는데 쿼리파라미터를 보낼 경우 url 객체를 사용할 필요없이 params 옵션을 사용하면 된다.
// axios
export async function getColorSurveys(params = {}) {
const res = await axios.get(
'https://learn.codeit.kr/api/color-surveys',
{ params }, //이 문법은 params라는 프로퍼티로 params 객체를 설정하는 것이다.
);
return res.data;
}
이렇게 쿼리 파라미터를 담고 있는 객체를 전달하면 객체에 있는 프로퍼티들로 알아서 쿼리 스트링을 만들고 URL 뒤에 붙여서 리퀘스트를 보내준다. 만약 프로퍼티 값이 null이나 undefined이면 그 프로퍼티를 무시하고 쿼리 스트링을 만들어준다.
// fetch
async function getColorSurveys(params = {}) {
const url = new URL('https://learn.codeit.kr/api/color-surveys');
Object.keys(params).forEach((key) =>
url.searchParams.append(key, params[key])
);
const res = await fetch(url);
const data = await res.json();
return data;
}
params 외에 헤더 같은 정보도 옵션으로 설정할 수 있다.
POST 리퀘스트
POST는 axios.post를 사용하면되고, 각 HTTP 메소드는 동일한 이름의 axios 메소드를 쓰면 된다. 그리고 POST 메소드는 바디로 전달할 데이터를 두번째 아규먼트로 받는데 자바스크립트 객체를 그대로 사용할 수 있다.
// axios
async function createColorSurvey(surveyData) {
const res = await axios.post('https://learn.codeit.kr/api/color-surveys', surveyData);
return res.data;
}
axios가 알아서 자바스크립트 객체를 JSON 문자열로 변환해 주기 때문에 JSON.stringify 같은 메소드를 쓰지 않아도 된다. 그리고 헤더도 바디 데이터를 보고 알아서 설정해 주기 때문에 내가 설정하지 않아도 된다.
// fetch
async function createColorSurvey(surveyData) {
const res = await fetch('https://learn.codeit.kr/api/color-surveys', {
method: 'POST',
body: JSON.stringify(surveyData),
headers: {
'Content-Type': 'application/json',
},
});
if (!res.ok) {
throw new Error('데이터를 생성하는데 실패했습니다.');
}
const data = await res.json();
return data;
}
- 리퀘스트에 바디가 필요 없는 get이나 delete는 옵션을 두 번째 파라미터로 받는다.
- 바디가 필요한 post, patch, put은 바디 데이터를 두 번째 아규먼트로 받고,
- 옵션을 세 번째 아규먼트로 받는다. 옵션에서는 헤더, 쿼리 파라미터, 타임아웃 등 다양한 설정을 할 수 있다. <참고>
axios 인스턴스
리퀘스트마다 공통되는 부분이 있으면 인스턴스를 생성하고 인스턴스로 리퀘스트를 보내면 된다. 예를들어 리퀘스트 URL은 보통 경로만 다르고 앞부분은 항상 동일하다. base URL로 앞부분을 설정하고 리퀘스트 timeout을 3초로 설정해보자.
const instance = axios.create({
baseURL: 'https://learn.codeit.kr/api', //baseURL에서 URL은 모두 대문자로 작성하자
timeout: 3000,
}); //이제 인스턴스에서 baseURL을 설정했으니 axios를 사용하는 부분들을 바꿔주면 된다.
async function getColorSurveys(params = {}) {
const res = await instance.get(`/color-surveys`, { //나머지 함수들도
params, //비슷하게 바꿔주면 된다.
});
return res.data;
}
인스턴스로 리퀘스트를 보내고 있기 때문에 모두 baseURL과 timeout이 설정되어 있다. 이제 URL 앞부분이 바뀌거나 해도 한군데서만 바꾸면 된다. 인스턴스를 만들 때 설정할 수 있는 옵션은 리퀘스트를 보낼 때 설정할 수 있는 옵션과 똑같다.
axios 오류 처리
fetch 함수는 리퀘스트 자체가 실패했을 때만 promise가 reject되고 400이나 500 에러 리스폰스가 돌아왔을 때는 promise가 reject 되지 않았다.
axios는 리퀘스트 자체가 실패하거나 리스폰스의 상태 코드가 실패(4XX, 5XX)를 나타내면 Promise를 reject 한다. 그러니까 리퀘스트가 성공하고 200대의 상태코드를 가진 리스폰스가 돌아와야만 promise가 fulfilled가 되는 것이다. (그래서 오류처리가 좀 더 편하다.) axios 함수들을 호출할 때 try catch로 감싸주면 된다.
//main.js
import { getColorSurveys, getColorSurvey, createColorSurvey } from './axiosApi.js';
try {
const survey = await getColorSurvey(123);
console.log(survey);
} catch (e) {
console.log('오류가 발생했습니다.');
console.log(e.message);
}
에러 객체의 메세지는 axios가 알아서 설정해 주지만 이거 대신 에러 리스폰스 바디에 있는 메시지를 사용할 수도 있다. 에러 리스폰스가 돌아오면 axios는 에러 객체의 리스폰스를 저장해준다.
//main.js
import { getColorSurveys, getColorSurvey, createColorSurvey } from './axiosApi.js';
try {
const survey = await getColorSurvey(123);
console.log(survey);
} catch (e) {
console.log('오류가 발생했습니다.');
console.log(e.response); //response 프로퍼티로 변경
}
이렇게 response 프로퍼티로 접근할 수 있는데 이 response도 상태코드 status, 헤더 headers, 바디 데이터 data 프로퍼티가 있다.
//main.js
try {
const survey = await getColorSurvey(123);
console.log(survey);
} catch (e) {
console.log('오류가 발생했습니다.');
console.log(e.response.status); //상태코드
console.log(e.response.data); //바디내용
}
프로퍼티를 더 붙여주면 에러 리스폰스의 상태코드와 바디내용 등 출력하고자 하는 내용만 따로 출력할 수도 있다.
//api.js
export async function createColorSurvey(surveyData) {
const res = await axios.post('https://learn.codeit.kr/api/color-surveys', surveyData);
return res.data;
}
//main.js
import { createColorSurvey } from './api.js';
const surveyData = {
mbti: 'EEEE',
colorCode: '#CDCDCD',
password: '0000',
};
try {
const newColorSurvey = await createColorSurvey(surveyData);
console.log(newColorSurvey);
} catch (e) {
if (e.response) {
// 리퀘스트는 성공했지만 상태 코드가 실패(4XX, 5XX)를 나타냄
console.log(e.response.status);
console.log(e.response.data);
} else {
// 리퀘스트 자체가 실패
console.log('리퀘스트가 실패했습니다.');
}
}
Invalid MBTI //잘못된 MBTI
한 가지 주의해야할 점은 리스폰스가 돌아왔을 때만 리스폰스 객체가 존재한다는 것이다. status나 data같은 프로퍼티를 접근할 거라면 리스폰스 객체의 존재여부를 먼저 확인해야한다.
'코린이 개념잡기 > 비동기 자바스크립트' 카테고리의 다른 글
리퀘스트: 브라우저에서 리퀘스트 확인 (1) | 2024.12.27 |
---|---|
리퀘스트: 오류 해결 (3) | 2024.12.27 |
리퀘스트: API 함수 만들기 (1) | 2024.12.27 |
리퀘스트: POST 리퀘스트 보내는 방법 (0) | 2024.12.26 |
Query String, Path / Query Parameter (0) | 2024.12.26 |