Alova 인스턴스는 다양한 유형의 메소드 인스턴스를 생성할 수 있을 뿐만 아니라 전역 매개변수를 설정할 수도 있습니다. 생성된 메소드 인스턴스는 이 alova 인스턴스의 매개변수를 상속합니다.
alova 인스턴스의 매개변수가 timeout, shareRequest 등 메소드 인스턴스와 동일한 매개변수로 설정된 경우, 메소드 인스턴스의 매개변수가 먼저 사용됩니다.
alova의 전역 매개변수를 살펴보겠습니다.
baseURL을 설정한 후에는 더 이상 모든 요청에 대해 동일한 URL 접두사를 추가할 필요가 없습니다. 이후 메소드 인스턴스를 생성할 때 경로 이름만 지정하면 됩니다.
const alovaInstance = createAlova({
baseURL: 'https://api.alovajs.dev'
// ...
});
alovaInstance.Get('/todo/list');
전역 요청 시간 제한을 설정하는 방법입니다.
const alovaInstance = createAlova({
// ...
// Request timeout, unit: milliseconds, default: 0 (시간 초과 발생하지 않음)
timeout: 50000
});
전역적으로 요청 공유를 설정합니다.
const alovaInstance = createAlova({
// ...
shareRequest: false
});
일반적으로 요청 헤더에 토큰 및 타임스탬프를 추가하는 등 모든 요청에 대해 동일한 구성을 사용해야 합니다. 이때 모든 요청 전에 트리거되는 전역 요청 인터셉터를 설정할 수 있습니다. 인터셉터 세트 요청 매개변수를 균일하게 설정할 수 있습니다.
const alovaInstance = createAlova({
// ...
// beforeRequest 함수의 매개변수 method는
// url, params, data, headers 등과 같은 요청 데이터를 포함하는 메소드 인스턴스입니다.
async beforeRequest(method) {
method.config.headers.token = 'token';
}
});
응답 데이터를 균일하게 구문 분석(parse)하고, 오류를 균일하게 처리하고, 요청 완료를 균일하게 처리하려는 경우, alova 인스턴스를 생성할 때 전역 응답 인터셉터를 지정할 수 있습니다.
응답 인터셉터에는 성공적인 요청에 대한 인터셉터와 실패한 요청에 대한 인터셉터, 그리고 요청 완료 인터셉터가 포함됩니다.
const alovaInstance = createAlova({
// ...
responded: {
// 요청 성공에 대한 인터셉터
// alova/fetch 요청 어댑터를 사용할 때, 첫 번째 매개변수는 Response 객체를 받습니다.
// 두 번째 매개변수는 현재 요청의 메소드 인스턴스입니다. 이를 사용해 요청 전후의 구성 정보를 동기화할 수 있습니다.
onSuccess: async (response, method) => {
if (response.status >= 400) {
throw new Error(response.statusText);
}
const json = await response.json();
if (json.code !== 200) {
// 오류가 발생하거나 reject 상태의 Promise 인스턴스가 반환될 때 오류를 발생시킵니다.
throw new Error(json.message);
}
// parsed된 응답 데이터는 메소드 인스턴스의 transform 훅 함수로 전달됩니다.
return json.data;
},
// 요청 실패에 대한 인터셉터
// 두 번째 매개변수는 현재 요청의 메소드 인스턴스입니다. 이를 사용해 요청 전후의 구성 정보를 동기화할 수 있습니다.
onError: (error, method) => {
alert(error.message);
},
// 요청 완료에 대한 인터셉터
// 요청의 성공, 실패, 캐시 적중 여부에 관계없이 로직을 실행해야 하는 경우,
// 요청 로딩 상태를 끄는 등 전역 'onComplete' 인터셉터를 지정할 수 있습니다.
// 현재 요청의 메소드 인스턴스를 매개변수로 받습니다.
onComplete: async method => {
// ...
}
}
});
🧐요청 실패나 완료에 대한 인터셉터를 설정할 필요가 없다면,
객체를 통해 콜백을 설정하는 대신, 요청 성공에 대한 인터셉터 함수를 직접 전달할 수 있습니다.
const alovaInstance = createAlova({
// ...
async responded(response, method) {
// 요청 성공에 대한 인터셉터
}
});
⚠️ 주의사항
onSuccess,onError및onComplete는 동기 함수와 비동기 함수로 설정할 수 있습니다.onError콜백은 요청 오류를 캡처하는 함수입니다.onSuccess에서 발생한 오류는onError를 트리거하지 않습니다. 오류가 발생했지만 오류가 발생하지 않거나 거부(reject) 상태를 반환하는 Promise 인스턴스가 사용되는 경우, 요청은 성공한 것으로 간주되나 응답 데이터를 얻지 못합니다.
메소드 인스턴스는 alova의 전체 요청 라이프사이클을 통해 실행되며, 프로젝트에는 다양한 메소드 인스턴스가 많이 있을 것입니다. 때로는 식별이나 추가 정보 전송을 용이하게 하기 위해 특정 메소드 인스턴스에 추가 정보를 추가해야 하는 경우도 있습니다. 이때, 메소드 메타데이터를 사용해야 합니다.
예를 들어, 프로젝트의 인터페이스 대부분은 각 요청에 대해 token을 동반해야 하지만 여전히 확인이 필요하지 않은 일부 인터페이스가 있습니다. 전역 beforeRequest 함수에서 이를 균일하게 처리할 수 있습니다.
const 유효성검사_필요없는_Api = [
'/api/url1',
'/api/url2',
'/api/url3'
// ...
];
createAlova({
beforeRequest(method) {
if (!nonvalidateRequiredApi.includes(method.url)) {
method.config.headers.token = '...';
}
}
});
위에서 다음 두 가지 문제가 발생합니다.💥
1. 정보는 메소드 인스턴스와 집계되지 않으므로 유지 관리성이 더욱 악화됩니다.
2. 코딩은 더 번거롭습니다.
문제 해결을 위해 메타데이터를 사용하여 특정 메소드 인스턴스가 생성될 때 이를 식별합니다.
Step 1: 메소드 인스턴스 생성 시 메타데이터 정의
const loginAPI = (username, password) => { const methodInstance = alovaInstance.Post('/login', { username, password }); methodInstance.meta = { ignoreToken: true }; return methodInstance; }; // config에서 메타데이터를 직접 정의할 수도 있습니다. const loginAPI = (username, password) => { return alovaInstance.Post( '/login', { username, password }, { meta: { ignoreToken: true } } ); };
Step 2: 판단의 기준으로 메타데이터 사용
createAlova({ // ... beforeRequest(method) { // 전역 요청 인터셉터 if (!method.meta?.ignoreToken) { method.config.headers.token = '...'; } } });
전역 responded 에서도 사용할 수 있습니다.
예를 들어, 대부분의 경우 요청 API는 json 데이터를 반환하지만, 바이너리 데이터 스트림을 반환하는 파일 다운로드 인터페이스가 있을 수 있습니다.
이 경우 responded에 서로 다른 메타데이터를 사용하여 서로 다른 응답을 별도로 처리할 수 있습니다.
Step 1: 메소드 인스턴스 생성 시 메타데이터 정의
const downloadAPI = filePath => { const methodInstance = alovaInstance.Post('/download_file', { filePath }); methodInstance.meta = { isDownload: true }; return methodInstance; };
Step 2: 판단의 기준으로 메타데이터 사용
createAlova({ // ... responded: // 전역 응답 인터셉터 onSuccess: (response, method) => method.meta?.isDownload ? response.blob() : response.json() onError: (error, method) => { // 오류에 응답할 때 메소드 인스턴스의 메타데이터에도 액세스할 수 있습니다. } } });
다른 곳에서 사용하기 위해 다른 메소드 인스턴스에 추가 정보를 추가하려는 경우, 메타데이터를 사용하여 저장할 수도 있습니다. 다양한 메소드 인스턴스 ID를 균일하게 생성하는 것을 예로 들어 보겠습니다.
createAlova({
beforeRequest(method) { // 요청 이전
if (!method.meta.generateId) { // generateId가 없을 경우
method.meta.uid = generateUUID(); // 고유 식별자를 생성하여 저장
} // -> 각 요청에 고유한 uid를 부여
},
responded: {
onSuccess(response, method) {
// 요청이 성공하면 현재 메소드에서 생성된 메타데이터에 액세스합니다.
const currentMethodUID = method.meta.uid;
},
onError(error, method) {
// 요청이 실패하면 현재 메소드에서 생성된 메타데이터에 액세스합니다.
const currentMethodUID = method.meta.uid;
}
}
});
TypeScript가 아닌 환경에서는 meta 속성에 국한되지 않고 모든 속성을 정보 매체로 사용할 수 있습니다.
methodInstance.showResponseMsg = true;
methodInstance.others = 'abc';