diff --git a/README.md b/README.md index 80ce12f..41254cf 100755 --- a/README.md +++ b/README.md @@ -29,6 +29,13 @@ 1. Clone this repository 2. Install dependencies using `yarn install` 3. Start development server using `yarn dev` +4. Then go for instance to `http://localhost:3000/mounted` + +## 📖 Contribute to the documentation + +1. Go into the docs folder +2. Install dependencies using `yarn install` +3. Start development server using `yarn dev` ## 📑 License diff --git a/docs/content/en/advanced.md b/docs/content/en/advanced.md index 63d987c..680f47a 100644 --- a/docs/content/en/advanced.md +++ b/docs/content/en/advanced.md @@ -1,7 +1,7 @@ --- title: Advanced description: 'Advanced concepts' -position: 4 +position: 5 category: Getting Started --- @@ -61,7 +61,7 @@ This method should probably not be called inside hooks as it is global and will - + Please note that HTTP headers are case-insensitive. Therefore all header names will be converted to lower-case to make sure that if you set the same header twice but with different casing the last one set will be used. @@ -92,7 +92,7 @@ this.$http.setHeader('Content-Type', false) Globally set `Authorization` header to all subsequent requests. - + This is a global method, you only have to call it once after which all future requests will include the token diff --git a/docs/content/en/helpers.md b/docs/content/en/helpers.md index fcae421..5512a4a 100644 --- a/docs/content/en/helpers.md +++ b/docs/content/en/helpers.md @@ -5,7 +5,7 @@ position: 7 category: API --- - + Helpers available on `$http` instance. @@ -38,6 +38,12 @@ if (process.server) { Globally set a header to all subsequent requests +**Example: ** +```js +// Add header `Content-Type: application/json` +this.$http.setHeader('Content-Type', 'application/json') +``` + See [here](/advanced#header-helpers) for usage. ## `setToken` @@ -46,10 +52,15 @@ See [here](/advanced#header-helpers) for usage. Globally set a `Authorization` header for all subsequent requests. +```js +// Adds header: `Authorization: Bearer 123` to all requests +this.$http.setToken('123', 'Bearer') +``` + See [here](/advanced#settokentoken-type) for usage. ## `create` - arguments: `(kyOptions)` -Create a new KY instance based on defaults, see [create new instance based on defaults](/guide/advanced.html#create-new-instance-based-on-defaults) for usage. +Create a new KY instance based on defaults, see [create new instance based on defaults](/advanced#create-new-instance-based-on-defaults) for usage. diff --git a/docs/content/en/hooks.md b/docs/content/en/hooks.md index 289d8f6..a37c513 100644 --- a/docs/content/en/hooks.md +++ b/docs/content/en/hooks.md @@ -11,13 +11,33 @@ The `arguments` listed below are those your hook will receive when it's called. - arguments: `(config)` -See [here](/advanced#hooks) for usage. +**Example: ** +```js{}[plugins/http.js] +export default function ({ $http }) { + $http.onRequest(config => { + console.log('Making request to ' + config.url) + }) +} +``` + +See [here](/advanced#hooks) for advanced usage. ## `onResponse` - arguments: `(response)` -See [here](/advanced#hooks) for usage. +**Example: ** +```js{}[plugins/http.js] +export default function ({ $http }) { + $http.onResponse((req, options, res) => { + console.log('Making request to ' + req.url) + console.log('Options :', options) + console.log('Response data :', res.body) + }) +} +``` + +See [here](/advanced#hooks) for advanced usage. ## `onError` @@ -25,6 +45,18 @@ See [here](/advanced#hooks) for usage. If the error originated from a request. +**Example: ** +```js{}[plugins/http.js] +export default function ({ $http, redirect }) { + $http.onError((err) => { + // In case of unauthorized, redirect to a specific page + if (error.statusCode === 401) { + redirect('/401') + } + }) +} +``` + Available properties: - `error.statusCode` (may be undefined) @@ -32,4 +64,4 @@ Available properties: You can optionally return a value or promise that can resolve for fallback response. If hook returns any value, other hooks **won't** be called. -See [here](/advanced#hooks) for usage. +See [here](/advanced#hooks) for advanced usage. diff --git a/docs/content/en/http-methods.md b/docs/content/en/http-methods.md index ac4dd92..2297532 100644 --- a/docs/content/en/http-methods.md +++ b/docs/content/en/http-methods.md @@ -1,58 +1,272 @@ --- title: HTTP Methods description: 'HTTP Methods' -position: 9 -category: API +position: 4 +category: Getting Started --- - - -See [here](/guide/usage.html#making-requests) for usage information for below methods. - - - - + Each http method returns a `Promise` -### `delete` -### `get` -### `head` - +### `$get` - arguments: `(url, options?)` + - url: `String` + - options: [options](/options) +- resolves: [JSON](https://developer.mozilla.org/en-US/docs/Web/API/Body/json) if [destr](https://github.com/nuxt-contrib/destr) can convert automatically, otherwise fallback to String +- rejects: `Error` + +**Examples:** + +```js +const package = await $http.$get('https://unpkg.com/nuxt/package.json') +``` + +```js +// With prefixUrl option to call `https://example.com/items` +const items = await $http.$get('items', { prefixUrl: 'https://example.com' }) +``` + +### `$post` +- arguments: `(url, body?, options?)` + - url: `String` + - body: `Object` + - options: [options](/options) +- resolves: [JSON](https://developer.mozilla.org/en-US/docs/Web/API/Body/json) if [destr](https://github.com/nuxt-contrib/destr) can convert automatically, otherwise fallback to String +- rejects: `Error` + +**Examples:** + +```js +const data = await $http.$post('http://api.com', { foo: 'bar' }) +``` + +```js +// With some additional options +const data = await $http.$post('http://api.com', { foo: 'bar' }, { + debug: true, + retry: 2, + serverTimeout: 5000 +}) +``` + +### `$put` +- arguments: `(url, body?, options?)` + - url: `String` + - body: `Object` + - options: [options](/options) +- resolves: [JSON](https://developer.mozilla.org/en-US/docs/Web/API/Body/json) if [destr](https://github.com/nuxt-contrib/destr) can convert automatically, otherwise fallback to String +- rejects: `Error` + +**Examples:** + +```js +const data = await $http.$put('http://api.com/{id}', { foo: 'bar' }) +``` + +```js +// With some additional option +const data = await $http.$put('http://api.com/{id}', { foo: 'bar' }, { + clientTimeout: 5000 +}) +``` + +### `$delete` +- arguments: `(url, options?)` + - url: `String` + - options: [options](/options) +- resolves: [JSON](https://developer.mozilla.org/en-US/docs/Web/API/Body/json) if [destr](https://github.com/nuxt-contrib/destr) can convert automatically, otherwise fallback to String +- rejects: `Error` + +**Example:** + +```js +await $http.$delete('https://api.example.com/item/{id}') +``` + +```js +// With some options to call `https://example.com/api/item` +const jsonResponse = await $http.$delete('item/{id}', { + baseUrl: 'https://example.com', + prefixUrl: '/api' +}) +``` + +### `$patch` +- arguments: `(url, body?, options?)` + - url: `String` + - body: `Object` + - options: [options](/options) +- resolves: [JSON](https://developer.mozilla.org/en-US/docs/Web/API/Body/json) if [destr](https://github.com/nuxt-contrib/destr) can convert automatically, otherwise fallback to String +- rejects: `Error` + +**Examples: ** + +```js +const data = await $http.$patch('http://api.com/{id}', { foo: 'bar' }) +``` + +```js +// With some additional option +const data = await $http.$patch('http://api.com/{id}', { foo: 'bar' }, { + proxyHeaders: true, + proxyHeadersIgnore: ['content-type'] +}) +``` + +### `$head` +- arguments: `(url, options?)` + - url: `String` + - options: [options](/options) +- resolves: - +- rejects: `Error` + +### `get` +- arguments: `(url, options?)` + - url: `String` + - options: [options](/options) - resolves: [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) - rejects: `Error` +**Examples:** + +```js +const response = await $http.get('https://unpkg.com/nuxt/package.json') +const jsonResponse = await response.json() +``` + +```js +// With prefixUrl option to call `https://example.com/items` +const response = await $http.get('items', { prefixUrl: 'https://example.com' }) +const textResponse = await response.text() +``` + +See [`here`](/usage#making-requests) to convert response stream into usable data. + +These methods corresponds to the similar named HTTP/1.1 methods. + +### `post` +- arguments: `(url, body?, options?)` + - url: `String` + - body: `Object` + - options: [options](/options) +- resolves: [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) +- rejects: `Error` + +**Examples: ** + +```js +const response = await $http.post('http://api.com', { foo: 'bar' }) +const jsonResponse = await response.json() +``` + +```js +// With some additional options +const response = await $http.post('http://api.com', { foo: 'bar' }, { + debug: true, + retry: 2, + serverTimeout: 5000 +}) +const jsonResponse = await response.json() +``` + +See [`here`](/usage#making-requests) to convert response stream into usable data. + +These methods corresponds to the similar named HTTP/1.1 methods. + +### `put` +- arguments: `(url, body?, options?)` + - url: `String` + - body: `Object` + - options: [options](/options) +- resolves: [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) +- rejects: `Error` + +**Examples:** + +```js +const response = await $http.put('http://api.com/{id}', { foo: 'bar' }) +const jsonResponse = await response.json() +``` + +```js +// With some additional option +const response = await $http.put('http://api.com/{id}', { foo: 'bar' }, { + clientTimeout: 5000 +}) +const jsonResponse = await response.json() +``` + +See [`here`](/usage#making-requests) to convert response stream into usable data. + +These methods corresponds to the similar named HTTP/1.1 methods. + +### `delete` +- arguments: `(url, options?)` + - url: `String` + - options: [options](/options) +- resolves: [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) +- rejects: `Error` + +**Example:** + +```js +await $http.delete('https://api.example.com/item/{id}') +``` + +```js +// With some options to call `https://example.com/api/item` +const response = await $http.delete('item/{id}', { + baseUrl: 'https://example.com', + prefixUrl: '/api' +}) +``` + +See [`here`](/usage#making-requests) to convert response stream into usable data. + These methods corresponds to the similar named HTTP/1.1 methods. ### `patch` -### `post` -### `put` - - arguments: `(url, body?, options?)` + - url: `String` + - body: `Object` + - options: [options](/options) - resolves: [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) - rejects: `Error` +**Examples:** + +```js +const response = await $http.patch('http://api.com/{id}', { foo: 'bar' }) +const jsonResponse = await response.json() +``` + +```js +// With some additional option +const response = await $http.patch('http://api.com/{id}', { foo: 'bar' }, { + proxyHeaders: true, + proxyHeadersIgnore: ['content-type'] +}) +const jsonResponse = await response.json() +``` + +See [`here`](/usage#making-requests) to convert response stream into usable data. + These methods corresponds to the similar named HTTP/1.1 methods. -### `$delete` -### `$get` -### `$head` - +### `head` - arguments: `(url, options?)` -- resolves: `JSON` + - url: `String` + - options: [options](/options) +- resolves: [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) - rejects: `Error` -These `$`-prefixed convenience methods always return the requested content as [`JSON`](https://developer.mozilla.org/en-US/docs/Web/API/Body/json). +**Example:** -### `$patch` -### `$post` -### `$put` +```js +await $http.head('https://unpkg.com/nuxt/package.json') +``` -- arguments: `(url, body?, options?)` -- resolves: `JSON` -- rejects: `Error` - -These `$`-prefixed convenience methods always return the requested content as [`JSON`](https://developer.mozilla.org/en-US/docs/Web/API/Body/json). +These methods corresponds to the similar named HTTP/1.1 methods. diff --git a/docs/content/en/index.md b/docs/content/en/index.md index 5e314b4..40eafc5 100644 --- a/docs/content/en/index.md +++ b/docs/content/en/index.md @@ -3,7 +3,6 @@ title: Introduction description: 'HTTP module for Nuxt.js provides a universal way to make HTTP requests to the API backend.' position: 1 category: '' -menuTitle: 'Intro' features: - The fluent ky API has been extended with enhancements and shortcuts - Highly customizable options support for `BaseURL` @@ -12,14 +11,16 @@ features: - Easy proxy support to avoid CORS problems and making deployment easier --- - - + + -HTTP module for Nuxt.js provides a universal way to make HTTP requests to the API backend. +The HTTP module for [Nuxt](https://nuxtjs.org) provides a universal way to make HTTP requests to any API. -This module is an alternative to [Axios Module](https://github.com/nuxt-community/axios-module). Behind the scenes it use [ky-universal](https://github.com/sindresorhus/ky-universal) and [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) to make HTTP requests. Please see the [migration guide](./migration) if you are currently using axios module and wish to migrate. +It uses [ky-universal](https://github.com/sindresorhus/ky-universal) and [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) to make HTTP requests. Please see the [migration guide](./migration) if you are currently using axios module and wish to migrate. -Starting from [v2.5.0](https://github.com/nuxt/nuxt.js/releases/tag/v2.5.0), Nuxt.js has built-in support for universal fetch. However, this module provides several advantages: +Starting from [v2.5.0](https://github.com/nuxt/nuxt.js/releases/tag/v2.5.0), Nuxt.js has built-in support for universal fetch. However, this module provides several advantages. + +> This module is an alternative to the [Axios module](https://axios.nuxtjs.org). ## Features diff --git a/docs/content/en/migration.md b/docs/content/en/migration.md index bcea3bd..21e22d3 100644 --- a/docs/content/en/migration.md +++ b/docs/content/en/migration.md @@ -7,7 +7,7 @@ category: Migration This guide will help you to migrate from [Axios Module](https://github.com/nuxt-community/axios-module). - + The nuxt-community axios module is still supported and maintained. The HTTP module uses newer web technologies like fetch which might be beneficial @@ -22,7 +22,7 @@ _Use the [`onError`](/hooks#onerror) hook instead_ - The http module does not have a `debug` option like the axios module
_You can setup a basic logger using the [`onRequest`](/hooks#onrequest) hook_ - Progress bar integration is not supported (for the moment)
-_This option may be added again once [`PR #34: Add 'onProgress' option`](https://github.com/sindresorhus/ky/pull/34) for ky is merged_ +_This option may be added again once [`PR #105 : progress bar`](https://github.com/nuxt/http/pull/105) is merged_ ## Response body parsing diff --git a/docs/content/en/options.md b/docs/content/en/options.md index 30c692c..654c4ac 100644 --- a/docs/content/en/options.md +++ b/docs/content/en/options.md @@ -33,7 +33,7 @@ Base URL which is used and prepended to make requests in server side. Environment variable `API_URL` can be used to **override** `baseURL`. - + `baseURL` and `proxy` won't work together, you will need to use [`prefix`](/options#prefix) instead @@ -84,13 +84,13 @@ You can easily integrate HTTP with [Proxy Module](https://github.com/nuxt-commun } ``` - + It is not required to manually register `@nuxtjs/proxy` module, but it does need to be in your dependencies - + `/api/` will be added to all requests to the API end point. If you need to remove it use `pathRewrite`: @@ -153,7 +153,7 @@ In SSR context, sets client request header as http default request headers. This is useful for making requests which need cookie based auth on server side. Also helps making consistent requests in both SSR and Client Side code. - + When directing requests at a url protected by CloudFlare's CDN you should set this to `false` to prevent CloudFlare from mistakenly detecting a reverse proxy loop and returning a 403 error. @@ -171,13 +171,13 @@ Headers added to all requests. If provided, will be merged with the defaults. * Default: `{}` - + Do NOT include any credentials or tokens here. One can easily access them. - + This headers are effective to ALL requests. Please take care and consider providing special headers on each call that needs this unless you are pretty sure you always need to add headers. diff --git a/docs/content/en/setup.md b/docs/content/en/setup.md index 052c96c..75deef9 100644 --- a/docs/content/en/setup.md +++ b/docs/content/en/setup.md @@ -5,21 +5,42 @@ position: 2 category: Getting Started --- -Check the [Nuxt.js documentation](https://nuxtjs.org/api/configuration-modules#the-modules-property) for more information about installing and using modules in Nuxt.js +Checkout the [Nuxt documentation](https://nuxtjs.org/api/configuration-modules#the-modules-property) for more information about installing and using modules. ## Install -Install with yarn: +Add `@nuxt/http` dependency to your project: -```bash -yarn add @nuxt/http + + + + ```bash + yarn add @nuxt/http + ``` + + + + + ```bash + npm install @nuxt/http + ``` + + + + +Then add it to the modules section in your `nuxt.config.js`: + +```js{}[nuxt.config.js] +export default { + modules: ['@nuxt/http'] +} ``` -Install with npm: + -```bash -npm install @nuxt/http -``` +That's it! You can now use [$http](/usage) in your Nuxt app ✨ + + ## Configure diff --git a/docs/content/en/usage.md b/docs/content/en/usage.md index 1ed2ebf..f25c08d 100644 --- a/docs/content/en/usage.md +++ b/docs/content/en/usage.md @@ -7,12 +7,11 @@ category: Getting Started ## Making Requests -See the [API reference](/http-methods) for a list of available HTTP methods +See the list of [available HTTP methods](/http-methods). -Calling a HTTP methods returns a Promise that resolves to a [Reponse](https://developer.mozilla.org/en-US/docs/Web/API/Response) object or rejects in case of network errors. +Calling a HTTP methods returns a `Promise` that resolves to a [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) object or rejects in case of network errors. You can use methods to convert response stream into usable data: - - `json` - `text` - `formData` @@ -24,20 +23,53 @@ See [ky](https://github.com/sindresorhus/ky#options) docs for all available opti **Example: GET JSON data** ```js -const res = await $http.get('https://unpkg.com/nuxt/package.json') -const data = await res.json() +const package = await $http.$get('https://unpkg.com/nuxt/package.json') + +console.log(package.name) // log "nuxt" ``` -Alternatively for json only you can use `$` prefixed shortcut that smartly parses response using [destr](https://github.com/nuxt-contrib/destr). +In most of the case, you want to get the JSON response. You can use `$` prefixed shortcut that smartly parses response using [destr](https://github.com/nuxt-contrib/destr). + +Alternatively for other response type, you can use the methods mentioned above: + +**Example: GET data as `text`** ```js -await $http.$get('https://unpkg.com/nuxt/package.json') +const res = await $http.get('https://unpkg.com/nuxt/package.json') +const responseText = await res.text() +``` + +**Example: GET data as `arrayBuffer`** +```js +const response = await this.$http.get('https://nuxtjs.org/logos/nuxt.svg') +const buffer = await response.arrayBuffer() +console.log('buffer.byteLength = ', buffer.byteLength) +``` + +**Example: GET data as `readable stream`** +```js +const response = await this.$http.get('https://example.org') +const reader = response.body.getReader() + +let result = '' +reader.read().then(function process ({ done, value }) { + if (done) { + console.log('Stream complete result =>', result) + return + } + + const decoder = new TextDecoder('utf-8') + result += decoder.decode(value, { stream: true }) + + // Read some more, and call this function again + return reader.read().then(process) +}) ``` **Example: POST with JSON body** ```js -await $http.post('http://api.con', { foo: 'bar' }) +const data = await $http.$post('http://api.com', { foo: 'bar' }) ``` ## Using in `asyncData` @@ -46,42 +78,41 @@ For `asyncData` and `fetch` you can access instance from context: ```js async asyncData({ $http }) { - const res = await $http.get('http://icanhazip.com') + const res = await $http.get('https://icanhazip.com') const ip = await res.text() + return { ip } } ``` -**Example: GET JSON data using prefixed** +**Example: GET JSON data using $ helper** ```js async asyncData({ $http }) { const users = await $http.$get('https://reqres.in/api/users') + return { users } } ``` - ## Using in Component Methods - - -`this` is not available in Nuxt's `asyncData` method, see [using in `asyncData`](#using-in-asyncdata) for how to use this module in `asyncData` - - - When you have access to `this`, you can use `this.$http`: ```js methods: { async fetchSomething() { - const res = await this.$http.get('http://icanhazip.com') - const ip = await res.text() - this.ip = ip + this.ip = await this.$http.$get('https://icanhazip.com') } } ``` + + +`this` is not available in Nuxt's `asyncData` method, see [using in `asyncData`](#using-in-asyncdata) for how to use this module in `asyncData` + + + ## Using in Store For store actions you can also use `this.$http`: @@ -91,8 +122,8 @@ For store actions you can also use `this.$http`: { actions: { async getIP ({ commit }) { - const res = await this.$http.get('http://icanhazip.com') - const ip = await res.text() + const ip = await this.$http.$get('https://icanhazip.com') + commit('SET_IP', ip) } } diff --git a/docs/static/preview-dark.png b/docs/static/preview-dark.png index b3e6040..983bbbe 100644 Binary files a/docs/static/preview-dark.png and b/docs/static/preview-dark.png differ diff --git a/docs/static/preview.png b/docs/static/preview.png index d22879f..f5a683f 100644 Binary files a/docs/static/preview.png and b/docs/static/preview.png differ diff --git a/test/fixture/pages/index.vue b/test/fixture/pages/index.vue new file mode 100644 index 0000000..271d659 --- /dev/null +++ b/test/fixture/pages/index.vue @@ -0,0 +1,22 @@ + + + diff --git a/test/fixture/pages/mounted.vue b/test/fixture/pages/mounted.vue index ec08609..ea6bb65 100644 --- a/test/fixture/pages/mounted.vue +++ b/test/fixture/pages/mounted.vue @@ -13,7 +13,7 @@ export default { }, async mounted() { - // Request with full url becasue we are in JSDom env + // Request with full url because we are in JSDom env this.res = await this.$http.$get('http://localhost:3000/test_api/foo/bar') } } diff --git a/test/module.test.js b/test/module.test.js index 6fb2572..8bd6452 100644 --- a/test/module.test.js +++ b/test/module.test.js @@ -30,6 +30,12 @@ describe('module', () => { expect(html).toContain('foo/bar') }) + test('index', async () => { + const page = await browser.page(url('/')) + const html = await page.getHtml() + expect(html).toContain('foo/bar') + }) + test('defaults', async () => { const page = await browser.page(url('/mounted')) const defaults = await page.runScript(() => window.$nuxt.$http._defaults)