Переосмысление Apicase и почему я до сих пор не использовал axios

Щелкните здесь, чтобы опубликовать эту статью в LinkedIn »

Каждый день я вижу вопросы «Как работать с API?», «Можете ли вы дать несколько лучших практик», «Как приготовить аксиомы» во фронтенд-чатах. Они получают множество ответов, но все их можно свести к трем типам

- Fetch вполне хватит

Роковая ошибка. Тонны шаблонного кода гарантированы, мне больше нечего сказать

- Axios хорош и рекомендован сообществом

Некоторые люди просто используют аксиомы и не заботятся о них. На мой взгляд, хорошо смотрится только на примерах «Hello world». Когда мы хотим пойти глубже, нам нужно написать собственные оболочки, обработчики и т. Д. И здесь возникают вопросы, указанные выше.

- Я написал свою обертку, она не самая лучшая, но для моих случаев достаточно

Для ваших случаев. Некоторые люди делятся своими функциями-оболочками или даже классами, но это все равно выглядит некрасиво. Часто это просто вызовы axios, завернутые в функцию, которая проверяет аутентификацию, обрабатывает ответ и т. Д. Это очень специфично, охватывает только их варианты использования и не может использоваться в других приложениях.

Казалось бы, столько времени прошло, у нас есть действительно классные фреймворки для работы с view, у нас есть действительно классные библиотеки для управления состоянием, но ...

У нас до сих пор нет единого инструмента для комфортной работы с API.

Представляем Apicase

Apicase - это мощная библиотека, которая перемещает большую часть работы с API на отдельный уровень. Он основан на 4 принципах

  • Обработка запросов на основе событий
  • промежуточное ПО для обновления / изменения на лету / отмены / повтора вызовов API
  • услуги с неограниченным наследованием
  • адаптеры вместо конкретных инструментов (fetch / xhr)

Так что я не хочу глубоко погружаться в теорию и лирику, давайте углубимся и попытаемся написать несколько запросов.

Начиная

Установка

Установите его с помощью вашего любимого менеджера пакетов (npm, yarn, pnpm или лошадь в пальто)

npm install @apicase/core @apicase/adapter-fetch

Обычно я использую fetch, но если вы хотите xhr, вы можете вместо этого установить @apicase/adapter-xhr. Не волнуйтесь, у обоих одинаковый API.

Затем нам нужно обернуть наш адаптер в apicase:

Готово к использованию. Давай воспользуемся этим сейчас

Простые запросы с API на основе событий

Итак, простейший запрос выглядит так:

Почему не просто .then() и .catch()?

Apicase следует принципу «сбои бизнес-логики не являются исключением». Значит, вам нужно как минимум 3 состояния вашего запроса. У обещаний всего 2 - успех или неудача. События позволяют обрабатывать столько вещей, сколько захотите. Нравиться

Вы все еще можете использовать async/await, я сохранил это для вас, мои маленькие любители синтаксического сахара:

Примечание. Обещание будет отклонено только в том случае, если error произойдет. В противном случае он будет решен положительно.

Простые запросы с apicase похожи на запросы axios:

В том, что все? Конечно, нет.

Пример «Создать сообщение»

Услуги Apicase

Итак, как я сказал ранее, если мы углубимся, одного аксиоса недостаточно. Это просто заставляет нас писать много шаблонного кода или превращать его в функции.

Таким образом, мы не хотим записывать повторяющуюся часть данных запроса (в предыдущем примере: url, method, headers). Создадим сервис!

Кроме того, услуги могут быть расширены на сколько угодно, поэтому вы можете сделать что-то вроде этого:

Готов поспорить, у него уже есть более интересные способы работы, чем ваш способ организации API. Но это еще не все.

Итак, мы сократили здесь некоторый шаблонный код. Но здесь наши token переданы статически. Это никогда не изменится. Итак, хуки здесь, чтобы решить вашу проблему.

Крючки Apicase

Хуки перехватывают запрос в какой-то момент и могут изменять запрос payload, response, отменять запрос или повторять его, выполнять другие запросы и т. Д. Подобно перехватчикам axios, но намного лучше.

Выглядит просто - мы просто добавляем before хук, который добавляет token к заголовкам, а затем переходим к следующему шагу.

Можем ли мы сделать лучше? Конечно! Мы можем переместить его в нашу корневую службу, а затем просто унаследовать.

