Permalink
Browse files

feat(axios): Easier API

  • Loading branch information...
pi0 committed Jun 9, 2017
1 parent 3421d19 commit f54a434fcc01d5ba015234e4bbfca1ef68e9eea4
Showing with 56 additions and 41 deletions.
  1. +31 −9 modules/axios/README.md
  2. +17 −24 modules/axios/index.js
  3. +8 −8 modules/axios/plugin.js
@@ -6,7 +6,7 @@
- Exposes `setToken` function to `$axios` so we can easily and globally set authentication tokens.
- Throws *nuxt-friendly* exceptions and prevent SSR crashes.
- Automatically enables `withCredentials` when requesting to base URL.
- Automatically set request headers in SSR
- Proxy request headers in SSR.

## Setup
- Add `@nuxtjs/axios` dependency using yarn or npm to your project
@@ -85,15 +85,37 @@ export default {
}
```
## Config
Config can be done using environment variables (`proccess.env`), `options.env` or module options.
## Options
You can pass options using module options or `axios` section in `nuxt.config.js`:
Environment variable | Default | Description
---------------------|------------------------------------------------------------------|--------------------------------------------
API_URL | `http://[localhost]:[3000]/api` | Base url for requests in server-side (SSR)
API_URL_BROWSER | `/api` (relative `API_URL` if same host and port else `API_URL`) | Base url for requests in client-side
AXIOS_CREDENTIALS | `true` | Send credentials only to relative and API Backend requests
AXIOS_SSR_HEADERS | `true` | Use client request headers in SSR as axios default headers (useful for cookie based auth)
### `baseURL`
- Default: `http://[HOST]:[PORT]/api`
Base URL is required for requests in server-side & SSR and prepended to all requests with relative path.
You can also use environment variable `API_URL` which **overrides** `baseURL`.
### `browserBaseURL`
- Default: `/api`
Base URL which is used in client side prepended to all requests with relative path.
You can also use environment variable `API_URL_BROWSER` which **overrides** `browserBaseURL`.
- If this options is not provided it defaults to `baseURL` value.
- If both port and hostname of `browserbaseURL` are equal to nuxt server, it defaults to relative part of `baseURL`.
So that if you host your nuxt application is hosted under a different domain requests go to same origin and prevents Cross-Origin problems.
### `credentials`
- Default: `true`
Adds an interceptor to automatically set `withCredentials` config of axios when requesting to `baseUrl`
which allows passing authentication headers to backend.
### `proxyHeaders`
- Default: `true`
Proxies client request headers in SSR to axios default request headers.
This is useful for doing requests which need cookie based auth on server side.
Also Helps making same and consistent requests in both SSR and Client Side code.
## Dynamic API Backend
Please notice that, `API_URL` is saved into bundle on build, CANNOT be changed
@@ -5,35 +5,28 @@ const { URL } = require('url')
const port = process.env.PORT || process.env.npm_package_config_nuxt_port || 3000
const host = process.env.HOST || process.env.npm_package_config_nuxt_host || 'localhost'

module.exports = function nuxtAxios (options) {
// Get options
const getOpt = (key, default_val) => {
return process.env[key] || options[key] || options[key.toLowerCase()] || this.options.env[key] || default_val
module.exports = function nuxtAxios (moduleOptions) {
// Apply defaults
const options = Object.assign({
baseURL: process.env.API_URL || `http://${host}:${port}/api`,
browserBaseURL: null,
credentials: true,
proxyHeaders: true
}, this.options.axios, moduleOptions)

if (process.env.API_URL) {
options.baseURL = process.env.API_URL
}

const API_URL = getOpt('API_URL', `http://${host}:${port}/api`)
const url = new URL(API_URL)
const sameHost = url.host === `${host}:${port}`

const API_URL_BROWSER = getOpt('API_URL_BROWSER', sameHost ? url.pathname : API_URL)

// Commit new values to all sources
const setOpt = (key, val, env = true) => {
process.env[key] = val
options[key] = val
if (env) {
this.options.env[key] = val
}
if (process.env.API_URL_BROWSER) {
options.browserBaseURL = process.env.API_URL_BROWSER
}
setOpt('API_URL', API_URL)
setOpt('API_URL_BROWSER', API_URL_BROWSER)

// Other options
const ensureOpt = (key, default_val) => {
setOpt(key, getOpt(key, default_val), false)
if (!options.api_url_browser) {
const url = new URL(options.url)
const sameHost = url.host === `${host}:${port}`
options.api_url_browser = sameHost ? url.pathname : options.url
}
ensureOpt('AXIOS_CREDENTIALS', true)
ensureOpt('AXIOS_SSR_HEADERS', true)

// Register plugin
this.addPlugin({
@@ -3,10 +3,11 @@ import Vue from 'vue'

const axiosPlugin = {
install() {
if(this.installed) {
if(Vue.__nuxt_axios_installed__) {
return
}
this.installed = true
Vue.__nuxt_axios_installed__ = true

// Make `this.$axios` available
if (!Vue.prototype.hasOwnProperty('$axios')) {
// Add mixin to add this._axios
@@ -87,7 +88,6 @@ function errorHandler(error) {
error.statusCode = 500
error.message = error.message || 'axios error'
}

// Display error page on unhandled promises
if(process.browser) {
return Promise.reject(error)
@@ -101,18 +101,18 @@ function errorHandler(error) {
}

export default (ctx) => {
const { app, store, redirect, req } = ctx
const { app, store, req } = ctx

// Create new axios instance
const baseURL = process.browser
? (process.env.API_URL_BROWSER || '<%= options.API_URL_BROWSER %>')
: (process.env.API_URL || '<%= options.API_URL %>')
? (process.env.API_URL_BROWSER || '<%= options.browserBaseURL %>')
: (process.env.API_URL || '<%= options.baseURL %>')

const axios = Axios.create({
baseURL,
<% if(options.AXIOS_SSR_HEADERS) { %>headers: (req && req.headers) ? req.headers : {} <% } %>
<% if(options.proxyHeaders) { %>headers: (req && req.headers) ? req.headers : {} <% } %>
})
<% if(options.AXIOS_CREDENTIALS) { %>
<% if(options.credentials) { %>
// Send credentials only to relative and API Backend requests
axios.interceptors.request.use(config => {
if (config.withCredentials === undefined) {

0 comments on commit f54a434

Please sign in to comment.