UNPKG

axios-rest-api

Version:

Simple Axios wrapper for simple REST Api requests

301 lines (222 loc) 20.6 kB
# REST обертка для axios/axios Простая обертка для популярного HTTP клиента на javascript. Необходима для упрощения запросов к REST api из фронтенд клиента. Добавляет также функцию задержки выполнения запроса для тестирования отзывчивости и интуитивности интерфейса пользователя. Есть два варианта применения библиотеки. Когда у вас единственный сервер API по умолчанию или когда у вас несколько разных серверов/сервисов API. В начале речь идет об использовании единственного сервера. Зависит от `axios` и `underscore` - внешние зависимости. Их нужно подключить отдельно. Либо установить в проекте либо подключить отдельно в HTML для браузера. ## Как работает Просто создайте переменную для работы с API и используйте её где вам это необходимо. Экземпляр класса может быть глобальным или расширять возможности другой библиотеки, фреймворка. Создавался для использования в приложениях VUE расширяемых через плагин или `Vue.prototype.$api = api;`. ```javascript import Api from 'axios-rest-api'; var api = new Api(); // null - параметры запроса // данный вариант вызова возможен, но наименее привлекателен api.load(null, 'https://www.google.com?q=123').then((response) => { // ... вызов гугла только как пример }) .catch((e) => { // ... скорее всего вы получите 405 ошибку }); // Здесь параметры запроса уже вынесены из URL в параметры вызова метода api.load({g: 123}, 'https://www.google.com'); // Здесь и параметры убраны, но и сам URL отсутствует api.res('google').load({g: 123}); // URL вынесен в конфигурацию, описание ниже ``` ## Методы запросов Помимо стандартных *get* и *post* имеются не каноничные *cget, load, save, new, edit, remove*. Кроме прочего, *get* подразумевает наличие ID ресурса в качестве обязательного параметра запроса по умолчанию, ведь это библиотека для запросов к REST API. Когда вам понадобится просто запросить URL без праметров, используйте метод `load(null, url)` как в примере выше или сконфигурируйте свой роутер запросов. Когда вам нужно делать простые запросы GET/POST к серверу, вам не нужна обертка над axios, тогда просто используйте axios. ## Настройка Подразумевает установку значений по умолчанию для большинства запросов, таких как *базовый URL* и *шаблоны запросов*(роутер). У вас будет либо единственный *ресурс по умолчанию*, либо список ресурсов, которые затем необходимо передать в конструктор класса. Конфигурирование URL запросов полностью вынесено в настройки именно для удобства и простоты использования. Хотя писать полные или относительные URL запросов в методах вам никто не запрещает. ```javascript import Api from 'axios-rest-api'; const resources = []; resources.default = { host: 'http://127.0.0.1', prefix: 'api', }; resources.users = { routing: { cget: 'popular', }, }; var api = new Api(resources); api.res('users').load(); // GET http://127.0.0.1/api/users api.res('users').cget(); // GET http://127.0.0.1/api/users/popular api.res('users').get({id: 1}); // GET http://127.0.0.1/api/users/1 ``` ### Ресурсы Основа запросов заключается в получении *ресурсов* с единственного или нескольких серверов. Метод `res(name|url)` устанавливает *имя* ресурса или *адрес* его нахождения. Далее имя ресурса сопоставляется со списком сконфигурированных ресурсов для настройки конкретного *запроса*, если это необходимо. При остсуствии специфических настроек ресурса берется конфигурация *по умолчанию*, а при её отсутствии, запрос сформируется по общепринятым правилам. Метод возвращает сконфигурированный экземпляр класса для дальнейшей работы с ресурсом. Имя ресурса используется для подстановки в итоговый URL запроса как есть. Поэтому вы можете не заморачиваться с настройкой роутов, а просто вызывать ресурс с сервера по относительному адресу ```javascript resources.default = { host: 'http://127.0.0.1', prefix: 'api', }; var api = new Api(resources); api.res('users/new').post({name: 'Bob'}); // POST http://127.0.0.1/api/users/new // send data: {name: 'Bob'} ``` ### Параметры запросов Библиотека меняет порядок параметров в методе запросов(например *get* или *post*), и в отличии от Axios значению *url* отводится наименьший приоритет. URL либо не указывается вообще либо указывается самым последним параметром. На первое место выводятся либо *данные* для POST запроса, либо *параметры* URL для GET запросов. ```javascript resoures.google = { host: 'https://www.google.com', routing: { get: 'search', }, }; var api = new Api(resoures); api.res('google').get({q: 123, hl: 'ru'}); // GET https://www.google.com/search?q=123&hl=ru ``` ## Роутинг Именно для простоты вызова ресурсов в библиотеке испрользуется *роутинг*. Подразумевается, что все REST запросы к API стандартизованы. При обычной архитектуре API сервера вам даже не придется настраивать роутинг для ваших ресурсов. Настройка роутинга, это простой JS объект с указанием *названия* метода запроса и *шаблона запроса*, который перерисывает значения предустановленные этой библиотекой. Подстановочные значения URL указываются в фигурных скобках и берутся из списка параметров для запроса. Если подстановок в шаблоне нет, параметры уйдут в *query* часть URL. Часть параметров может уйти в подстановку, а оставшиеся в параметры URL, если такая ситуация будет необходима. ```javascript resources.users = { host: 'http://127.0.0.1', routing: { get: '{id}', // по умолчанию такой же cget: 'list', load: 'any/other/user/{id}' }, }; api.res('users').get({id: 1}); // GET http://127.0.0.1/api/users/1 api.res('users').get({id: 1, sort: 'asc'}); // GET http://127.0.0.1/api/users/1?sort=asc api.res('users').cget(); // GET http://127.0.0.1/api/users/list api.res('users').post({name: 'Bob'}); // POST http://127.0.0.1/api/users api.res('users').load({id: 1, sort: 'asc'}); // GET http://127.0.0.1/api/users/any/other/user?id=1&sort=asc ``` Стандартный роутер библиотеки. В комментариях реальный метод запроса отправляемого на сервер. Из них *get, post, put, patch, delete, options* являются общепринятыми, остальные добавлены библиотекой и не являются обязательными. ```javascript { route: resources, // имя ресурса load: '', // GET get: '{id}', // GET cget: '', // GET send: '', // GET !!! post: '', // POST save: '', // POST remove: '', // POST new: '', // POST edit: '', // POST delete: '{id}', // DELETE put: '{id}', // PUT patch: '{id}', // PATCH option: '{id}', // OPTIONS } ``` ## Задержка запросов Библиотека позволяет установить задержку в секундах на выполнение любого запроса. Ее можно сконфигурировать как настройку по умолчанию, для каждого ресурса в целом, для конкретного запроса индивидуально. Все эти значения могут различаться, но, если вы действительно захотите использовать что-то большее чем просто общую задержку для всех запросов по умолчанию, есть особенность. Приоритет значения задержки указан именно в такой последовательности. Например, когда общее значение по умолчанию(5 секунд) выше любого другого значения(2 секунды), будет использовано именно оно - значение по умолчанию 5 секунд. ```javascript resources.default = { delay: 5, host: 'http://127.0.0.1', prefix: 'api', }; resources.users = { delay: 3, }; resouresourcesres.comments = { delay: 2, }; var api = new Api(resources); api.res('users').load(); // реальная задержка 5 секунд api.res('comments').load(); // реальная задержка 5 секунд api.res('users').load(null, null, 4); // реальная задержка 5 секунд api.res('users').setDelay(3).load(); // реальная задержка 5 секунд api.res('autors').load(); // реальная задержка 5 секунд // Все значения перебиты максимальным (default) ``` Обратная ситуация, когда при уменьшении приоритета будет увеличиваться время задержки запроса, будут использоваться именно эти значения. ```javascript resources.default = { delay: 1, host: 'http://127.0.0.1', prefix: 'api', }; resources.users = { delay: 2, }; resources.comments = { delay: 3, }; var api = new Api(resoures); api.res('users').load(); // реальная задержка 2 секунды api.res('comments').load(); // реальная задержка 3 секунды api.res('users').load(null, null, 4); // реальная задержка 4 секунды api.res('users').setDelay(3).load(); // реальная задержка 3 секунды api.res('autors').load(); // реальная задержка 1 секунда (default) ``` ## Несколько серверов API По сказанному выше видно, что описание ресурса включает в себя в том числе перечисление настроек подключения к серверу АПИ. Когда у вас единственный сервер, эти настройки обычно легче указать в описании стандартного подключения по умолчанию. В самих же ресурсах перечислять настройки касающиеся непосредственно ресурсов. Такая путаница, или "магия", необходимы для простоты использования библиотеки. Имя конфигурации подключения к серверу АПИ указывается вторым параметром при вызове ресурса. ```javascript api.res('comments', 'post').get({id: 123}); // Загрузить комментарии к посту номер 123 с сервера АПИ постов, // описанном в ресурсе под именем 'post' ``` Далее, вы точно также конфигурируете ресурсы, за исключением только того, что какой-то выбранный вами лично ресурс, будет содержать настройки подключения к новому АПИ. Хорошо, если имя этого ресурса(описание подключения к новому АПИ) будет уникально. Но нет ничего плохого в том, чтобы описать получение единственного ресура с единственного сервера АПИ в одной инструкции. ```javascript resources.default = { host: 'http://localhost', prefix: 'api', }; resources.users = { host: 'http://api-server-first', }; resources.auth = { host: 'http://second-server-api', }; ``` В примере выше, все ресурсы распределены между тремя серверами. Два из них четко `users` и `auth` описаны отдельно, каждый на своем сервере АПИ. Любые остальные запрашиваемые у библиотеки ресурсы будут направляться на сервер по умолчанию. ```javascript // Ресурс или АПИ с именем 'post' не существует в новой конфигурации. // Будет вызван ресурс 'comments' с сервера по умолчанию api.res('comments', 'post').get({id: 123}); // http://localhost/api/comments/123 api.res('profiles', 'users').load(); // GET http://api-server-first/api/profiles api.res('credentials', 'auth').post({login: 'Bob'}); // POST http://second-server-api/api/credentials // Получение единственного ресурса АПИ по имени конфигурации АПИ // Имя ресурса и имя АПИ совпадают api.res('users').get({id: 3}); // GET http://api-server-first/api/users/3 ``` ### Один ресурс на разных серверах Объединение описания и ресурсов и самого подключения к серверу АПИ может запутать, но это необходимо именно для простоты использования. Иначе вам приходится в каждом вызове явно указывать и имя подключения и имя ресурса в других существующих библиотеках. В этой библиотеке имя подключения или имя самого ресурса могут отсутствовать в вызове ресурса или не существовать вовсе. ```javascript resources.default = { host: 'http://localhost', prefix: 'api', }; resources.first = { host: 'http://api-server-first', version: 'v1', }; resources.second = { host: 'http://second-server-api', version: 'v2', }; resources.users = { routing: { cget: 'popular', }, }; api.res('users').cget(); // GET http://localhost/api/users/popular api.res('users', 'first').cget(); // GET http://api-server-first/api/v1/users/popular api.res('users', 'second').cget(); // GET http://second-server-api/api/v2/users/popular // Получить не описанный в настройках ресурс 'posts' с описанного подключения 'second' api.res('posts', 'second').get({id: 5}); // GET http://second-server-api/api/v2/posts/5 ``` ## Значения по умолчанию Для всех запросов можно установить значения по умолчанию через метод `default(key, val)` или получить установленное значение `default(key)`. Эти значения используются внутри библиотеки для формирования запроса. Например, установка ключа авторизации. Вы можете использовать их также, при необходимости. ## Авторизация Дополнительно библиотекой реализована установка ключа авторизации в заголовок запроса `Authorization: Bearer`. Его нужно устанавливать для каждого запроса через `setAuthKey(authkey)`, или прописать параметр `key` в конфигурации ресурса, или установить значение по умолчанию для библиотеки `default('key', key)`. При формировании запроса ресурса ключ авторизации берется из конфигурации ресурса, а если его там нет, из значений по умолчанию. Значение установленное через `setAuthKey(authkey)`, оно перезаписывает для этого запроса все предыдущие. ## Костыли Вы можете перезаписать установленный в конфигурации ключ авторизации указав вторым параметром имя ресурса `setAuthKey(authkey, name)` Вы можете использовать `saveAuthKey(authkey, name)` вместо `setAuthKey(authkey, name)` когда нужно сохранить ключ в конфиге, но не устанавливать его для следующего запроса. Вы можете установить свои заголовки запроса через `setHeaders(headers)` Вы можете определить ресурс после создания экземпляра библиотеки через `define(name, resource)` указав имя и описав объект его конфигурации вторым параметром. Вы можете расширить конфигурацию ресурса или перезаписать некоторые поля через `extend(name, resource)`, вложенные объекты копируются по ссылке. Вы можете установить объект _конфигурации_ Axios через `setAxiosConfig(config)` или получить его `dumpAxiosConfig()`. Но он очищается после каждого запроса. Вы можете сами выполнить свой запрос по схеме `request(method, action, data, params, url, wait)` где _action_ - это имя запроса, ключ для роутера, например `post`, `load` или `save`. Вы можете получить Axios целиком методом `axios()` Вы можете получить сгенерированный URL через `lastURL()`