1.0.6 • Published 4 years ago

@kolinalabs/nodejs-api-pack v1.0.6

Weekly downloads
4
License
MIT
Repository
github
Last release
4 years ago

NodeJS Api Pack

A simple package for standardizing API operations.

This package provides the configuration base for executing API operations through the GET, POST, PUT, DELETE methods.

The package does not provide operations performers, just an interface to access the features configured for each step of the operations.

Basic concept

READ >> DESERIALIZE >> CHECK >> VALIDATE >> WRITE >> SERIALIZE

STEPDESCRIPTIONPERFORMER
READRetrieve data (item/collection/custom/null)provider
DESERIALIZEUpdate resource/entity retrieved with request dataserializer
CHECKCheck the resource access permissionschecker
VALIDATEValidate the populated/deserialized datavalidator
WRITEPersist/update/delete datapersister
SERIALIZESerialize data before responseserializer

Performers (recommendation)

Providers: Providers operate by interpreting the request by loading the corresponding data and inserting it into the operation property operation.data

Serializers Operate at two different times:

  • DESERIALIZE: Gets the request body and populates the entity. If an entity has not been recovered, a new entity must be provided by the provider.
  • SERIALIZE: Format/add/remove properties according to business rules, before response.

Checkers After entity recovery, this step can be used for secure / access checks, if necessary.

Validator Performs validation of entity data

Persister Do one of the operations - persist (update) or remove, when applicable.

Usage

Installation

// npm
npm install @kolinalabs/nodejs-api-pack

// or yarn
yarn add @kolinalabs/nodejs-api-pack

Example

The examples below may be used as a reference, although they do not produce a result.

For full use, use the integration features:

Custom performers

const Checker = {
  check(operation) {
    /** You custom checking process **/
    if (operation.method.toUpperCase() === "DELETE") {
      operation.context.errors.checker.push({
        message: "Unauthorized."
      });
    }
  }
};

const Persister = {
  persist(operation) {
    /** Your custom persistence process **/
    operation.data.id = Math.random();
    operation.data.updatedAt = new Date().toISOString();
  },
  remove(operation) {
    /** Your custom remove process **/
    operation.data = null;
  }
};

const Provider = {
  getCollection(operation) {
    /** Your custom retrieve collection process **/
    operation.data = [
      { title: "Item " + Math.random() },
      { title: "Item " + Math.random() },
      { title: "Item " + Math.random() }
    ];
  },
  getItem(operation) {
    /** Your custom retrieve item process **/
    operation.data = { title: "Item B" };
  },
  getInstance(operation) {
    /** Your custom instantiation process **/
    operation.data = {};
  }
};

const Serializer = {
  serialize(operation) {
    /** You custom serialization process **/
    delete operation.data.context;
    delete operation.data.email;
  },
  deserialize(operation, data = {}) {
    /** You custom deserialization process **/
    Object.keys(data).map(property => {
      operation.data[property] = data[property];
    });
  }
};

const Validator = {
  validate(operation) {
    /** You custom validation process **/
    if (operation.method.toUpperCase() === "PUT") {
      operation.context.errors.validator.push({
        message: "Validation error"
      });
    }
  }
};

Create ApiPack

const { ApiPack } = require("@kolinalabs/nodejs-api-pack");

const apiPack = new ApiPack();

apiPack.checker(Checker);
apiPack.persister(Persister);
apiPack.provider(Provider);
apiPack.serializer(Serializer);
apiPack.validator(Validator);

Custom operations

const operation = [
  {
    type: "collection",
    method: "get",
    path: "/dummies"
  },
  {
    type: "collection",
    method: "post",
    path: "/dummies"
  },
  {
    type: "item",
    method: "get",
    path: "/dummies/:id"
  },
  {
    type: "item",
    method: "put",
    path: "/dummies/:id"
  },
  {
    type: "item",
    method: "delete",
    path: "/dummies/:id"
  }
];

Using ExpressJS (+bodyParser.json)

const express = require("express");
const bodyParser = require("body-parser");
const router = express.Router();

const app = express();

/** You custom stack **/
function Stack(operation) {
  return [
    // initialization
    (req, res, next) => {
      operation.context = {
        request: req,
        errors: {
          checker: [],
          validator: []
        }
      };
      ApiPack.operation = operation;
      req.ApiPack = ApiPack;
      next();
    },
    // read
    (req, res, next) => {
      req.ApiPack.read();
      next();
    },
    // deserialize
    (req, res, next) => {
      req.ApiPack.deserialize(req.body);
      next();
    },
    // check
    (req, res, next) => {
      req.ApiPack.check();
      if (req.ApiPack.errors("checker").length) {
        return res
          .status(req.ApiPack.operation.status || 401)
          .send(req.ApiPack.errors("checker"));
      }
      next();
    },
    // validate
    (req, res, next) => {
      req.ApiPack.validate();
      next();
    },
    // write
    (req, res, next) => {
      req.ApiPack.write();
      next();
    },
    // serialize
    (req, res, next) => {
      req.ApiPack.serialize();
      next();
    },
    // respond
    (req, res, next) => {
      let status = 200;
      if (!req.ApiPack.operation.data) {
        status = 204;
      } else if (req.ApiPack.operation.type === "collection") {
        status = 201;
      }
      res.status(status).send(req.ApiPack.operation.data);
    }
  ];
}

// configure routes
operations.forEach(operation => {
  router[operation.method](operation.path, Stack(operation));
});

app.use("/api-pack", router);
app.use(bodyParser.json());
app.listen(3007);

Start your server

$ node express-mocked.js

Access the URLs

GET: http://localhost:3007/api-pack/dummies

POST: http://localhost:3007/api-pack/dummies

GET: http://localhost:3007/api-pack/dummies/123456

PUT: http://localhost:3007/api-pack/dummies/123456

DELETE: http://localhost:3007/api-pack/dummies/123456
1.0.6

4 years ago

1.0.5

5 years ago

1.0.4

5 years ago

1.0.3

5 years ago

1.0.2

5 years ago

1.0.1

5 years ago

1.0.0

5 years ago