Что, если нам не нужно везде передавать токен аутентификации? Apicase имеет meta параметров, которые передаются хукам. Как у vue-router, если знаете :)

Итак, здесь GetProfile сервису не будет передан токен.

Что-нибудь еще? Конечно, потому что я могу это сделать!

Собираюсь хардкор

«Обновить токен» больше не причиняет боли

Итак, представим, что у нас есть API, для которого требуется токен аутентификации. И если мы получим ошибку 401, мы можем попытаться обновить наш токен в пределах определенного маршрута. Типичный oAuth.

Мы можем сделать это без какого-либо шаблонного кода только один раз, используя хуки.

Поскольку хуки асинхронны, мы можем выполнять там другие запросы. И мы также можем изменить состояние запроса с неудачного на успешное и наоборот. Видеть это:

Итак, если запрос не выполняется со статусом 401, мы попытаемся обновить токен. Если все в порядке, запрос запускается заново без дополнительных действий и обработки в приложении.

Еще труднее! 2 запроса одновременно не выполнены

Ах, да! У вас есть два одновременных запроса API, и оба они не выполнены. Оба они попытаются обновить токен, но нам нужен только один.

Переписать предыдущий код? Создать велосипед? Лол, я могу исправить это одним словом. Не верите? Просто видеть:

У служб есть очередь запросов с текущими запущенными запросами. И у них также есть несколько полезных методов:

  • doRequest - просто запустите запрос и добавьте его в очередь
  • pushRequest - создавать новый запрос только после очистки очереди
  • doSingleRequest - создавать новый запрос только в том случае, если в данный момент нет запущенных запросов. В противном случае верните текущий выполняющийся запрос.
  • doUniqueRequest - создавать новый запрос только в том случае, если в настоящее время нет запущенных запросов с тем же payload. В противном случае верните текущий выполняющийся запрос.

Вы просто создаете запрос или слушаете текущий. Разве это не красиво?

Заканчивать? НЕТ!

Отмена запросов

Больше никаких дерьмовых жетонов отмены, просто .cancel() это

Адаптер XHR использует xhr.abort() для отмены запросов
Адаптер Fetch использует новый AbortController (если доступен)

Очереди запросов

Хотите сделать синхронную очередь запросов? Сделай это, братан:

Отложенные / ограниченные по времени / отклоненные запросы

У запросов есть свойство options с некоторыми вещами coll:

  • Немедленно: установлено значение false, и запрос не запускается автоматически. Вы должны использовать .start(), чтобы запустить его вручную
  • задержка: просто задержка. Запрос начнется через N мс (работает и автоматически)
  • debounce: классический debounce. Полезно для автозаполнения с сервера - создайте запрос, затем .start() его с задержкой N мс. Если он был вызван до истечения времени - перезапустите таймер еще раз.
  • тайм-аут: если вы хотите добавить ограничение по времени для запроса, вы можете использовать эту опцию.

Плагин дерева услуг

Создание сервисов может выглядеть гигантским и чудовищным. Я сделал небольшой инструмент, позволяющий объявлять сервисы с помощью одного объекта JSON:

Вы также можете передавать хуки, мета, опции. Кроме того, есть свойство on для передачи событий:

И, если вам нужна довольно чистая структура, вы можете использовать помощники rest и restWrapped:

Дорожная карта

Это был долгий путь, чтобы проделать такую ​​огромную работу. Пытался сделать с нуля минимум 4 раза. Сейчас это выглядит очень сильно (по крайней мере, для меня). Мои планы на будущее на Apicase:

  • Нормализация и стандартизация API. Я думаю, что некоторых вещей недостаточно. Также я мог пропустить некоторые ошибки. До релиза 1.0 я буду над этим работать.
  • Создание инструментов разработчика: самая важная функция - плагин для Chrome с журналом запросов, визуализацией сервисов и т. д.
  • Типы для TS / Flow: есть печальный момент - Apicase, вероятно, не будет печатать ответы из-за хуков. Но типографии для запросов можно создать хорошо.
  • Дополнительные инструменты для упрощения работы. Я также хочу создать больше вспомогательных инструментов (например, сервисов), чтобы сделать работу с API еще более удобной.

Ссылки

Документация Apicase: нажмите здесь (она все еще в разработке)
Репозитории Github: core, adapter-fetch, adapter-xhr, services
Мой скучный твиттер: подписывайтесь на меня