이번 주에 여러분은 axios를 이용해 서버와 http 통신을 수행했습니다!
오늘은 axios instance를 같이 만들어볼 것이며
공식문서를 함께 보면서 공식문서 보는 것에 익숙해질 것 입니다.
node.js와 브라우저를 위한 Promise 기반 http 클라이언트
http를 이용해 서버와의 통신을 돕는 패키지

아직은 공식문서를 더 풀어 쓴 강의 자료, 블로그 글이 더 편하시리란 것을 압니다.
여러 코드들의 데이터가 쌓이고 코드에 익숙해지면 공식문서가 더 편해질 수 있습니다.
또한 블로그나 공식문서를 정리한 자료들은 업데이트가 안 된 오래된 자료이거나 틀린 정보일 가능성도 있습니다.
공식문서가 가장 정확하고 최신의 자료입니다. 그래서 공식문서에 익숙해져야 한다고 강조드리는 것 입니다.


문서에서 제공해준다고 나와있는 create, request, get, delete … 등의 메소드가 코드에 그대로 구현되어 있습니다.
우리가 get, delete 메소드를 실습했을 때 결과물은 Promise가 나왔습니다. 기억하시나요 ?
// todosSlice.js
export const __deleteTodoThunk = createAsyncThunk(
"DELETE_TODO",
async (arg, thunkAPI) => {
try {
axios.delete(`${serverUrl}/todos/${arg}`);
return thunkAPI.fulfillWithValue(arg);
} catch (e) {
return thunkAPI.rejectWithValue(e.code);
}
}
);
export const __getTodosThunk = createAsyncThunk(
"GET_TODOS",
async (_, thunkAPI) => {
try {
const { data } = await axios.get(`${serverUrl}/todos`);
return thunkAPI.fulfillWithValue(data);
} catch (e) {
return thunkAPI.rejectWithValue(e.code);
}
}
);
코드에서도 get, delete 함수의 결과는 Promise를 반환한다고 적혀있습니다.

이것을 함께 보면서 여러분들께 알려드리고 싶은 것은
첫째로,
공식 문서는 사용법을 알려주고 있는 문서, 코드의 내용을 설명해주는 문서입니다.
어려워할 필요가 없습니다.
둘째,
내가 사용하는 라이브러리의 동작 원리를 궁금해하고 파고 들어가보는 경험은 여러분의 실력을 올려줍니다.
코드를 타고타고 들어가면 내용들을 다 확인할 수 있어요. 코드만 보고 이해가 어렵다면 공식문서와 대조해보면 그 어려워보이는 코드들이 조금은 이해가 되는 경험을 해보실 수 있어요.
공식문서가 친절하게 인스턴스 만드는 법을 알려주고 있습니다.

create 메소드를 사용하면 된다고 합니다.
그리고 인자에는 설정 값 (config)를 넣어주면 된다고 합니다.
const instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
사용자가 지정한 config를 계속해서 재사용할 수 있기 때문입니다.
중복되는 내용들을 지정해서 인스턴스를 생성하고
그 인스턴스를 사용하면 지정된 config가 추가된 config와 결합됩니다.
메소드 요청시마다 header에 로그인 토큰을 보내야 한다면 ?
#인스턴스 없이 작성하는 경우
각 axios 메소드의 config마다 중복되는 내용 (ex - headers: { ’token’: ‘foo’ }) 을 적어줘야 합니다.
함수마다 같은 내용을 적어줘야 하는데요. 복잡한 어플리케이션 속 함수가 수십 수백개라고 상상해보세요.
더 큰 문제는 유지보수입니다.
config의 들어갈 내용이 일부 바뀐다면.. 모든 axios 메소드가 사용되는 곳에 수정을 해야합니다.

#인스턴스가 있다면 ?
생성한 인스턴스를 기반으로 메소드를 사용하면 미리 지정한 config가 자동으로 재사용됩니다.
매번 config를 추가해줄 필요가 없어집니다.
const instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'token': 'foo'}
});
instance.get()
instance.delete()
이것도 공식문서에 잘 나와있습니다!

// 응답 인터셉터 추가하기
axios.interceptors.response.use(function (response) {
// 2xx 범위에 있는 상태 코드는 이 함수를 트리거 합니다.
// 응답 데이터가 있는 작업 수행
return response;
}, function (error) {
// 2xx 외의 범위에 있는 상태 코드는 이 함수를 트리거 합니다.
// 응답 오류가 있는 작업 수행
console.log(error.msg)
return Promise.reject(error);
});
axios.get(~~)
axios.delete(~~)
export const __addTodoThunk = createAsyncThunk(
"ADD_TODO",
async (arg, thunkAPI) => {
try {
const { data } = await axios.post(`${serverUrl}/todos`, arg);
return thunkAPI.fulfillWithValue(data);
} catch (e) {
return thunkAPI.rejectWithValue(e);
}
}
);
export const __deleteTodoThunk = createAsyncThunk(
"DELETE_TODO",
async (arg, thunkAPI) => {
try {
axios.delete(`${serverUrl}/todos/${arg}`);
return thunkAPI.fulfillWithValue(arg);
} catch (e) {
return thunkAPI.rejectWithValue(e.code);
}
}
);
export const __getTodosThunk = createAsyncThunk(
"GET_TODOS",
async (_, thunkAPI) => {
try {
const { data } = await axios.get(`${serverUrl}/todos`);
return thunkAPI.fulfillWithValue(data);
} catch (e) {
return thunkAPI.rejectWithValue(e.code);
}
}
);
요청이 전달되기 전에 작업을 수행하거나
응답 결과를 중간에 미리 처리할 수 있습니다.