1.0.7 • Published 1 year ago

@codehubby/crudql v1.0.7

Weekly downloads
-
License
ISC
Repository
-
Last release
1 year ago

CrudQL: Simplify Your HTTP Server

  • 💜 Simplify Your Api Servers
  • 💜 Write Reuseable Functions
  • 💜 Exposes documentation based on Authentication

A https://hub.codehubby.com package to radically simplify your HTTP API setup. Use GET http://localhost:3333 to view routes, and POST an array with arguments to the desired route to execute functions.

app.js:

import { readRoute,readRoutes } from '@codehubby/crudql';

const crudql = {
    routes: {
        creator: {
            test(user,a,b) {
                console.log({user,a,b});
                return [a+b,200]; // [result,statusCode]
            }
        }
    },
    getRouteUser(token,mode) {
        return 'creator';
    }
}

const HTTP_PORT = process.env.HTTP_PORT || 3333;
console.log(`:${HTTP_PORT}`, await readRoutes(crudql));

/* 
//
// (^ that's it :)
// 
// Minimal Express Setup with CRUDQL 
//
// (edit below only if needed)
// 
*/
import express from 'express';
import bodyparser from 'body-parser';
import logger from 'morgan';
import cors from 'cors'
const app = express();
app.use(cors({origin: '*'}));
app.use(bodyparser.json());
app.use(logger('dev'));
app.use(bodyparser.urlencoded({extended: true}));
app.get('/', async(req, res) => {
    let user = null;
    try {
        const token = req.headers['authorization']; 
        const requestmode = req.headers['requestmode']; // if user requests other user mode

        // 1. AUTH: First variable of every function
        if(token) {
            user = '?'; // here comes your ex. JWT auth;
        } 
          
        // 2. Gather Route Info based on user
        const routes = await readRoutes(crudql,user, requestmode);
        res.send(routes);
    } catch(err) {
        console.log('err',err);
        res.status(503).send();
    }
});

app.post('/:funcName', async(req, res) => {
    let user = null;
    const inputs = {};
    try { 
        inputs['token'] = req.headers['authorization'];
        inputs['requestmode'] = req.headers['requestmode']; // in case user requests other
        inputs['funcName'] = req.params.funcName.toString();
        inputs['args'] = [];
        if(req.body && Array.isArray(req.body)) {
            for(const arg of req.body) {
                inputs['args'].push(arg);
            }
        }

        // 1. AUTH: Check for valid user auth token (your own implemtation, etc JWT)
        if(inputs['token']) {
            user = '?'; // here comes your ex. JWT auth;
        } 
           
        // 2. EXECUTION (inputs.func='readExample' and inputs.args=[] need to be defined)
          const [text,status] = await createAction(crudql, inputs['funcName'], inputs['args'], user, inputs['requestmode'] );
          res.status(status).send(text);
    } catch(err) {
        const crudQLUser = crudql.getRouteUser(user,inputs['requestmode']);
        if(err.toString().includes('function') && err.toString().includes('not found')) {
          res.status(404).send({error: 'Function not found for ' + crudQLUser + ' user'});
        } else {
          console.log('err',err);
          res.status(503).send({error: 'Unknown error'});
        }
    }
});

app.set('port', HTTP_PORT);
app.listen(HTTP_PORT);

Quick CrudQL Tutorial

// tutorial-crudql.js 
const creator = { 
      readSum(user, a, b) {
          return [ a+b, 200 ];
      }
}

/*
// test 
const [text, status] = creator.readSum({}, 1,2);
console.log({text});
//*/

export default creator;

CrudQL Tutorial (index file)

// tutorial-crudql-index.js 
import creatorRoutes from './tutorial-crudql.js';
import { createAction, readRoutes } from 'crudql';
export const crudql = { 
    routes: { creator: creatorRoutes, guest:[] },
    getRouteUser(user,requestMode) {
        if(user) return 'creator';
        else return 'guest';
    }
}

const [user, func, args] = [ {user_id:1}, 'readSum', [1,2] ];
const routes = await readRoutes(crudql,  user);
console.log( { routes: JSON.stringify(routes) } ); // 1. (optional) Show All User Routes

const result = await createAction(crudql, func, args, user); // ex. inside POST /:funcName
console.log( { result } ); // 2. Execute and Show Result

CrudQL Express Example

// app.js

import express from 'express';
import logger from 'morgan';
import bodyparser from 'body-parser';
import { createAction, readRoutes } from 'crudql';
const app = express();
app.use(logger('dev'));
app.use(bodyparser.json());
app.use(bodyparser.urlencoded({extended: true}));

const crudql = {
    routes: {
        creator: { test(user) { return ['testcreator',200] } },
        guest: { test(user) { return ['testguest',200] } },
    },
    getRouteUser(user,requestmode) {
        if(user) return 'creator';
        else return 'guest';
    } 
};

app.options('*', (req, res) => { // all options request respond OK
  res.json({ status: 'OK'});
});

app.post('/', async(req, res) => {
    try {
      let user = null;
      const { authorization, requestmode } = req.headers;
      
      // 1. AUTH
      if(authorization === 'your authentication check goes here') {
        user = {user_id:1}; // your token decode goes here
      }

       // 2. Read All User Routes
      const routes = await readRoutes(crudql,user, requestmode);
      res.send(routes);
    } catch(err) {
      console.log('err',err);
      res.status(503).send();
    }
});

app.post('/:funcName', async(req, res) => {
    let user, requestmode;
    try { 
      const { authorization } = req.headers;
      requestmode = req.headers.requestmode;
      const { funcName } = req.params;
      const args = req.body;
      
      // 1. AUTH
      if(authorization === 'your authentication check goes here') {
          user = {user_id:1}; // your token decode goes here
      }

      // 2. EXECUTE
      const [text,status] = await createAction(crudql, funcName, args, user, requestmode);
      res.status(status).send(text);
    } catch(err) {
        // Extra: Nice error handling
        let text,status;
        const crudQLUser = crudql.getRouteUser(user,requestmode);
        if(err.toString().includes('function') && err.toString().includes('not found')) {
          [text,status] = ['Function not found for ' + crudQLUser + ' user',404];
        } else {
          console.log('err',err);
          [text,status] = ['Unknown error',503];
        }
        
        res.status(status).send({error: text});
    }
});

const HTTP_PORT=3473;
console.log("[*] Starting http server (CrudQL) on port " + HTTP_PORT);
app.set('port', HTTP_PORT);
app.listen(HTTP_PORT);

Quick Tip to Use Import / ES6 with NodeJS:

Add this to your package.json file

  "type":"module",
1.0.7

1 year ago

1.0.6

1 year ago

1.0.5

1 year ago