node package manager
Painless code sharing. npm Orgs help your team discover, share, and reuse code. Create a free org »

marchio-datastore

marchio-datastore

REST to Google Datastore Mapper

Continuous Integration Coverage Status Downloads Version License

Installation

As main app:

$ npm init
$ npm install marchio-datastore --save

As marchio child app:

$ npm init
$ npm install marchio --save
$ npm install marchio-datastore --save

Modules

marchio-datastore

Module

marchio-datastore-factory

Factory module

marchio-datastore-ERROR

Error module

marchio-datastore

Module

marchio-datastore-factory

Factory module

marchio-datastore-factory.create(spec) ⇒ Promise

Factory method It takes one spec parameter that must be an object with named parameters

Kind: static method of marchio-datastore-factory
Returns: Promise - that resolves to an expressjs app

Param Type Description
spec Object Named parameters object
[spec.path] String Base path (like "/api" or "/v1")
[spec.post] boolean Allow HTTP POST
[spec.get] boolean Allow HTTP GET
[spec.put] boolean Allow HTTP PUT
[spec.del] boolean Allow HTTP DELETE
[spec.patch] boolean Allow HTTP PATCH

Example (Environment setup)

export MARCHIO_GOOGLE_PROJECT_ID='my-project-id'
export MARCHIO_PORT=8080

Example (Child app of marchio example)

"use strict";
 
var factory = require("marchio"),
    datastore = require('marchio-datastore');
 
const GOOGLE_PROJECT_ID = process.env.MARCHIO_GOOGLE_PROJECT_ID,
      PORT = process.env.MARCHIO_PORT || 8080;
 
var _testModel = {
    name: 'user',
    fields: {
        email:    { type: String, required: true },
        status:   { type: String, required: true, default: "NEW" }, 
    }
}
 
var _marchio = null;
 
factory.create({
    verbose: true
})
.then( (obj) => _marchio = obj )
.then( () => 
   datastore.create({
        projectId: GOOGLE_PROJECT_ID,
        model: _testModel,
        post: true,
        get: true,
        put: true,
        del: true,
        patch: true
    })
)
.then( (dsApp) => _marchio.use(dsApp) )
.then( () => _marchio.listen( PORT ) )
.catch( (err) => { 
   console.error(err); 
}); 

Example (curl testing)

$ curl --POST -"Content-Type: application/json" \
    -'{"email":"test@demo.com"}' http://localhost:8080/user 
 
$ curl --GET -"Accept: applications/json" \
    http://localhost:8080/user/1234567890123456 
 
$ curl --PUT -"Content-Type: application/json" \
    -'{"email":"test@demo.com", "status":"UPDATED"}' \
    http://localhost:8080/user/1234567890123456 
 
$ curl --PATCH -"Content-Type: application/json" \
    -'[{"op":"replace","path":"/status","value":"PATCH"}]' \
    http://localhost:8080/user/1234567890123456 
 
$ curl --DELETE -"Content-Type: application/json" \
    http://localhost:8080/user/1234567890123456 

Example (Main app example)

var factory = require("marchio-datastore");
 
const GOOGLE_PROJECT_ID = process.env.MARCHIO_GOOGLE_PROJECT_ID,
      PORT = process.env.MARCHIO_PORT || 8080;
 
var _testModel = {
    name: 'user',
    fields: {
        email:    { type: String, required: true },
        status:   { type: String, required: true, default: "NEW" },
        password: { type: String, select: false },  // select: false, exclude from query results 
    }
};
 
factory.create({
    model: _testModel,
    projectId: GOOGLE_PROJECT_ID,
    post: true,
    get: true,
    put: true,
    del: true,
    patch: true
})
.then(function(app) {
    app.listen(PORT, () => {
        console.log(`listening on port ${PORT}`);   
    });
})
.catch( function(err) { 
    console.error(err); 
});

Example (Path based example)

var factory = require("marchio-datastore");
 
