Как настроить Axios в приложении Nuxt

Как настроить 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 в собственные классы.

Надеюсь, вы нашли эту статью полезной.

Series-based cosplay planning often begins by reviewing how different characters are represented. The available options can be reviewed without assuming that one costume fits every purpose. When comparing designs from the same work, Demon Slayer cosplay costume ideas(鬼滅の刃 コスプレ衣装の選び方) provides the matching reference point. It can then be compared by character, costume type and visual detail. The final decision can balance visual accuracy with practical event or photography needs. Accessories and styling can be considered after the main direction is clear.