Git Product home page Git Product logo

expressa-folder's Introduction

file-based design-pattern to organize expressa & express REST/db middleware

Build Status

Usage

require('expressa-folder')(expressa, app)
expressa.addListener('ready', 100, >(){
  expressa.folderDir = __dirname+"/lib"
  expressa.initFolder('foo')      // will require expressa db/REST-listener code if collection 'foo' exist
  expressa.initFolder('foo/bar')  // will setup custom express point
  // optional: generate REST client for in the browser at /api/client.js
  require('expressa-client').middleware({expressa:expressa,  app:app}) 
})

This will automatically fetch the following files if present:

file expressa listener creates express endpoint note
lib/foo/get.js yes no requires data/collection/foo.js to exist
lib/foo/post.js yes no requires data/collection/foo.js to exist
lib/foo/put.js yes no requires data/collection/foo.js to exist
lib/foo/delete.js yes no requires data/collection/foo.js to exist
lib/foo/schema.js yes no requires data/collection/foo.js to exist
lib/foo/functions.js no no all db objects will inherit these functions
lib/foo/swagger.js no no only when expressa-swagger is installed
lib/foo/bar/get.js no yes bare express endpoint without expressa schema-validation
lib/foo/bar/swagger.js no no only when expressa-swagger is installed

Example: lib/foo/get.js

module.exports = function(expressa, app){
  return function(req, collection, doc, resolve, reject) {
    // do stuff with the response data (doc)
    resolve(doc)
  })
}

Example: lib/foo/functions.js

module.exports = function(expressa, app){
  return {
    addPropertyFoo: () => {
      this.foo = "bar"
    }
  }
}

Now you can easily access helper functions on the server:

expressa.db.foo.find({})
.then( function(items){
  items.map( (i) => i.addPropertyFoo() )
})

Example: lib/foo/bar/get.js (bare express)

module.exports = function(expressa,app){
  return function(req, res, next){
			res.writeHeader(200, {"Content-Type":"application/json"})
			res.end( JSON.stringify({"foo":"bar"}) )
  }
}

Voila..this will automatically setup a 'foo/bar' express-endpoint

Example: robust custom endpoint

NOTE: The non-expressa endpoint above, is a simple express endpoint. Unfortunately express endpoints have zero input validation (unlike expressa endpoints).

Here's how to do it for express as well..let assume we want the user to submit to a mailinglist:

// lets add the endpoint
expressa.initFolder('users/mailinglist')

And now lets write lib/users/mailinglist/post.js:

var typeshave = require('typeshave') // json schema validator
var typesafe  = typeshave.typesafe

var schema = require('./../../../../data/collection/users.json').schema
schema.required = ["firstname", "email"] // overrule required properties

module.exports = function(expressa, app ){

  return function(req, res, next){

    res.writeHeader(200, {"Content-Type":"application/json"})

    try{ 

      typesafe(schema, function(){

        expressa.db.users.find({email:req.body.email})
        .then( function(user){
          if(user.length != 0) throw "user "+req.body.email+" already exist"
          return expressa.db.users.create( req.body )
        })
        .then(function(id){
          res.end( JSON.stringify({code:0, id:id}) )
        })
        .catch(function(err){
          res.end( JSON.stringify({"code":1, error:err}) )
        })

      })(req.body) 

    }catch(e){
      return res.end( JSON.stringify({"code":2, error:e}) )
    }

  }
}

Boom...if we would now post {} to our endpoint:

$ curl -X POST 'http://localhost:3001/api/users/mailinglist' --data '{}'

Then the server will reply:

{ data: {},
  errors:
   { message: 'Missing required property: email',
     dataPath: '',
     schemaPath: '/required/0',
     subErrors: null },
  schema:
   { type: 'object',
     additionalProperties: false,
     properties:
      { meta: [Object],
        email: [Object],
        password: [Object],
        firstname: [Object],
        lastname: [Object],
        roles: [Object] }
     required: [ 'email', 'firstname' ],

Authentication / permissions

For expressa endpoints the user+permissions are already available at req.user and req.user.roles. For ad-hoc express endpoints you can do this:

       var auth = require('expressa/auth')
   var _    = require('lodash')

   return function(req, res, next){                                                        
	  var rolePermissions = require('expressa/role_permissions')(expressa).middleware;    
	  auth.middleware(req, res, function(){
	      rolePermissions(req, res, function(){
		  var admin = ( _.get( req,'user.roles' ) || [] ).indexOf("Admin") // is admin?
		  res.writeHeader(200, {"Content-Type":"application/json"})                   
		  res.end( admin ? JSON.stringify(lines) : JSON.stringify({error:"access denied"}) )             
	      })
	  })
      }     

Example: lib/foo/swagger.js

This will add (or overwrite) swagger documentation, generated at url /api/doc using expressa-admin:

module.exports = {
  "/foo":{
    "get":{
      "parameters": [
        {
          "in": "body",
          "name": "payload",
          "description": "", 
          "required": true,
          "schema": {
            "type": "object",
            "required":["id_user"],                  // see swagger
            "properties": {                          // documentation
              "id_user":{
                "required":true, 
                "type":"string",
                "default":"lLK34LK" 
              }
            }
          }
        }    
      ],
      "responses": { },
      "tags": [ "users" ],
      "summary": "Lorem ipsum"
    }
  }
}

expressa-folder's People

Contributors

coderofsalvation avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.