Neolithic Psychedelic Mushrooms
    Have ideas to improve npm?Join in the discussion! »

    bissle

    4.1.1 • Public • Published

    bissle

    Minimalist HALicious pagination response toolkit interface for hapi.js

    Travis node npm standard npm

    1. Introduction
    2. Installation
    3. Usage
    4. API
    5. Example
    6. Testing
    7. Contribution

    Introduction

    This hapi.js plugin enables an additional response toolkit interface to paginate a response in a RESTful and HAL compliant manner. So the plugin accordingly splices the initial response; extends it with meta information about the count of entries per page, the total count and the current page; adds a link map for HALicious navigation and appends the corresponding Link header. It is not a middleware-like plugin, so you are allowed to control the usage explicitly by yourself. Because of this, it works perfectly in combination with HAL plugins like halacious, as it is shown in the example below.

    The modules standard and ava are used to grant a high quality implementation.

    Compatibility

    Major Release hapi.js version node version
    v4 >=18.4 @hapi/hapi >=12
    v3.1 >=18.3.1 @hapi/hapi >=8
    v3 >=18 hapi >=8
    v2 >=17 hapi >=8
    v1 >=13 hapi >=6

    bissle is the Swabian term for a little bit, it should visualize the sense of pagination.

    Installation

    For installation use the Node Package Manager:

    $ npm install --save bissle
    

    or clone the repository:

    $ git clone https://github.com/felixheck/bissle
    

    Usage

    Import

    First you have to import the module and the peer dependency akaya:

    const bissle = require('bissle');
    const akaya = require('akaya');

    Create Hapi server

    Afterwards create your Hapi.js server if not already done:

    const hapi = require('@hapi/hapi');
    const server = hapi.server({
      port: 1337,
      host: 'localhost',
    });

    Registration

    Finally register the plugins per server.register():

    await server.register([akaya, bissle]);
    await server.start();

    After registering bissle, the hapi.js response toolkit will be decorated with the new method h.bissle().

    Joi Validation

    If you use Joi for request validation, simply add the parameters to the query scheme. The plugin exposes the all bissle related scheme via server.plugins.bissle.scheme. Alternatively it is possible to enable the allowUnknown option.
    The exposed object contains additionally the scheme for plugin related options.

    API

    Plugin Options

    While the plugin registration it is possible to pass a plugin specific options object:

    • options {Object} - The plugin specific options object.
      • host {string} - The host to use in the URL
        Default: undefined (utilizes request.info.host)
      • absolute {boolean} - If the pagination links (not the Link header) should be absolute or not.
        Default: false.
      • paramNames {Object} - Config object for overriding default parameter names output in the response
        • perPage {string} - Parameter name for describing the page limit
          Default: per_page
        • page {string} - Parameter name for describing the current page
          Default: page
        • total {string} - Parameter name for describing the total item count
          Default: total

    toolkit.bissle(response, [options])

    An additional response toolkit for paginated responses.

    • response {Object} - The result to be decorated and replied.
    • options {Object} - The custom default values.
      • key {string} - The access key of response to get the result to be paginated.
        Default: 'result'.
      • perPage {number} - The default entries per page if none is defined in the query string.
        Default: 100.
        Range: 1-500.
      • total {number} - Overwrite the internally generated total value and avoid data splicing. The passed response get returned without internally done pagination. Just meta information and the Link header get added.
        Default: null.
        Range: >=0.

    Example

    The following example demonstrates the usage of bissle in combination with mongoose, halacious and various utilities.

    const hapi = require('@hapi/hapi');
    const bissle = require('bissle');
    const halacious = require('halacious');
    const akaya = require('akaya');
    const Boom = require('@hapi/boom');
    const _ = require('lodash');
    const YourModel = require('./models/yourModel');
    
    const server = hapi.server({ port: 1337 });
    
    server.route({
      method: 'GET',
      path: '/',
      config: {
        id: 'root',
        handler (request, h) {
          YourModel.find({}, (err, result) => {
            if (err) throw Boom.badRequest(err);
            if (!result) throw Boom.notFound();
    
            return h.bissle({ result });
          });
        },
        plugins: {
          hal: {
            prepare(rep) {
              _.forEach(rep.entity.result, task => {
                rep.embed('task', `./${task._id}`, task);
              });
            },
            ignore: ['result']
          }
        }
    });
    
    (async () => {
      try {
        await server.register([akaya, halacious, {
          plugin: bissle,
          options: { absolute: false }
        }]);
        await server.start();
        console.log('Server started successfully');
      } catch (err) {
        console.error(err);
      }
    })();

    Assuming that mongoose's find() returns the following data as result:

    [
      {
        _id: "abc",
        title: "abc"
      },
      {
        _id: "def",
        title: "def"
      },
      {
        _id: "ghi",
        title: "ghi"
      },
      {
        _id: "jkl",
        title: "jkl"
      },
      {
        _id: "mno",
        title: "mno"
      }
    ]

    Requesting the route /items?page=2&per_page=2, the plugin replies:

    {
      _links: {
        self: {
          href: "/items?page=2&per_page=2"
        },
        first: {
          href: "/items?per_page=2"
        },
        prev: {
          href: "/items?per_page=2"
        },
        next: {
          href: "/items?page=3&per_page=2"
        },
        last: {
          href: "/items?page=3&per_page=2"
        },
      },
      page: 2,
      per_page: 2,
      total: 5,
      result: [
        {
          _id: "ghi",
          title: "ghi"
        },
        {
          _id: "jkl",
          title: "jkl"
        }
      ]
    }

    Additionally the plugin sets the corresponding Link header.


    The halacious plugin enables to extend this response to:

    {
      _links: {
        self: {
          href: "/items?page=2&per_page=2"
        },
        first: {
          href: "/items?per_page=2"
        },
        prev: {
          href: "/items?per_page=2"
        },
        next: {
          href: "/items?page=3&per_page=2"
        },
        last: {
          href: "/items?page=3&per_page=2"
        },
      },
      page: 2,
      per_page: 2,
      total: 5,
      _embedded: [
        {
          _links: {
            self: {
              href: "/items/ghi"
            }
          },
          _id: "ghi",
          title: "ghi"
        },
        {
          _links: {
            self: {
              href: "/items/jkl"
            }
          },
          _id: "jkl",
          title: "jkl"
        }
      ]
    }

    So in the end the combination of bissle and a HAL plugin results in a REST/HAL compliant and paginated response.

    Testing

    First you have to install all dependencies:

    $ npm install
    

    To execute all unit tests once, use:

    $ npm test
    

    or to run tests based on file watcher, use:

    $ npm start
    

    To get information about the test coverage, use:

    $ npm run coverage
    

    Contribution

    Fork this repository and push in your ideas.

    Do not forget to add corresponding tests to keep up 100% test coverage.

    Install

    npm i bissle

    DownloadsWeekly Downloads

    69

    Version

    4.1.1

    License

    MIT

    Unpacked Size

    49.1 kB

    Total Files

    21

    Last publish

    Collaborators

    • avatar