Skip to content

Commit

Permalink
feat: pagination with recursive api
Browse files Browse the repository at this point in the history
  • Loading branch information
LuXDAmore committed Oct 6, 2020
1 parent 56da64e commit 239d9d7
Show file tree
Hide file tree
Showing 16 changed files with 884 additions and 158 deletions.
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,18 +95,29 @@ ___
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',
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 after with version >= 1.2
id: -1, // useful for debugging purpose, default = `the actual index in this array of requests + 1`
// For recursive api calls with lists or nested data
pagination: {
pathBodyToPaginationParamValue: 'variables.nextToken', // [REQUIRED]
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 deep of iterations
lastPaginationValue: null // stop the recursion if 'pathResponseToTheNextPaginationValue' or 'pathBodyToPaginationParamValue' is this value, and is useful to stop the Iteration if the next value is matched
},
},
],
},
Expand Down Expand Up @@ -223,6 +234,7 @@ ___
- Nuxt [staticDir](https://nuxtjs.org/api/configuration-dir/);
- Nuxt [buildModules](https://nuxtjs.org/guide/modules/#build-only-modules);
- [fs-extra.outputJson](https://github.com/jprichardson/node-fs-extra/blob/master/docs/outputJson.md);
- `pathTo` data handled with [dot-notation](https://github.com/rhalff/dot-object);
- [Axios.create](https://github.com/axios/axios#creating-an-instance);
- [@nuxtjs/axios](https://axios.nuxtjs.org/).

Expand Down
154 changes: 151 additions & 3 deletions example/nuxt.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,67 @@ import { resolve } from 'path';
import * as PACKAGE from '../package.json';

// GraphQL RAW Queries
import { GRAPHQL, LOCATIONS } from './graphql';
import {
GRAPHQL,
LOCATIONS,
} from './graphql';

// Configuration
const apisToFile = {
axios: {
baseURL: 'https://jsonplaceholder.typicode.com',
},
requests: [
// Rest API
{
endpoint: '/posts',
field: 'posts',
body: {
params: {
'_page': 1,
'_limit': 10,
},
},
},
{
endpoint: '/posts',
field: 'postsPaginated',
body: {
params: {
'_page': 1,
'_limit': 10,
},
},
// New settings
pagination: {
pathBodyToPaginationParamValue: 'params._page',
maxIterations: 3,
},
},
{
endpoint: '/comments',
field: 'comments',
body: {
params: {
'_limit': 10,
},
},
},
{
endpoint: '/comments',
field: 'commentsPaginated',
body: {
params: {
'_page': 1,
'_limit': 15,
},
},
// New settings
pagination: {
pathBodyToPaginationParamValue: 'params._page',
step: 2,
lastPaginationValue: 7,
},
},
// GraphQL
{
Expand All @@ -31,7 +77,7 @@ const apisToFile = {
{
endpoint: 'https://kdonz3bavvbbhmocoletnw4w2q.appsync-api.eu-west-1.amazonaws.com/graphql',
method: 'post',
field: 'locations',
field: 'graphqlLocations',
pathToData: 'data.listLocations',
config: {
headers: {
Expand All @@ -42,7 +88,25 @@ const apisToFile = {
},
emptyValue: {},
body: LOCATIONS,
},
{
endpoint: 'https://kdonz3bavvbbhmocoletnw4w2q.appsync-api.eu-west-1.amazonaws.com/graphql',
method: 'post',
field: 'graphqlLocationsPaginated',
pathToData: 'data.listLocations.items',
config: {
headers: {
'Content-Type': 'application/json',
'x-api-key': 'da2-jy2nym3ybbgubehdqhf5rjgbxq',
'x-region': 'eu-west-1',
},
},
body: LOCATIONS,
// New settings
pagination: {
pathResponseToTheNextPaginationValue: 'data.listLocations.nextToken',
pathBodyToPaginationParamValue: 'variables.nextToken',
},
},
],
};
Expand All @@ -51,7 +115,7 @@ const apisToFile = {
export default {
// Plugin options
apisToFile,
// Other options
// Options
modern: true,
srcDir: __dirname,
rootDir: resolve(
Expand All @@ -68,11 +132,34 @@ export default {
'../lib/module'
),
],
watch: [
resolve(
__dirname,
'../lib/module'
),
],
// Meta
head: {
htmlAttrs: {
lang: 'en',
},
title: PACKAGE.name,
link: [
{
once: true,
hid: 'favicon',
rel: 'shortcut icon',
type: 'image/x-icon',
href: '/favicon.ico',
},
{
once: true,
hid: 'humans',
rel: 'author',
type: 'text/plain',
href: '/humans.txt',
},
],
meta: [
{
once: true,
Expand Down Expand Up @@ -101,6 +188,67 @@ export default {
'../docs'
),
},
/*
* Build
*/
build: {
loaders: {
vue: {
compilerOptions: {
preserveWhitespace: false,
whitespace: 'condense',
},
},
},
/*
** Minifier
*/
html: {
minify: {
collapseBooleanAttributes: true,
decodeEntities: true,
minifyCSS: true,
minifyJS: true,
processConditionalComments: true,
collapseInlineTagWhitespace: true,
removeOptionalTags: true,
removeAttributeQuotes: true,
removeEmptyAttributes: true,
removeRedundantAttributes: true,
trimCustomFragments: true,
useShortDoctype: true,
collapseWhitespace: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
removeComments: true,
continueOnParseError: true,
},
},
/*
** Run lint on save
*/
extend(
config,
{
isDev,
isClient,
},
) {

/*
** ESLint loaded
*/
isDev && isClient && config.module.rules.push(
{
enforce: 'pre',
test: /\.(js|vue)$/,
loader: 'eslint-loader',
exclude: /(node_modules)/,
},
);

},
},
/*
* Server
*/
Expand Down
30 changes: 30 additions & 0 deletions example/pages/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.page h3,
.page p {

display: block;
width: 100%;
max-width: 500px;
margin: 0;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;

}

.page h3 {

margin-top: 16px;

}

.page em {

display: block;

}

.page button {

margin: 32px;

}
55 changes: 48 additions & 7 deletions example/pages/index.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,31 @@
<template>
<main>
<main class="page">
<h1>NUXT Apis to file</h1>
<h2>Nuxt module to merge and transform API calls into a single file, during the build phase.. Like a payload extractor</h2>
<hr>
<!-- Rest API -->
<section class="posts">
<h3>
<strong>Total number of posts preloaded:</strong>
</h3>
<p v-if="$store.state.posts && $store.state.posts.items && $store.state.posts.items.length">
<em
class="number"
v-text="$store.state.posts.items.length"
/>
</p>
</section>
<section class="posts-paginated">
<h3>
<strong>Total number of posts (paginated) preloaded:</strong>
</h3>
<p v-if="$store.state.posts && $store.state.posts.paginated && $store.state.posts.paginated.length">
<em
class="number"
v-text="$store.state.posts.paginated.length"
/>
</p>
</section>
<section class="comments">
<h3>
<strong>Total number of comments preloaded:</strong>
Expand All @@ -14,20 +37,21 @@
/>
</p>
</section>
<section class="posts">
<section class="comments-paginated">
<h3>
<strong>Total number of posts preloaded:</strong>
<strong>Total number of comments (paginated) preloaded:</strong>
</h3>
<p v-if="$store.state.posts && $store.state.posts.items && $store.state.posts.items.length">
<p v-if="$store.state.comments && $store.state.comments.paginated && $store.state.comments.paginated.length">
<em
class="number"
v-text="$store.state.posts.items.length"
v-text="$store.state.comments.paginated.length"
/>
</p>
</section>
<!-- GraphQL -->
<section class="graphql">
<h3>
<strong>Total number graphql data preloaded:</strong>
<strong>GraphQL Object loaded:</strong>
</h3>
<code v-if="$store.state.graphql && $store.state.graphql.data">
<pre
Expand All @@ -48,11 +72,23 @@
/>
<em
v-if="$store.state.locations.data.nextToken"
class="number"
class="next-token"
v-text="$store.state.locations.data.nextToken"
/>
</p>
</section>
<section class="locations-paginated">
<h3>
<strong>Total number of locations (paginated) preloaded:</strong>
</h3>
<p v-if="$store.state.locations && $store.state.locations.paginated">
<em
v-if="$store.state.locations.paginated && $store.state.locations.paginated.length"
class="number"
v-text="$store.state.locations.paginated.length"
/>
</p>
</section>
<button type="button" @click="refresh">REFRESH</button>
</main>
</template>
Expand Down Expand Up @@ -80,3 +116,8 @@
},
};
</script>

<style
scoped
src="./index.css"
></style>

0 comments on commit 239d9d7

Please sign in to comment.