Как настроить Axios в приложении Nuxt
Вы, вероятно, слышали про axios или использовали его в своих веб-приложениях. Axios - это HTTP-клиент для браузера и node.js. Он значительно упрощает работу с API-запросами. Если вы работаете с Nuxt, есть официальный модуль, который ещё больше упрощает задачу интеграции этой библиотеки в фреймворк: @nuxtjs/axios
. Именно на нём я сосредоточусь в этой статье. Предполагается, что вы знакомы с Nuxt и уже настроили проект. Я не буду подробно рассказывать о том, как использовать axios, об этом вы можете почитать в другой статье. Здесь вы узнаете, как настроить axios для ваших нужд в приложении Nuxt.
Как установить модуль axios
В вашем текущем проекте Nuxt запустите yarn add @nuxtjs/axios
или npm install @nuxtjs/axios
в зависимости от вашей рабочей среды.
Добавьте @nuxtjs/axios
в список модулей в nuxt.config.js
.
Теперь axios готов к использованию!
Базовое использование
Теперь вы можете использовать axios в ваших компонентах и в любой части приложения, которая имеет доступ к контексту Nuxt. Модуль добавляет axios в контекст и он становится доступен под именем $axios
. Например, вы можете использовать this.$axios.get(url)
или this.$axios.post(url, data)
в любом .vue
файле.
Настройка axios с помощью плагина
Одним из способов настройки axios является создание плагина, в котором задаются все значения по умолчанию. Это то же самое, что и создание любого другого плагина для Nuxt. Код плагина запускается до инициализации ядра Vue.
Создание плагина
- Создайте файл в папке
plugins
. Назовите его как угодно, но, я советую назватьaxios.js
- это общепринятое название. - Добавить файл в списке плагинов в
nuxt.config.js
свойствоplugins
. - Готово!
Настройка плагина
Как же должен выглядеть этот плагин?
export default function ({ $axios, store }, inject) {
// тут будем всё настраивать
})
В этой статье мы будем использовать только $axios
и store
из контекста. Но список параметров в действительности намного больше. Рекомендую просмотреть документацию по контексту Nuxt, где приведён список всех доступных параметров и их описание.
Вот несколько примеров того, что вы можете сделать в файле плагина plugins/axios.js
:
- Установить базовый URL для всех запросов
- Создать несколько экземпляры axios, внедрить их в приложение и использовать в нужных местах необходимые экземпляры
- Прикрепить токен к каждому запросу
- Перехватывать ответ до того, как он попадает в вызываемый код приложения
Установка базового URL для всех запросов
Если все запросы направлены на один и тот же API, то можем задать базовый URL по умолчанию, чтобы в запросах к API мы не хардкодили домен, и в случае чего, могли в любой момент хост на другой. Мы можем настроить экземпляр axios
так, чтобы он хранил этот базовый URL.
Это означает, что нам не нужно прописывать полный URL в каждом запросе, который мы хотим сделать. Просто добавьте это в функцию плагина:
$axios.setBaseUrl('https://api.badcode.ru/')
Теперь при использовании $axios
этот URL всегда будет использоваться в качестве базового URL-адреса. Что даёт теперь возможным сделать такой вызов api:
$axios.get('/post/1')
Добавление нового экземпляра axios и внедрение его в приложение
Но что, если нам потребуется обращаться к нескольким доменам разных API? Вы можете создать новый экземпляр axios
с любым именем, которое вы предпочитаете, и внедрить его в приложение.
Допустим, мы хотим получить данные о постах блога и пользователях, которые хостятся на разных API. Мы можем создать два разных экземпляра axios с разными базовыми адресами.
const postsApi = $axios.create()
const membersApi = $axios.create()
postsApi.setBaseUrl('https://api.badcode.ru/')
membersApi.setBaseUrl('https://members.badcode.ru/')
inject('postsApi', postsApi)
inject('membersApi', membersApi)
Здесь мы используем функция inject
, предоставляемый плагинами Nuxt. Inject
принимает два аргумента: первый - ключ, второй - значение.
То есть, после вызова функции inject
, в контексте приложения Nuxt появится новое свойство с таким ключом и значением как было указано. Nuxt автоматически добавляет знак доллара к внедряемому ключу.
Чтобы использовать экземпляры axios, которые мы создали, вы можете обратиться так:
this.$membersApi.get('/people/1')
this.$postsApi.get('/posts/1')
Всё это упрощает использование и делает более явным то, что вы запрашиваете. Созданные нами экземпляры axios имеют те же вспомогательные функции, что и исходный экземпляр $axios
.
Добавление токена в заголовок при каждом запросе
Если ваши API вызовы требуют какого-то токена авторизации, это также можно настроить в файле плагина. Чтобы установить заголовок авторизации в запросе, мы должны задать его в параметре option
.
Допустим, для примера, API информации о пользователях блога (membersApi
) требует аутентификации.
Вот один из способов установить Authorization
токен в axios:
this.$membersApi.get('/people/1', {
headers: {
Authorization: `Bearer ${token}`,
},
})
Этот код отлично работает, но быстро надоедает, когда приходится добавлять его в несколько мест. С помощью модуля @nuxtjs/axios
мы можем указать добавление токена в запрос в файле плагина.
Если мы хотим использовать токен Bearer, мы можем поступить следующим образом:
const token = 'test_token'
$axios.setToken(token, 'Bearer')
Это добавит токен в заголовок под названием Authorization
. Обычно этот токен хранится в localstorage
или в хранилище Vuex
. Я использую для хранения токена текущего пользователя Vuex state
. В функции плагина у вас есть доступ к Vuex из контекста Nuxt.
Теперь можем проверить, добавляется ли токен в запрос к созданному экземпляру axios.
const token = store.state.currentUser.token
membersApi.setToken(token, 'Bearer')
Если вы используете refresh-токен или обновляете текущий токен каким-либо способом, вы также можете вызвать метод setToken
, в том месте, где обновляется токен пользователя. В компоненте или модуле Vuex store вы можете, например, выполнить:
this.$membersApi.setToken(newToken, 'Bearer')
Перехват ответа axios
Если вы хотите проверять статус ответа при каждом вызове axios, вы можете зарегистрировать глобальный перехватчик респонсов.
@nuxtjs/axios
предоставляет вспомогательные методы для этого. Допустим, мы хотим логировать что-то определённое каждый раз, когда статус ответа равен 404
. Это можно реализовать с помощью метода onResponse
.
$axios.onResponse((response) => {
if (response.status === 404) {
console.log('И вот он, 404 код')
}
})
Итоговый файл плагина axios
В заключение, полный файл плагина (/plugins/axios.js
) со всей конфигурацией, упомянутой в этой статье, может выглядеть примерно так:
export default function ({ $axios, store }, inject) {
const postsApi = $axios.create()
const membersApi = $axios.create()
postsApi.setBaseUrl('https://api.badcode.ru/')
membersApi.setBaseUrl('https://members.badcode.ru/')
const token = store.state.currentUser.token
membersApi.setToken(token, 'Bearer')
membersApi.onResponse((response) => {
if (response.status === 404) {
console.log('И вот он, 404 код')
}
})
inject('postsApi', postsApi)
inject('membersApi', membersApi)
}
Внедрение зависимости axios-клиента в сервис
Очень часто возникает задача - создать класс, решающий определённые задачи, при работе с API. И в таких сервисах всегда нужен HTTP-клиент. Мы могли бы подключить axios
простым импортом в нужном классе, но это не совсем то, что нам нужно.
Идеально было бы в конструктор передавать HTTP-клиент, являющийся абстракцией определённого интерфейса. В результате чего, в каком-то одном месте, мы могли бы подменять реализации HTTP-клиентов.
Или же проще, когда нам нужно просто получить инстанс axios, который создан с помощью плагина (настроены перехватчики, базовый URL и т.д.). Но при обычном импорте мы получаем совершенно другой инстанс. Потому, в этой секции я покажу, как передавать axios в конструктор в качестве зависимости в проекте Nuxt.
Прежде всего, аналогично добавлению плагина axios
, нам нужно создать новый плагин, в котором мы будем объявлять все наши сервисы приложения (читай контейнер). Каждому из сервисов могут потребоваться различные зависимости, будь то API клиент для запросов, библиотека сохранения данных в cookie/localStorage
.
Потому, для примера, создадим plugins/services.js
с таким содержимым:
import PostService from "~/Services/Blog/PostService";
import FavoriteService from "~/Services/Catalog/FavoriteService";
import ConfigService from "~/Services/Shared/ConfigService";
// $cookies - это сторонняя библиотека по работе с cookie (https://www.npmjs.com/package/cookie-universal-nuxt)
export default ({ app: { $axios, $cookies } }, inject) => {
// как зависимость передаём экземпляр axios
inject('postService', new PostService($axios));
inject('favoriteService', new FavoriteService($cookies));
// как зависимость передаём экземпляр axios и библиотеку $cookies
inject('configService', new ConfigService($axios, $cookies));
}
Затем, в файле nuxt.config
нужно подключить созданный плагин.
plugins: [
'~/plugins/axios',
'~/plugins/services.js',
],
И после чего, в контексте приложения Nuxt появятся зарегистрированные в плагине сервисы. Вызвать которые можно несколькими способами:
- через переменную контекста
({ route, redirect, $postService, $configService, store })
- в любом компоненте, или Vuex хранилище -
this.$favoriteService.add(productId)
,this.$configService.getParams()
Резюме
Это был всего лишь краткий обзор того, как можно настроить axios для лучшей разработки приложения на Nuxt.js. Вы можете сделать намного больше и наверняка сможете отрефакторить этот кода и написать идеальный плагин для своих целей.
В этой статье так же было показано, как перехватывать ответ в axios. Так же, разобрались как внедрять зависимости в виде плагина axios в собственные классы.
Надеюсь, вы нашли эту статью полезной.