axios는 HTTP 메서드에 따라 데이터를 전달하는 방식이 조금씩 다르다.
앞으로 axios를 사용할 일이 많을 것 같아서, 메서드별 사용법을 완벽하게 정리해보기로 했다.
GETget 메서드는 HTTP GET 요청을 보내기 위한 함수이며, 서버에서 데이터를 가져올 때 주로 사용된다.
기본 개념
axios.get(url[, config])
📥
url(필수 인자)
- 요청할 서버 주소
- 문자열로 된 주소 (REST API의 endpoint)
- 예:
"https://api.example.com/users"
📥
config(선택 인자)
- 헤더, 쿼리 파라미터, 응답 설정 등 세부 설정 객체
{ params?: object; // 쿼리 파라미터 headers?: object; // 요청 헤더 timeout?: number; // 요청 제한 시간(ms) withCredentials?: boolean; // 쿠키 포함 여부 responseType?: string; // 응답 형식 (예: 'json', 'blob') signal?: AbortSignal; // 요청 취소용 AbortController }
⚠️ 주의사항
get메서드는 두 번째 인자로 객체 이외의 값(예: 문자열, 숫자 등)을 받을 수 없다.- 비객체 타입을 전달하면 에러는 아니지만 무시되거나, 잘못 동작할 수 있다.
사용법
axios.get("https://api.example.com/users", {
params: { page: 2, limit: 10 },
headers: { Authorization: "Bearer TOKEN" },
timeout: 5000,
});
결과적으로 요청은 다음과 같이 전송된다.
GET https://api.example.com/users?page=2&limit=10
반환값
axios.get()은 Promise를 반환한다. (Promise<AxiosResponse> 타입)
axios.get(...).then(response => {
console.log(response.data); // 실제 데이터
console.log(response.status); // HTTP 상태 코드 (200, 404 등)
console.log(response.headers); // 응답 헤더
console.log(response.config); // 요청에 사용된 config
console.log(response.request); // 원본 요청 객체
});
💡
response.data에 들어 있는 데이터는 백엔드가 응답에 넣은 JSON, 객체, 문자열 등이다.
- 예시
- 백엔드 응답 JSON
{ "code": 200, "message": "성공", "data": { "userId": 1, "nickname": "Jiny" } }- 이걸
axios.get()으로 받으면axios.get("/api/user").then((res) => console.log(res.data))console.log(res.data)의 결과{ "code": 200, "message": "성공", "data": { "userId": 1, "nickname": "Jiny" } }
실제 예제
장바구니 조회 (basket.api.ts)
// basket.api.ts
export const readBasket = async ({
countryName,
regionName,
}: CountryAndRegion): Promise<InsertBasketDataType> => {
const path = "/account/basket/read";
try {
const response = await api.get(path, {
params: {
countryName,
regionName,
},
});
const data = response.data;
return data;
} catch (error) {
if (axios.isAxiosError(error)) {
console.error("[readBasket] Axios 에러: ", error);
} else {
console.error("[readBasket] 일반 에러: ", error);
}
throw error;
}
};
🧩 전체 동작 흐름
- 사용자가 특정 국가와 지역을 선택함
readBasket({ countryName: "대한민국", regionName: "부산" })을 호출함- Axios가 다음 주소로 GET 요청을 전송함:
GET /account/basket/read?countryName=대한민국®ionName=부산- 응답이 오면
.data를 추출하여 return함- 에러 발생 시 콘솔에 로그 출력 후 에러를 전파함
장소 세부정보 요청 (place.api.ts)
// place.api.ts
export const readPlaceDetail = async ({
placeId,
}: PlaceId): Promise<ReadPlaceDetailResponse> => {
const path = `/discovery/details/${placeId}`;
try {
const response = await api.get(path);
const data = response.data;
return data;
} catch (error) {
if (axios.isAxiosError(error)) {
console.error("[readPlaceDetail] Axios 에러: ", error);
} else {
console.error("[readPlaceDetail] 일반 에러: ", error);
}
throw error;
}
};
🧩 전체 동작 흐름
readPlaceDetail({ placeId: "abc123" })을 호출함- Axios가
GET /discovery/details/abc123요청을 보냄- 서버에서 해당 장소의 상세 정보를 반환함
response.data를 추출해 return함- 에러 발생 시 콘솔에 로그 출력 후 에러를 전파함
POSTpost 메서드는 HTTP POST 요청을 보내기 위한 함수이며, 서버에 데이터를 생성하거나 전달할 때 주로 사용된다.
기본 개념
axios.post(url[, data[, config]])
📥
url(필수 인자)
- 요청할 서버 주소
- 문자열로 된 주소 (REST API의 endpoint)
- 예:
"https://api.example.com/users"
📥
data(선택 인자)
- 서버에 전달할 본문 데이터
- 일반적으로 JSON 형식을 사용함
- 자동으로
JSON.stringify(data)처리됨Content-Type: application/json헤더가 기본으로 설정됨
📥
config(선택 인자)
- 헤더, 쿼리 파라미터, 응답 설정 등 세부 설정 객체
{ params?: object; // 쿼리 파라미터 headers?: object; // 요청 헤더 timeout?: number; // 요청 제한 시간(ms) withCredentials?: boolean; // 쿠키 포함 여부 responseType?: string; // 응답 형식 (예: 'json', 'blob') signal?: AbortSignal; // 요청 취소용 AbortController }
🧐
JSON.stringify(data)자동 처리란?🔍 Fetch를 사용하면
fetch("/api/data", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ name: "Jiny" }), });
fetch()를 사용할 때는 본문 데이터를 직접JSON.stringify()로 문자열로 바꿔줘야 함- 그렇지 않으면 서버는 정상적인 JSON이 아닌 "객체 그대로의 값"을 받아서 파싱 실패할 수 있음
🔍 하지만, Axios를 사용하면
axios.post("/api/data", { name: "Jiny" });위 코드만 작성해도 내부적으로 아래처럼 처리됨
fetch("/api/data", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ name: "Jiny" }), });
- 즉,
data객체를 자동으로 JSON 문자열로 변환해 주고,"Content-Type": "application/json"헤더도 자동으로 붙여줌
사용법
axios.post(
"/api/login",
{
email: "hyunjin@naver.com",
password: "1234"
},
{
headers: {
Authorization: "Bearer ACCESS_TOKEN",
},
timeout: 5000,
}
);
결과적으로 요청은 다음과 같이 전송된다. (요약 형태)
POST /api/login HTTP/1.1
Host: example.com
Content-Type: application/json
Authorization: Bearer ACCESS_TOKEN
Content-Length: 52
{
"email": "hyunjin@naver.com",
"password": "1234"
}
반환값
axios.post()는 Promise를 반환한다. (Promise<AxiosResponse> 타입)
axios.post(...).then(response => {
console.log(response.data); // 실제 데이터 (백엔드 응답 데이터)
console.log(response.status); // HTTP 상태 코드 (200, 404 등)
console.log(response.headers); // 응답 헤더
console.log(response.config); // 요청에 사용된 config
console.log(response.request); // 원본 요청 객체
});
POST와 GET의 차이 요약
| 항목 | GET | POST |
|---|---|---|
| 목적 | 데이터 조회 | 데이터 생성/전송 |
| 데이터 위치 | URL 쿼리 (params) | 요청 본문 (data) |
| 보안 | URL 노출 가능성 ↑ | 상대적으로 안전 (본문에 포함됨) |
| 캐싱 | 브라우저가 캐싱할 수 있음 | 기본적으로 캐싱 안 됨 |
✅ GET 요청: 데이터는 URL에 붙음 (
params)axios.get("/api/search", { params: { keyword: "제주도", sort: "popular" } });실제 전송되는 HTTP 요청은 다음과 같음 👇
GET /api/search?keyword=%EC%A0%9C%EC%A3%BC%EB%8F%84&sort=popular HTTP/1.1
params객체는 URL에 쿼리스트링으로 변환되어 붙음axios가 자동으로 인코딩 처리를 해줌- 브라우저 주소창에도 그대로 노출됨 → 즐겨찾기나 공유에 좋음
- 쿼리스트링이 주소창에 그대로 노출되므로 민감 정보 노출 위험에 주의해야 함
✅ POST 요청: 데이터는 요청 본문에 담김 (
data)axios.post("/api/login", { username: "hyunjin", password: "test123" });실제 전송되는 HTTP 요청은 다음과 같음 👇
POST /api/login HTTP/1.1 Content-Type: application/json { "username": "hyunjin", "password": "test123" }
data객체는 HTTP 본문(body)에 담김- 주소창에는 전혀 보이지 않음
- 민감한 정보(비밀번호, 토큰 등)에 적합함
- JSON 형식으로 자동 변환됨 (
JSON.stringify())- 본문에 담기므로 상대적으로 안전하지만, HTTPS를 반드시 사용해야 암호화됨
🤔 왜 GET은 캐싱이 되고, POST는 기본적으로 안 되는가?
➡️ HTTP 표준 때문
- GET은 "읽기 전용"이므로, 동일한 요청은 항상 동일한 결과여야 함 → 캐시 가능
- POST는 "서버 상태 변경"이 목적이라서, 같은 요청이라도 결과가 다를 수 있음 → 캐싱하면 데이터 일관성 문제가 생김
🤔 캐싱을 의도적으로 조절하고 싶다면?
🔍 GET 요청에서 캐싱 방지
- HTTP 응답 헤더에 캐시 관련 지시를 내림
Cache-Control: no-cache, no-store, must-revalidate
지시어 의미 no-cache브라우저는 캐시된 응답을 사용하기 전에 항상 서버에 검증 요청해야 함 (즉, 무조건 fresh한지 확인해야 함) no-store아예 캐시에 저장하지 마라 (메모리, 디스크 모두 포함) must-revalidate캐시된 응답이 만료되면, 반드시 서버에 검증 요청을 보내야 함. 만료된 후 재사용하지 않음 - 또는 요청 URL에 현재 시각(
timestamp)을 붙여, URL을 매번 다르게 만들어 캐시를 우회함axios.get(`/api/data?ts=${Date.now()}`);🔍 POST 요청에서도 강제로 캐싱할 수는 있지만, 거의 하지 않음
- 브라우저는 캐싱하려 하지 않지만, 캐시 서버/프록시가 응답을 저장할 수는 있음
- 다만 이건 위험하고, 특수한 경우(예: idempotent POST)에만 고려됨
실제 예제
자체 로그인 (login.api.ts)
// login.api.ts
export const selfLogin = async ({ id, pw }: LoginType) => {
const path = "/account/login";
try {
const response = await api.post(path, {
memberId: id,
password: pw,
});
return response;
} catch (error) {
if (axios.isAxiosError(error)) {
if (error.response?.data.code === "CLT010") {
console.error("[login] 회원정보 불일치");
throw new Error("회원정보가 일치하지 않습니다.");
} else {
console.error("[login] Axios 에러: ", error);
}
} else {
console.error("[login] 일반 에러: ", error);
}
throw error;
}
};
🧩 전체 동작 흐름
- 사용자 입력 수집:
id,pw를 사용자가 입력함- 로그인 요청: Axios
post()로memberId,password를 서버에 보냄- 성공 응답 처리
- 응답 전체를 반환함 (
response.data,response.status등 포함)- 로그인 성공 시 토큰, 사용자 정보 등을 받아올 수 있음
- 에러 발생 시 분기 처리
- 서버에서 응답한
code가"CLT010"이면 → 회원정보 불일치- 사용자는
"회원정보가 일치하지 않습니다."라는 에러 메시지를 받게 됨- 기타 Axios 에러나 일반 에러도 콘솔에 출력하고 다시 throw
이메일 인증코드 전송 (signup.api.ts)
// signup.api.ts
export const checkEmail = async ({ email }: CheckEmailType) => {
const path = "/account/email/verification";
try {
const response = await api.post(path, {
email,
});
return response;
} catch (error) {
if (axios.isAxiosError(error)) {
if (error.response?.data.code === "CLT001") {
console.error("[checkEmail] 이미 존재하는 이메일", error);
throw new Error("이미 존재하는 이메일입니다.");
} else if (error.response?.data.code === "SYS001") {
console.error("[checkEmail] 이메일 전종 실패", error);
throw new Error("이메일 전송에 실패했습니다.");
} else {
console.error("[checkEmail] Axios 에러: ", error);
}
} else {
console.error("[checkEmail] 일반 에러: ", error);
}
throw error;
}
};
🧩 전체 동작 흐름
- 사용자 입력 수집:
- 이메일 인증 요청: Axios
post()로- 성공 응답 처리
- 인증코드 전송 성공 시 응답 전체를 반환함
- 이후에 사용자에게 "인증코드 전송 완료" 안내 가능
- 에러 발생 시 분기 처리
- 응답에
code가 포함된 경우 코드별로 처리- 그 외 Axios 에러는 콘솔 출력, 일반 에러도 throw 처리
PUTput 메서드는 HTTP PUT 요청을 보내기 위한 함수이며, 서버에 있는 데이터를 완전히 수정(대체)할 때 주로 사용된다.
기본 개념
axios.put(url[, data[, config]])
📥
url(필수 인자)
- 요청할 서버 주소
- 문자열로 된 주소 (REST API의 endpoint)
- 예:
"https://api.example.com/users"
📥
data(선택 인자)
- 서버에 전달할 수정 대상 데이터
- 일반적으로 JSON 형식을 사용함
- 자동으로
JSON.stringify(data)처리됨Content-Type: application/json헤더가 기본으로 설정됨
📥
config(선택 인자)
- 헤더, 쿼리 파라미터, 응답 설정 등 세부 설정 객체
{ params?: object; // 쿼리 파라미터 headers?: object; // 요청 헤더 timeout?: number; // 요청 제한 시간(ms) withCredentials?: boolean; // 쿠키 포함 여부 responseType?: string; // 응답 형식 (예: 'json', 'blob') signal?: AbortSignal; // 요청 취소용 AbortController }
사용법
axios.put("/api/user/1", {
name: "hyunjin",
email: "jiny@example.com"
});
결과적으로 요청은 다음과 같이 전송된다.
PUT /api/user/1
Content-Type: application/json
{
"name": "hyunjin",
"email": "jiny@example.com"
}
반환값
axios.put()은 Promise를 반환한다. (Promise<AxiosResponse> 타입)
axios.put(...).then(response => {
console.log(response.data); // 실제 데이터 (백엔드 응답 데이터)
console.log(response.status); // HTTP 상태 코드 (200, 404 등)
console.log(response.headers); // 응답 헤더
console.log(response.config); // 요청에 사용된 config
console.log(response.request); // 원본 요청 객체
});
PUT 메서드의 특징
| 항목 | 내용 |
|---|---|
| 목적 | 기존 자원의 전체 수정/대체 |
| 멱등성 | 있음 (같은 요청 여러 번 보내도 결과 동일) |
| 데이터 위치 | 요청 본문(body) |
| 사용 예 | 회원 정보 수정, 게시글 수정, 설정 업데이트 등 |
예제: 회원정보 수정 API
진행하는 프로젝트에 put() 예제가 없어서, 임의로 실무 예제를 만들어 보았다.
export const updateProfile = async ({
userId,
name,
email
}: {
userId: string;
name: string;
email: string;
}) => {
try {
const res = await api.put(`/account/profile/${userId}`, {
name,
email,
});
return res.data;
} catch (err: any) {
if (axios.isAxiosError(err)) {
console.error("[updateProfile] 에러: ", err.response?.data);
}
throw err;
}
};
🧩 전체 동작 흐름
- 사용자로부터 수정할 정보 입력 받기
- UI 폼 등에서 사용자로부터 입력을 수집함
- 이 값이
updateProfile({ userId, name, email })의 인자로 전달됨- PUT 요청 준비
- 요청 경로를
userId로 동적으로 구성함- 서버에 전송할 데이터를 JSON 형태로 준비함
- 서버에 요청 전송:
PUT /account/profile/1234요청을 전송함- 서버 응답 수신: 서버가 수정 결과를 응답으로 반환함
- 응답 데이터 반환
- 호출한 쪽에서는
await updateProfile(...)결과로res.data를 받음- 이 데이터를 UI에 반영하거나 성공 메시지 표시 가능
- 에러 발생 시 처리 (실패 시)
- 서버가 오류 코드(예: 400, 404, 500 등)를 보낼 경우,
catch블록으로 이동함- Axios 에러인지 확인 후 콘솔 출력
throw로 다시 던져서 상위에서onError등으로 처리
PATCHpatch 메서드는 HTTP PATCH 요청을 보내기 위한 함수이며, 서버에서 자원의 일부만 수정할 때 주로 사용된다.
기본 개념
axios.patch(url[, data[, config]])
📥
url(필수 인자)
- 요청할 서버 주소
- 문자열로 된 주소 (REST API의 endpoint)
- 예:
"https://api.example.com/users"
📥
data(선택 인자)
- 서버에 전달할 수정할 필드만 담긴 데이터 객체
- 일반적으로 JSON 형식을 사용함
- 자동으로
JSON.stringify(data)처리됨Content-Type: application/json헤더가 기본으로 설정됨
📥
config(선택 인자)
- 헤더, 쿼리 파라미터, 응답 설정 등 세부 설정 객체
{ params?: object; // 쿼리 파라미터 headers?: object; // 요청 헤더 timeout?: number; // 요청 제한 시간(ms) withCredentials?: boolean; // 쿠키 포함 여부 responseType?: string; // 응답 형식 (예: 'json', 'blob') signal?: AbortSignal; // 요청 취소용 AbortController }
사용법
axios.patch("/api/user/1234", {
nickname: "Jinny",
});
결과적으로 요청은 다음과 같이 전송된다.
PATCH /api/user/1234 HTTP/1.1
Content-Type: application/json
{
"nickname": "Jinny"
}
반환값
axios.patch()는 Promise를 반환한다. (Promise<AxiosResponse> 타입)
axios.patch(...).then(response => {
console.log(response.data); // 실제 데이터 (백엔드 응답 데이터)
console.log(response.status); // HTTP 상태 코드 (200, 404 등)
console.log(response.headers); // 응답 헤더
console.log(response.config); // 요청에 사용된 config
console.log(response.request); // 원본 요청 객체
});
PATCH 메서드의 특징
| 항목 | 내용 |
|---|---|
| 목적 | 자원의 일부만 수정 |
| 멱등성 | 보장되지 않음 (같은 요청 여러 번 보내면 서버 상태가 달라질 수 있음) |
| 데이터 위치 | 요청 본문(body) |
| 사용 예 | 닉네임만 변경, 비밀번호만 변경 등 필드 단위 업데이트 |
PUT과 PATCH 차이 요약
| 항목 | PUT | PATCH |
|---|---|---|
| 목적 | 리소스 전체를 완전히 교체 | 리소스의 일부 필드만 수정 |
| 사용 예 | 사용자 정보 전체 변경 | 닉네임만 변경, 비밀번호만 변경 |
| 전송 데이터 | 변경 대상의 모든 필드 포함 (전체 구조) | 변경할 필드만 포함 |
| 요청 크기 | 큼 (전체 리소스를 보내야 하므로) | 작음 (수정 필드만 보내므로) |
| 멱등성 | ✅ 같은 요청을 반복해도 결과가 동일함 | ❌ 같은 요청을 여러 번 보내면 결과가 다르게 나올 수 있음 |
| 생략된 필드 처리 | 생략된 필드는 삭제되거나 기본값으로 대체됨 | 생략된 필드는 유지됨 |
| 서버 구현 복잡도 | 상대적으로 단순함 (전체 덮어쓰기) | 약간 높음 (부분 병합 구현 필요) |
| 의미상 구분 | 대체(replace) → 전체 구조를 새로 보내서 덮어씀 | 변경(change) → 수정할 부분만 보냄 |
| 주로 사용하는 곳 | 게시글 전체 수정, 리소스 상태 초기화 등 전체 갱신이 필요한 경우 | 마이페이지 수정, 비밀번호 변경, 설정 토글 등 |
| 실무에서의 빈도 | 전체 상태를 명시적으로 덮어쓸 필요 있을 때 사용 | 자주 사용됨 (성능 & UX 고려해 필드 단위 수정) |
axios.patch("/api/user/1234", {
nickname: "Jiny"
});nickname만 바꾸고 나머지 필드는 그대로 유지함axios.put("/api/user/1234", {
nickname: "Jiny",
email: "jiny@naver.com"
});user 데이터를 전체 교체함 (nickname, email 둘 다 필요)patch() 예제가 없어서, 임의로 실무 예제를 만들어 보았다.export const updatePassword = async ({
userId,
newPassword,
}: {
userId: string;
newPassword: string;
}) => {
try {
const res = await api.patch(`/account/password/${userId}`, {
password: newPassword,
});
return res.data;
} catch (err: any) {
if (axios.isAxiosError(err)) {
console.error("[updatePassword] 에러: ", err.response?.data);
}
throw err;
}
};🧩 전체 동작 흐름
- 사용자 입력
- 사용자가 새 비밀번호를 입력함
userId는 로그인 중인 사용자의 ID 또는 관리자 수정 대상 ID임- PATCH 요청 준비
userId를 경로에 포함하여 해당 사용자의 비밀번호만 변경하도록 함- 요청 body에는 변경할 비밀번호만 포함함
- 서버에 PATCH 요청 전송:
PATCH /account/password/1234요청을 전송함- 서버 응답 수신: 비밀번호 변경에 성공하면 응답이 도착함
- 응답 데이터 반환: 호출한 쪽에서
await updatePassword(...)로 이 응답 데이터를 받아 사용 가능함- 에러 발생 시 처리
- 서버 응답 오류(예: 잘못된 형식, 인증 실패 등) 발생 시
- Axios 전용 에러인지 판별 후 로그 출력
- 에러는 다시 throw 되어 상위
onError,try...catch,catch()에서 처리 가능
DELETEdelete 메서드는 HTTP DELETE 요청을 보내기 위한 함수이며, 서버에 있는 데이터를 삭제할 때 주로 사용된다.
기본 개념
axios.delete(url[, config])
📥
url(필수 인자)
- 삭제할 자원의 경로
- 문자열로 된 주소 (REST API의 endpoint)
- 예:
"https://api.example.com/users"
📥
config(선택 인자)
- 헤더, 쿼리 파라미터, 응답 설정 등 세부 설정 객체
{ data?: { [key: string]: any; // ⭐ get 메서드와의 차이점!! }; params?: object; // 쿼리 파라미터 headers?: object; // 요청 헤더 timeout?: number; // 요청 제한 시간(ms) withCredentials?: boolean; // 쿠키 포함 여부 responseType?: string; // 응답 형식 (예: 'json', 'blob') signal?: AbortSignal; // 요청 취소용 AbortController }
⚠️ 주의사항
delete메서드는post,put,patch와 달리 기본적으로data를 두 번째 인자로 받지 않는다.- 그러나 일부 서버에서는
data를 요청 본문에 필요로 하기도 하므로, 그럴 경우config안에data를 넣어야 한다.
사용법
axios.delete("/api/favorite", {
data: {
userId: "abc123",
placeId: "p001"
}
});
결과적으로 요청은 다음과 같이 전송된다.
DELETE /api/favorite HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 46
{
"userId": "abc123",
"placeId": "p001"
}
data를 config 객체 안에 포함시켜야 한다.delete(url, data)는 잘못된 사용이다. 반드시 config.data로 감싸야 한다.반환값
axios.delete()는 Promise를 반환한다. (Promise<AxiosResponse> 타입)
axios.delete(...).then(response => {
console.log(response.data); // 실제 데이터 (백엔드 응답 데이터)
console.log(response.status); // HTTP 상태 코드 (200, 404 등)
console.log(response.headers); // 응답 헤더
console.log(response.config); // 요청에 사용된 config
console.log(response.request); // 원본 요청 객체
});
실제 예제
travelPlan.api.ts)// travelPlan.api.ts
export const deleteTravelPlan = async ({ id }: TravelPlanId) => {
const path = "/account/plan/delete";
try {
const response = await api.delete(path, {
data: { id },
});
return response;
} catch (error) {
if (axios.isAxiosError(error)) {
console.error("[deleteTravelPlan] Axios 에러: ", error);
} else {
console.error("[deleteTravelPlan] 일반 에러: ", error);
}
throw error;
}
};🧩 전체 동작 흐름
deleteTravelPlan함수 호출:id는 삭제할 여행 계획의 고유 식별자path정의: 삭제 요청을 보낼 API 경로axios.delete()로 DELETE 요청 실행
- DELETE 요청이
path로 전송됨- 본문(
body)에는{ id: "plan1234" }가 JSON 형태로 포함됨- 여기서
config객체 안에data를 넣는 건 DELETE 메서드의 특별한 사용법임- 서버 응답 받기
- 서버는 해당
id를 기준으로 여행 계획을 삭제함- 삭제 성공 시, 일반적으로
200 OK또는204 No Content상태 코드를 반환함- 응답 본문에 삭제 결과 메시지나 상태 정보가 포함될 수 있음
- 응답 처리
- 응답 전체(
AxiosResponse객체)를 반환함- 필요한 경우, 호출부에서
.data로 실제 데이터를 추출할 수 있음- 예외 처리
- 요청 실패 시 오류 로그를 출력함
axios.isAxiosError()로 Axios에서 발생한 오류인지 구분함- 오류를 다시 throw 하므로, 호출부에서도
.catch()또는try...catch로 처리해야 함
| 메서드 | 데이터를 어디에 담아야 하는가? | 이유 |
|---|---|---|
| GET | config.params (URL 쿼리스트링) | GET은 HTTP 표준상 본문(body)을 가질 수 없음 |
| DELETE | config.params 또는 config.data | 보통은 쿼리로 식별자를 전달하지만, 일부 API는 본문(body)도 허용함 |
| POST, PUT, PATCH | data (body에 포함됨) | 본문(body) 전송이 표준 방식 |
🤔 GET은 절대 body(
data)를 가질 수 없는가?
- HTTP 명세(RFC 7231)에 따르면:
- GET 요청은 리소스를 가져오는 목적이며,
- 요청 본문(body)을 갖지 않아야 함
- 대부분의 브라우저와 서버는 GET의 body를 무시하거나 거부함
- 그래서 GET 요청에서는 아래와 같이
params에 데이터를 담아 URL 쿼리로 전송함axios.get("/api/items", { params: { category: "fruit", page: 2 } }); // 전송 URL: /api/items?category=fruit&page=2
🤔 DELETE는 왜
data에 담을 수 있는가?
- DELETE는 일부 서버에서 요청 본문(body)을 받아들이도록 허용함
- 하지만 HTTP 표준상 반드시 보장되는 건 아님
- Axios는 이를 지원하기 위해 아래와 같이
config.data를 통해 본문 전송을 허용함axios.delete("/api/favorite", { data: { userId: "abc", placeId: "p001" } });- 즉, DELETE는
config.params로도 가능하고, 서버가 지원한다면config.data로도 가능함
🤔 그럼 DELETE에서
params를 사용하면 안 되는가?✅ 사용할 수 있음!
axios.delete("/api/favorite", { params: { userId: "abc", placeId: "p001" } });이때, 전송 URL은 다음과 같음
DELETE /api/favorite?userId=abc&placeId=p001
- 이건 RESTful하게 자원 식별자로 삭제 요청을 보낼 때 많이 사용됨
- 만약 데이터가 민감하거나, 길거나, 구조화된 형태라면 body(
data)에 담는 것이 더 적절할 수 있음
❓ REST(Representational State Transfer)란?
2000년에 로이 필딩(Roy Fielding)이 자신의 박사 논문에서 제안한 웹 아키텍처 스타일로, HTTP의 기본 원칙에 따라 클라이언트와 서버가 통신하는 방식을 정의한다.
❓ RESTful이란?
REST의 원칙을 지키는 방식으로 API를 설계한 상태를 "RESTful하다"고 말한다.
🔍 RESTful한 DELETE 요청 예시
- RESTful하지 않은 방식
DELETE /deleteUser Body: { userId: "1234" }
- URL만 봐서는 어떤 자원을 삭제하는지 알기 어려움
- 삭제할 대상을 본문에 넣음 → REST 원칙 위반
- RESTful한 방식
DELETE /users/1234
/users/1234는 삭제 대상 자원(Resource)을 URL에서 명확하게 표현함- 행위(DELETE)는 HTTP 메서드로 표현됨
- 본문 없음 → REST 스타일에 맞음
🤔 GET 요청에
data를 넣으면 어떻게 되나?axios.get("/api/test", { data: { foo: "bar" } });
- 이건 전혀 효과 없음 → Axios는 내부적으로
data를 무시함- 브라우저도 GET 요청에 body가 있으면 무시하거나 경고를 발생시킴
- 따라서 GET에서는
params만 사용해야 함