GithubHelp home page GithubHelp logo

ferrielmelarpis / anytv-node-boilerplate Goto Github PK

View Code? Open in Web Editor NEW

This project forked from anytv/anytv-node-boilerplate

0.0 2.0 0.0 151 KB

anyTV boilerplate for creating backend API on node.js

License: MIT License

JavaScript 99.25% Makefile 0.75%

anytv-node-boilerplate's Introduction

Node REST API Boilerplate

Build Status Coverage Status Dependencies bitHound Dependencies bitHound Code

Table of contents

Introduction

A boilerplate for REST APIs. Can also be used for server-side rendered web pages. This project strictly uses the company's JS conventions.

Running the application

  1. Download Zip
  2. Extract to your project's folder
  3. Import database/schema.sql and database/seed.sql
mysql -uroot < database/schema.sql
mysql -uroot < database/seed.sql
  1. Run these commands:
npm install -g grunt-cli
npm install
grunt #or npm run dev-server
  1. check http://localhost:<config.app.PORT>
  2. Update package.json details
  3. Update config/config.js
  4. Don't forget to pull

Creating a controller

Controllers are the heart of your application, as they determine how HTTP requests should be handled. They are located at the controllers folder. They are not automatically routed. You must explicitly route them in config/router.js. Using sub-folders for file organization is allowed.

Here's a typical controller:

// user.js

require('app-module-path/register');

const util   = require('../helpers/util');
const mysql  = require('anytv-node-mysql');
const squel  = require('squel');
const moment = require('moment');



exports.update_user = (req, res, next) => {

    const data = util.get_data(
        {
            user_id: '',
            _first_name: '',
            _last_name: ''
        },
        req.body
    );


    function start () {
        let id;

        if (data instanceof Error) {
            return res.warn(400, {message: data.message});
        }

        id = data.user_id;
        delete data.user_id;

        const query = squel.update()
            .table('users')
            .setFields(data)
            .where('user_id = ?', id)
            .limit(1);
        
        mysql.use('my_db')
            .squel(query, send_response)
            .end();
    }


    function send_response (err, result) {
        if (err) {
            return next(err);
        }

        res.send({ message: 'User successfully updated' });
    }

    start();
};



exports.delete_user = (req, res, next) => {
...

Detailed explanation:

require('app-module-path/register');

const util   = require('../helpers/util');
const mysql  = require('anytv-node-mysql');
const squel  = require('squel');
const moment = require('moment');
  • The first part of the controller contains the helpers, and libraries to be used by the controller's functions
  • The app-module-path/register module prevents the usage of __dirname in requiring local modules
  • Notice the order of imported files, local files first followed by 3rd-party libraries
  • This block should always be followed by at least one new line to separate them visually easily
exports.update_user = (req, res, next) => {
  • snake_case on exported function names
  • req is an object from express, it contains user's request
  • res also an object from express, use this object to respond to the request
  • next a function from express, use this to pass to the next middleware which is the error handler
    const data = util.get_data(
        {
            user_id: '',
            _first_name: '',
            _last_name: ''
        },
        req.body
    ),
  • it is common to use data as the variable to store the parameters given by the user
  • util.get_data helps on filtering the request payload
  • putting an underscore as first character makes it optional
  • non-function variables are also declared first
  • new line after non-function variables to make it more readable
    function start () {

        let id;

        if (data instanceof Error) {
            return res.warn(400, {message: data.message});
        }

        id = data.id;
        delete data.id;

        const query = squel.update()
            .table('users')
            .setFields(data)
            .where('user_id = ?', id)
            .limit(1);
        
        mysql.use('my_db')
            .squel(query, send_response)
            .end();
    }
  • start function is required for uniformity
  • the idea is to have the code be readable like a book, from top-to-bottom
  • since variables are declared first and functions are assigned to variables, we thought of having start function to denote the start of the process
  • as much as possible, there should be no more named functions inside this level except for forEach, map, filter, and reduce. If lodash is available, use it.
    function send_response (err, result) {

        if (err) {
            return next(err);
        }

        res.send({ message: 'User successfully updated' });
    }

    start();
  • send_response is common to be the last function to be executed
  • use next for passing server fault errors
  • after all variable and function declarations, call start

Notes:

  • use res.warn(status, obj) or res.warn(obj) instead of next(error) if the error is caused by the API caller

Setting environment configs

The default configuration uses development. Any changes on the files inside that folder will be ignored. If you want your config to be added on the repo permanently, add it on config.js. Just make sure that it's not confidential.

production is a dedicated config folder for the production environment. Use it via setting $NODE_ENV to production

export NODE_ENV=production

Contributing

Install the tools needed:

npm install istanbul -g
npm install apidoc -g
npm install mocha -g
npm install --only=dev

Production Config

git submodule add -b <branch> <https repository> config/env/production
  • Whenever there are changes in production, you should update the submodule too.
git submodule init
git submodule foreach git pull

Running test

npm test
# or
grunt test

Test Driven Development (TDD)

  • Use npm scripts or grunt tasks that watches the tests.
npm run dev-tests
# or
grunt dev-tests

Code coverage

npm run coverage

Then open coverage/lcov-report/index.html.

API documentation

npm run docs

Then open apidoc/index.html.

License

MIT

Author

Freedom! Labs, any.TV Limited DBA Freedom!

anytv-node-boilerplate's People

Contributors

adin234 avatar airondumael avatar greenkeeperio-bot avatar ninnzz avatar ravenjohn avatar wilbertverayin avatar

Watchers

 avatar  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.