Nuxt module to merge and transform multiple API + GraphQL requests into a single one, during build-time, like a
payload extractor
.
If you have (like me), too much dispatch
in you nuxtServerInit action, maybe you prefer to merge all of this requests into a single JSON file to speed up, blazing fast your nuxt-website!
This file is generated during the build-process and it's called only once.
In this way, your are also saving and protecting your data because you aren't exposing the .json
file in the static/
dir (you can change this behavior passing a different configuration to the module).
Usually, when you call one or more API π, you're slowing down your website because every single request need to resolve the response (with different TTFB).
Having 3/4 requests in the
nuxtServerInit
or in theasyncData
can increase up to a second the TTFB of your website (causing worse performance audits).
With this module you (and your users) no longer have to wait for this anymore, because everything is resolved during the build-process.
You can use this module for every static, shared or pre-loaded data.
- Add
@luxdamore/nuxt-apis-to-file
dependency to your project; - Add
@luxdamore/nuxt-apis-to-file
to thebuildModules
section of yournuxt.config.js
; - Add the folder
apis-to-json/
to your.gitignore
file.
yarn add @luxdamore/nuxt-apis-to-file # or npm install --save @luxdamore/nuxt-apis-to-file
N.B. : Shallow merge, not deep merge.
// nuxt.config.js
export default {
// Module installation
modules: [ '@luxdamore/nuxt-apis-to-file' ], // nuxt < v2.9
buildModules: [ '@luxdamore/nuxt-apis-to-file' ], // nuxt >= v2.9
// Module config
apisToFile: {
file: {
// The name of the file
name: 'data',
// The extension of the file
ext: 'json',
// The main folder where to save the generated file, you should add this path to your `.gitignore` file
path: 'apis-to-file',
// The `file.path` is always starting from the `srcDir`, but you can force it to the `static/` dir changing this
startFromStaticDir: false,
// Options passed directly to the `outputJson` method of the `fs-extra` library
options: {},
},
// Hide console messages
hideErrorsInConsole: false,
hideGenericMessagesInConsole: false, // default = `! nuxtConfig.dev`
// A sub-folder of `file.path` in which to place the file
dir: null,
// `@nuxtjs/axios` config is automatically injected, but you can override it here
axios: {},
// Your APIs to extract
requests: [
// Every request is passed to an `axios.create` instance
{
skip: false, // skip a request
endpoint: 'https://awesome-api.com/give-me-my-blazing-fast-data', // default = `axios.url`
method: 'get', // default = `axios.method || 'get'`
// The params of the request, you can pass a graph-ql query too, check it in the example folder
body: {},
// Use this to map the response in a custom `key`
field: 'categories', // default = `the actual index in this array of requests`
// Usually, your data is always nested in one or more objects
pathToData: 'data.categories.listCategories.items', // Check `dot-object` to know more
// In case of no-response, what value do you prefer for your empty data?
emptyValue: [],
// Like headers, authentication or everything is required by this request
config: {},
// New, available with version >= 1.2
id: -1, // useful for debugging purpose, default = `the actual index in this array of requests + 1`
// For RECURSIVE api request with lists or nested data, N.B. : RECURSIVE, keep attention
pagination: {
pathBodyToPaginationParamValue: 'variables.nextToken', // [REQUIRED], witch params should update to match the next page? It depends on how you manage the pagination from the BE
pathResponseToTheNextPaginationValue: 'data.categories.listCategories.nextToken', // useful with Graphql, default = null
step: 1, // It always start with the `pathBodyToPaginationParamValue` param if specified, so this is used to increase this numeric value
maxIterations: 15, // Max iterations
lastPaginationValue: null // useful with Graphql, stop the next Iteration if 'pathResponseToTheNextPaginationValue' or 'pathBodyToPaginationParamValue' match this value
},
},
],
},
};
# In this example the *response* is:
`response: {
data: {
categories: {
listCategories: [ DATA ],
},
},
}`,
# but the extracted file is only containing the chosen *pathToData* in the *field* key:
`{ categories: [ DATA ] }`
// store/index.js
export const actions = {
async nuxtServerInit(
{ dispatch },
) {
// usual old-slowly-way
await dispatch(
'items/getItemsCategories', // TTFB + ~200ms π¨
);
await dispatch(
'news/getNewsCategories', // TTFB + ~250ms π±
);
// with the-fastest-new-way of apis-to-json
await dispatch(
'build-data/getDataFromFile', // TTFB .. Guess π€
);
},
};
// Create a module to load the generated file
// store/build-data.js
const getFile = () => import(
'~/apis-to-file/data.json'
).then(
m => m.default || m
);
export const actions = {
async getDataFromFile(
{ commit }
) {
let itemsCategories = []
, newsCategories = []
;
try {
const { categories, otherCategories } = await getFile();
if( categories )
itemsCategories = categories;
if( otherCategories )
newsCategories = otherCategories;
} catch( e ) {
console.error(
{
e,
}
);
}
commit(
'items/SET_ITEMS_CATEGORIES',
itemsCategories,
{
root: true,
}
);
commit(
'news/SET_NEWS_CATEGORIES',
newsCategories,
{
root: true,
}
);
}
};
- Nuxt srcDir;
- Nuxt staticDir;
- Nuxt buildModules;
- fs-extra.outputJson;
pathTo
data handled with dot-notation;- Axios.create;
- @nuxtjs/axios.
- Clone this repository;
- Install dependencies using
yarn install
ornpm install
; - Start development server using
npm run dev
.
Please make sure to read the Issue Reporting Checklist before opening an issue. Issues not conforming to the guidelines may be closed immediately.
Please make sure to read the Contributing Guide before making a pull request.
Details changes for each release are documented in the release notes.
MIT License // Copyright (Β©) 2019-present Luca Iaconelli
If You want to share a beer, we can be really good friends
β It's always a good day to be magnanimous - cit.