Wondering what’s next for npm?Check out our public roadmap! »

    hal-json-vuex

    1.2.2 • Public • Published

    hal-json-vuex

    npm version Downloads Build Status Coverage Status

    A package to access HAL JSON data from an API, using a Vuex store, restructured to make life easier.

    With this plugin, you can use your HAL JSON API in a fluid way:

    // Reading data and traversing relationships
    let singleBook = this.api.get('/books/1')
    let firstBookName = this.api.get().books().items[0].name // visits the 'books' rel on the root API endpoint
    let author = singleBook.author() // related entity
    let bookChapters = this.api().books().items[0].chapters()
    author = singleBook.author() // doesn't trigger another network call because we already fetched it
    this.api.reload(author) // force re-fetching an entity or a URI
    
    // Writing data
    this.api.post('/books', { name: 'My first book', author: { _links: { self: '/users/433' } } })
    this.api.patch(singleBook, { name: 'Single book - volume 2' })
    this.api.del(author).then(() => { /* do something */ })

    This library will only load data from the API when necessary (i.e. if the data is not yet in the Vuex store). It also supports templated links and partially loaded data from the API.

    Installation

    npm install hal-json-vuex

    Usage

    import Vue from 'vue'
    import Vuex from 'vuex'
    import axios from 'axios'
    import HalJsonVuex from 'hal-json-vuex'
    
    Vue.use(Vuex)
    
    const store = new Vuex.Store({})
    
    axios.defaults.baseURL = 'https://my-api.com/api'
    
    Vue.use(HalJsonVuex(store, axios, { /* options */ }))
    // Use it in a computed or method or lifecycle hook of a Vue component
    let someEntity = this.api.get('/some/endpoint')
    this.api.reload(someEntity)
    <!-- Use it in the <template> part of a Vue component -->
    <li v-for="book in api.get('/all/my/books').items" :key="book._meta.self">...</li>

    Nuxt.js (experimental support)

    To install in a Nuxt.js application:

    // First, make sure the Nuxt.js app uses Vuex, by adding an index.js to your store/ directory.
    
    // Then, create a file plugins/hal-json-vuex.js with the following content:
    import Vue from 'vue'
    import HalJsonVuex from 'hal-json-vuex'
    
    export default function ({ store, $axios }, nuxtInject) {
      if (!Vue.$api) {
        Vue.use(HalJsonVuex(store, $axios, { nuxtInject }))
      }
    }
    
    // Add the plugin to nuxt.config.js:
    export default {
      plugins: [
        { src: '~/plugins/hal-json-vuex.js' }
      ],
      // ...
    }

    Then, you can use $api on both the server side and the client side:

    // On the server
    async asyncData({ $api }) {
      const books = await $api.get().books()._meta.load
      return { books }
    }
    // On the client, in a computed or method or lifecycle hook of a Vue component
    let someEntity = this.$api.get('/some/endpoint')
    <!-- On the client, in the <template> part of a Vue component -->
    <li v-for="book in $api.get('/all/my/books').items" :key="book._meta.self">...</li>

    Available options

    apiName

    This package will install a module into your Vuex store, as well as an accessor (this.api) into your Vue prototype. These are by default called api, but in case you want to change that or need to support multiple APIs at the same time, you can use the apiName option:

    Vue.use(HalJsonVuex(store, axios, { apiName: 'backend' }))
    
    // In a Vue component
    let someEntity = this.backend.get('/some/endpoint')

    avoidNPlusOneRequests

    When accessing the elements of an embedded collection, and some of the elements of the collection have not been loaded from the API before, this library will automatically try to avoid N+1 queries by eager fetching the whole collection. In case you run into problems with this behaviour with your API, you can disable it by setting the avoidNPlusOneRequests option to false:

    Vue.use(HalJsonVuex(store, axios, { avoidNPlusOneRequests: false }))

    forceRequestedSelfLink

    When requesting an entity, some HAL JSON APIs will not always return the same self link as it was in the request. An example would be if the API added a page=0 query parameter to the self link of a collection, even if the request was done without that parameter:

    // request
    GET /all/my/books
    
    // response JSON from the API
    {
      "_embedded": {
        "items": [ ... ]
      },
      "_links": {
        "self": {
          "href": "/all/my/books?page=0"
        }
      }
    }
    

    This can lead to problems, because in your component template you might be requesting /all/my/books but that URI never appears in your Vuex store, causing an infinite loop of re-fetching the same URI.

    In case your backend API does this, you can set the forceRequestedSelfLink option to true, and the top-level self link in all responses will be overwritten to the link that was actually requested.

    Vue.use(HalJsonVuex(store, axios, { forceRequestedSelfLink: true }))

    Install

    npm i hal-json-vuex

    DownloadsWeekly Downloads

    327

    Version

    1.2.2

    License

    MIT

    Unpacked Size

    90.6 kB

    Total Files

    8

    Last publish

    Collaborators

    • avatar