Введение
Как указано в заголовке, [пакет Mongez http](https://github.com/hassanzohdy/mongez-http) — это библиотека на базе Axios для управления ajax-запросами (и node js тоже), но на профессиональном уровне.
Этот пакет построен на Axios, поэтому если вы хорошо знакомы с Axios, вы будете знакомы с остальной частью статьи.
Установка
Использование npm
npm i @mongez/http
Используя Yarn
yarn add @mongez/http
После установки создайте файл http-config.ts
в вашем проекте (или .js, рекомендуется использовать typescript), чтобы мы могли задать наши конфигурации.
Импортируйте этот файл на ранней стадии вашего проекта, в начале
src/index.ts
, например, или в записи главного файла проекта.
Давайте определим наш файл конфигурации.
// http-config.ts
import { setHttpConfigurations } from '@mongez/http';
setHttpConfigurations({
baseUrl: 'https://jsonplaceholder.typicode.com',
});
Для демонстрации мы будем использовать JSON Placeholder API, чтобы вы могли увидеть реальные результаты.
На данный момент все в порядке, теперь давайте попробуем сделать несколько красивых запросов.
Вы можете следить за тем, что происходит в песочнице.
Обработчик конечных точек
После того, как мы установили наши конфигурации, теперь мы можем использовать наш обработчик endpoint
, который может быть использован в любом месте вашего приложения.
Что такое обработчик конечных точек? По сути, это экземпляр Axios, но с некоторыми изменениями.
Чтобы сделать наш проект чистым и более структурированным, давайте создадим каталог services
в вашем проекте src, внутри которого мы добавим файл todo-service.ts
.
// todo-service.ts
import endpoint from "@mongez/http";
export function getTodoList() {
return endpoint.get("/todo");
}
Итак, мы импортировали обработчик конечной точки и экспортировали функцию для получения списка Todo.
Как вы можете видеть, мы просто добавили в метод get только относительный путь к базовому api url /todo
, так что вам не придется указывать свой базовый url в каждом запросе.
Использование
Теперь мы настроили наши конфигурации, обработали наши сервисы, давайте использовать его.
В вашем App.ts
или если вы используете react в хуке useEffect
вызовите службу конечной точки.
// App.ts
import { getTodoList } from 'src/services/todo-service';
// let's make an ajax call
getTodoList().then((response) => {
console.log(response.data);
});
Размещение данных
Мы рассмотрели, как работать с GET-запросами, теперь давайте посмотрим, как работать с POST-запросами.
Для демонстрации я использую React, чтобы сделать простую страницу создания аккаунта.
// RegisterPage.tsx
export default function RegisterPage() {
return (
<>
<form>
<input name="name" type="text" placeholder="Your Name" />
<br />
<input name="email" type="email" placeholder="Email Address" />
<br />
<input name="password" type="password" placeholder="Password" />
<br />
<button>Create Account</button>
</form>
</>
);
}
Мы только что сделали простой базовый ui для предварительного просмотра формы создания аккаунта, теперь, чтобы отправить форму, нам нужно получить данные, которые будут отправлены, но перед этим давайте создадим файл auth-service.ts
в нашей директории services.
// src/services/auth-service.ts
import endpoint from "@mongez/http";
export function register(data: any) {
return endpoint.post('/users', data);
}
Мы создали обработчик регистра, теперь давайте снова вернемся к нашему ui.
// RegisterPage.tsx
import { useState } from "react";
import { register } from "./services/auth-service";
export default function RegisterPage() {
const [data, setData] = useState({
email: "",
name: "",
password: ""
});
const createAccount = (e: any) => {
e.preventDefault();
register(data).then((response) => {
console.log(response.data);
});
};
return (
<>
<form onSubmit={createAccount}>
<input
name="name"
onChange={(e) => {
setData({
...data,
name: e.target.value
});
}}
type="text"
placeholder="Your Name"
/>
<br />
<input
onChange={(e) => {
setData({
...data,
email: e.target.value
});
}}
name="email"
type="email"
placeholder="Email Address"
/>
<br />
<input
onChange={(e) => {
setData({
...data,
password: e.target.value
});
}}
name="password"
type="password"
placeholder="Password"
/>
<br />
<button>Create Account</button>
</form>
</>
);
}
Мы создали простое состояние для хранения данных нашей формы внутри него, чтобы мы могли отправить объект на сервер, после отправки вы увидите консольный лог с теми же данными, которые мы заполнили, так как api сервер возвращает те же данные с id, обычно 11
.
Данные формы и загрузка
Это было хорошо, но что если мы хотим загрузить файлы или изображения? В этом случае нам придется использовать FormData, однако это не обязательно, так как пакет обрабатывает это за вас, давайте немного расширим наш код.
Обратите внимание, что это не будет работать, так как JSON Placeholder принимает только json, но не form-data запросы.
// RegisterPage.tsx
import { register } from "./services/auth-service";
export default function RegisterPage() {
const createAccount = (e: any) => {
e.preventDefault();
// as you can see we skipped the state to store the data as we'll fetch it from the form inputs directly
const formData = new FormData(e.target);
register(formData).then((response) => {
console.log(response.data);
});
};
return (
<>
<form onSubmit={createAccount}>
<input
name="name"
type="text"
placeholder="Your Name"
/>
<br />
<input
name="email"
type="email"
placeholder="Email Address"
/>
<br />
<input
name="password"
type="password"
placeholder="Password"
/>
<br />
<button>Create Account</button>
</form>
</>
);
}
Теперь мы отправили запрос данных формы, как упоминалось ранее, это можно сделать проще, просто передав элемент формы The e.target element
непосредственно в конечную точку.
// RegisterPage.tsx
import { register } from "./services/auth-service";
export default function RegisterPage() {
const createAccount = (e: any) => {
e.preventDefault();
register(e.target).then((response) => {
console.log(response.data);
});
};
return (
<>
<form onSubmit={createAccount}>
<input
name="name"
type="text"
placeholder="Your Name"
/>
<br />
<input
name="email"
type="email"
placeholder="Email Address"
/>
<br />
<input
name="password"
type="password"
placeholder="Password"
/>
<br />
<button>Create Account</button>
</form>
</>
);
}
Теперь мы обработали отправку данных в serer, используя три метода:
- Передача объектов
Plain
. - Передача объектов
FormDta
. - Передача объектов
FormElement
.
Конечная точка Restful
Еще одной мощной особенностью Mongez Http является класс Restful
, который управляет несколькими запросами в рамках одного класса.
Давайте снова вернемся к нашему todo-service.ts и добавим класс Restful endpoint для управления им.
// todo-service.ts
import endpoint, { RestfulEndpoint } from "@mongez/http";
class TodoService extends RestfulEndpoint {
/**
* {@inheritDoc}
*/
public route = "/todos";
}
const todoService: TodoService = new TodoService();
export default todoService;
// will be kept only for the demo
export function getTodoList() {
return endpoint.get("/todos");
}
Итак, что это было? Ну, в основном класс RestfulEndpoint
управляет основными запросами restful api в 6 основных методах.
Давайте посмотрим, как использовать его в нашем реальном коде.
// TodoList.tsx
import { useEffect, useState } from "react";
import todoService from 'src/services/todo-service';
export default function TodoList() {
const [items, setItems] = useState([]);
const [isLoading, setLoading] = useState(true);
useEffect(() => {
todoService.list().then((response) => {
setItems(response.data);
console.log(response.data);
setLoading(false);
});
}, []);
if (isLoading) return <h1>Loading....</h1>;
return (
<>
{items.map((item) => (
<div key={item.id}>{item.title}</div>
))}
</>
);
}
Мы только что вызвали метод list
, чтобы сделать запрос,
Мы также можем определить параметры запроса к запросу списка, передав ему объект, например
todoService.list({
limit: 15,
active: 1,
}); // will make GET /todos?limit=15&active=1
Чтобы получить одну запись, метод service.get()
сделает это за вас.
const todoId = 1;
todoService.get(todoId).then(response => {
console.log(response.data);
});
Прерывание запросов
Еще одна хорошая возможность — это перехват запроса в переменную, чтобы вы могли отменить/заменить его в любое время, например, при отправке запроса в useEffect, для этого можно использовать функцию lastRequest
.
// TodoList.tsx
import { lastRequest } from "@mongez/http";
import { useEffect, useState } from "react";
import todoService from 'src/services/todo-service';
export default function TodoList() {
const [items, setItems] = useState([]);
const [isLoading, setLoading] = useState(true);
useEffect(() => {
todoService.list().then((response) => {
setItems(response.data);
console.log(response.data);
setLoading(false);
});
.catch((error) => {
console.log(error);
});
// catch the request
let request = lastRequest();
return () => {
request.abort();
};
}, []);
if (isLoading) return <h1>Loading....</h1>;
return (
<>
{items.map((item) => (
<div key={item.id}>{item.title}</div>
))}
</>
);
}
Put To Post
В некоторых языках, таких как PHP, вы не можете напрямую загружать файлы или изображения, используя метод запроса PUT
, но некоторые фреймворки, такие как Laravel, сделали обходной путь для решения этой проблемы, делая запрос POST
с ключом _method
в паре с PUT
в качестве его значения, чтобы вы могли прослушать запрос как запрос PUT
, Это также можно сделать, установив ключ putToPost
в конфигурации http в true, но ваш код останется тем же.
Перед использованием запрос будет выглядеть примерно так
// some-service.ts
import endpoint from '@mongez/http';
export function updateProfile(data: any) {
return endpoint.put('/me', data);
}
updateProfile({
username: 'hasan',
password: '123'
});
// PUT /me request and { username: hasan, password: 123 } as data
Теперь активируем флаг.
// http-config.ts
import { setHttpConfigurations } from '@mongez/http';
setHttpConfigurations({
baseUrl: 'https://jsonplaceholder.typicode.com',
putToPost: true,
});
После активации
// some-service.ts
import endpoint from '@mongez/http';
export function updateProfile(data: any) {
return endpoint.put('/me', data);
}
updateProfile({
username: 'hasan',
password: '123'
});
// PUT /me request and { username: hasan, password: 123, _method: PUT } as data
Таким образом, вы ничего не измените в своем коде, и если ваш api когда-нибудь пренебрежет этой функцией и разрешит прямую загрузку, вы просто отключите флаг, и все будет в порядке.
События HTTP / перехватчики
Последняя функция, о которой я хотел бы рассказать, это события запроса или перехватчики, это чрезвычайно полезный способ манипулировать запросами до их отправки или даже ответом, когда они уже отправлены.
Это можно сделать с помощью обработчика endpointEvents
, он предоставляет 4 хороших перехватчика для работы.
Перехватчик beforeSending
получает конфигурацию запроса axios для своего обратного вызова, мы можем, например, установить заголовок Authorization
.
import { AxiosRequestConfig } from "axios";
import { AxiosRequestConfig } from "axios";
import { endpointEvents } from '@mongez/http';
// This is triggered before sending any request
endpointEvents.beforeSending((config: AxiosRequestConfig): EventSubscription => {
config.headers.Authorization = 'key xxx';
});
Заключение
Основная цель пакета — сделать ваш код организованным, хорошо структурированным и простым в поддержке или масштабировании. Как уже упоминалось ранее, он основан на Axios, поэтому любая функция, которая может понадобиться в Axios, может быть использована и здесь.
Для получения более подробной документации по пакету, не стесняйтесь посетить репозиторий Github.
Надеюсь, вам понравится пакет, и любые отзывы будут приняты с благодарностью.
Наслаждайтесь и удачного кодинга.