Создание абстракции запроса является стандартным решением, но для разделения проблем ваша служба должна иметь возможность отправлять запросы, но она должна возвращать обещание, которым будет управлять вызывающая сторона.
Обычно абстракция запроса обрабатывает также ошибки 400/401 (для токенов обновления / выхода из системы), но не зависит от логики вызывающей стороны.
Вот так выглядит общая абстракция:
/**
* Parses the JSON returned by a network request
*
* @param {object} response A response from a network request
*
* @return {object} The parsed JSON from the request
*/
function parseJSON(response) {
if (response.status === 204 || response.status === 205) {
return null;
}
return response.json();
}
/**
* Checks if a network request came back fine, and throws an error if not
*
* @param {object} response A response from a network request
*
* @return {object|undefined} Returns either the response, or throws an error
*/
function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response;
}
const error = new Error(response.statusText);
error.response = response;
throw error;
}
/**
* Requests a URL, returning a promise
*
* @param {string} url The URL we want to request
* @param {object} [options] The options we want to pass to "fetch"
*
* @return {object} The response data
*/
export default function request(url, options) {
return fetch(url, options)
.then(checkStatus)
.then(parseJSON);
}
Тогда сервис будет выглядеть так:
import request from 'shared/lib/request';
import { API } from 'shared/constants';
const create = (content) => request(
{
url: API.MY_ENDPOINT,
method: 'POST',
data: content,
});
const get = (id) => request(
{
url: `${API.MY_ENDPOINT}/${id}`,
method: 'GET',
});
const put = (content) => request(
{
url: `${API.MY_ENDPOINT}/${content.id}`,
method: 'PUT',
data: content,
});
const MyEndpointService = {
create,
get,
put,
};
export default MyEndpointService;
Использование, где вы хотите (также за пределами области действия реакции):
import MyEndpointService from '/API/MyEndpointService'
MyEndpointService.create(payload)
.then((data) => {
// code
})
.catch((errors) => {
// error code
});