const GOOGLE_PROJECT_ID = process.env.MARCHIO_GOOGLE_PROJECT_ID,
      PORT = process.env.MARCHIO_PORT || 8080;
 
var _testModel = {
    name: 'user',
    fields: {
        email:    { type: String, required: true },
        status:   { type: String, required: true, default: "NEW" },
        password: { type: String, select: false },  // select: false, exclude from query results 
    }
};
 
factory.create({
    model: _testModel,
    projectId: GOOGLE_PROJECT_ID,
    path: '/api',
    post: true,
    get: true,
    put: true,
    del: true,
    patch: true
})
.then(function(app) {
    app.listen(PORT, () => {
        console.log(`listening on port ${PORT}`);   
    });
})
.catch( function(err) { 
    console.error(err); 
});

Example (path-based curl testing)

$ curl --POST -"Content-Type: application/json" \
    -'{"email":"test@demo.com"}' http://localhost:8080/api/user 
 
$ curl --GET -"Accept: applications/json" \
    http://localhost:8080/api/user/1234567890123456 
 
$ curl --PUT -"Content-Type: application/json" \
    -'{"email":"test@demo.com", "status":"UPDATED"}' \
    http://localhost:8080/api/user/1234567890123456 
 
$ curl --PATCH -"Content-Type: application/json" \
    -'[{"op":"replace","path":"/status","value":"PATCH"}]' \
    http://localhost:8080/api/user/1234567890123456 
 
$ curl --DELETE -"Content-Type: application/json" \
    http://localhost:8080/api/user/1234567890123456 

marchio-datastore-ERROR

Error module

Param Type Description
MODEL_MUST_BE_DEFINED string datastore.create: model must be defined
MODEL_NAME_MUST_BE_DEFINED string datastore.create: model.name must be defined
PROJECT_ID_MUST_BE_DEFINED string datastore.create: projectId must be defined
NO_HTTP_METHODS_ENABLED string datastore.create: No HTTP methods enabled

Example (Usage example)

 .catch( (err) => {
    if( err.message == _factory.ERROR.MODEL_MUST_BE_DEFINED ) {
        ...
    }
}

Testing

To test, go to the root folder and type (sans $):

$ npm test

Repo(s)


Contributing

In lieu of a formal style guide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code.


Version History

Version 0.1.19

  • The numeric flag is ignored since post always auto-generates numeric keys

Version 0.1.18

  • Updated to use latest marchio-core-app

Version 0.1.17

  • Now uses external marchio-core-record

Version 0.1.16

  • Updated marchio-core-app to version 0.1.3

Version 0.1.15

  • Now uses external marchio-core-app

Version 0.1.14

  • Added path parameter to create method ('/api', '/v1', etc.)

Version 0.1.13

  • Added a Google Cloud Function example

Version 0.1.12

  • Implemented preprocess setting on microservice cores
  • Added preprocess password encryption example

Version 0.1.11

  • Microservice cores now use app instead of router

Version 0.1.10

  • Moved non-datastore functionality out of datastore-core

Version 0.1.9

  • Refactored code to use router.param instead of custom callback

Version 0.1.8

  • Refactored code
  • Moved model / id validation to core

Version 0.1.7

  • HTTP PATCH now uses transaction for better record integrity
  • Fixed issue where PUT was saving on datastore and not transaction

Version 0.1.6

  • HTTP PUT can now handle partial updates
  • Behind the scenes PUT now use a transaction to ensure record integrity

Version 0.1.5

  • Added HTTP PATCH support
  • Added new test cases for HTTP PATCH

Version 0.1.4

  • Added HTTP DELETE support
  • Improved GET and PUT handling for invalid ids
  • Added and updated test cases

Version 0.1.3

  • Added PUT support

Version 0.1.2

  • Fixed some doc issues

Version 0.1.1

  • Now must specify what HTTP methods to allow in create method.

Version 0.1.0

  • initial release