All Projects → MarkKhramko → nodejs-express-jwt

MarkKhramko / nodejs-express-jwt

Licence: MIT license
Node.js Express REST API boilerplate with JWT Authentication and support for MySQL and PostgreSQL.

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to nodejs-express-jwt

Ravys-unified-discord-ruleset
Extensive, yet polished community ruleset, aimed at reducing the work of moderators
Stars: ✭ 21 (-62.5%)
Mutual labels:  hacktoberfest2021
CodeBucket
A beginner-friendly project to help you in open-source contributions. Made specifically for contributions in HACKTOBERFEST! Please leave a star ⭐ to support this project! ✨
Stars: ✭ 22 (-60.71%)
Mutual labels:  hacktoberfest2021
VCPlayerBot
Telegram bot to stream videos in telegram voicechat for both groups and channels. Supports live steams, YouTube videos and telegram media. Supports scheduling streams, recording and many more.
Stars: ✭ 432 (+671.43%)
Mutual labels:  hacktoberfest2021
ML-ProjectYard
This repo consists of multiple machine learning based projects with frontend
Stars: ✭ 105 (+87.5%)
Mutual labels:  hacktoberfest2021
30-Days-Of-Code
This File Contains all solutions of: Hackerrank 30 day of code. You are welcome to add any other variants of them or in other language if you know, but DO NOT MAKE THIS REPO ACT LIKE A SOURCE OF +1.
Stars: ✭ 14 (-75%)
Mutual labels:  hacktoberfest2021
wallet-adapter
Modular TypeScript wallet adapters and components for Solana applications.
Stars: ✭ 964 (+1621.43%)
Mutual labels:  hacktoberfest2021
Hacktoberfest-2021
Repository for community contributions
Stars: ✭ 46 (-17.86%)
Mutual labels:  hacktoberfest2021
CPCODES-Hacktoberfest2021
No description or website provided.
Stars: ✭ 11 (-80.36%)
Mutual labels:  hacktoberfest2021
HacktoberFest2021
Beginner-friendly repository for Hacktober Fest 2021. Start your contribution to open source through baby steps. 💜
Stars: ✭ 33 (-41.07%)
Mutual labels:  hacktoberfest2021
Xpendi
iOS expense tracker
Stars: ✭ 13 (-76.79%)
Mutual labels:  hacktoberfest2021
open-source-contribution
to learn how to do pull request and do contribution to other's repo
Stars: ✭ 78 (+39.29%)
Mutual labels:  hacktoberfest2021
BnademOverflow
BnademOverFlow's Official Website
Stars: ✭ 37 (-33.93%)
Mutual labels:  hacktoberfest2021
controller-topology-project
The Controller Topology Project models how controllers connect to and map to each other for all gaming history
Stars: ✭ 17 (-69.64%)
Mutual labels:  hacktoberfest2021
EduSmart
It utilizes 3D, Augmented reality to give real-life simulations or feels of various models and make the learning process more impactful and fascinating. With an interactive live feature, students can ask the teacher their doubts instantly and also discuss.
Stars: ✭ 23 (-58.93%)
Mutual labels:  hacktoberfest2021
Hacktoberfest-Nepal-2020
A beginner-friendly open source repository to create your first pull request.
Stars: ✭ 15 (-73.21%)
Mutual labels:  hacktoberfest2021
Web-Dev-Helper
Developer Helper where you can find all resources related to open source and software developer resources
Stars: ✭ 33 (-41.07%)
Mutual labels:  hacktoberfest2021
TruHealth
A website, which is wholly focused on Mental Health issues.
Stars: ✭ 16 (-71.43%)
Mutual labels:  hacktoberfest2021
backend
Cambiatus GraphQL API
Stars: ✭ 17 (-69.64%)
Mutual labels:  hacktoberfest2021
Hacktoberfest 21
No description or website provided.
Stars: ✭ 17 (-69.64%)
Mutual labels:  hacktoberfest2021
Algorithms
Short explanations and implementations of different algorithms in multiple languages
Stars: ✭ 37 (-33.93%)
Mutual labels:  hacktoberfest2021

nodejs-express-jwt

Express REST API Boilerplate with JWT Authentication and support for MySQL and PostgreSQL.

  • Compilation via Babel;
  • Authentication via JWT;
  • Routes mapping via express-routes-mapper;
  • Environments for development, testing, and production.

Table of Contents

Version notice

This project came a long way since the initial release in 2018. If you used this boilerplate before 2021, you should check a v0.x.x branch and v0 tags for the latest changes of v0.

Install and Use

Start by cloning this repository

# HTTPS
$ git clone https://github.com/MarkKhramko/nodejs-express-jwt

then use npm to

# Enter project root
$ cd nodejs-express-jwt
# Install dependencies
$ npm i
# Copy environment file 
$ cp .env.example .env
# Fill .env file
# ...
# If you want to use PostgreSQL (optional)
$ npm install -S pg pg-hstore
# Start the application (without code watcher)
$ npm start
#
# OR
#
# start development with nodemon
$ npm run dev

MySQL is supported out of the box as it is the default.

Controllers

Controllers in this boilerplate have a naming convention: ModelnameController.js and uses an object factory pattern. To use a model inside of your controller you have to require it. We use Sequelize as ORM, if you want further information read the Docs.

Folder structure

  • Controllers for your main API should be placed inside /api/ directory;
  • Controllers for HTTP requests should be placed inside /web/ directory.

Create a Controller

Example Controller for all CRUD oparations:

const Model = require('#models/Model');

model.exports = function ModelController() {
  const _create = (req, res) => {
    // body is part of a form-data
    const { value } = req.body;

    Model
      .create({
        key: value
      })
      .then((model) => {
        if(!model) {
          return res.status(400).json({ msg: 'Bad Request: Model not found' });
        }

        return res.status(200).json({ model });
      })
      .catch((err) => {
        // better save it to log file
        console.error(err);

        return res.status(500).json({ msg: 'Internal server error' });
      });
  };

  const _getAll = (req, res) => {
    Model
      .findAll()
      .then((models) => {
        if(!models){
          return res.status(400).json({ msg: 'Bad Request: Models not found' });
        }

        return res.status(200).json({ models });
      })
      .catch((err) => {
        // better save it to log file
        console.error(err);

        return res.status(500).json({ msg: 'Internal server error' });
      });
  };

  const _get = (req, res) => {
    // params is part of an url
    const { id } = req.params;

    Model
      .findOne({
        where: {
          id,
        },
      })
      .then((model) => {
        if(!model) {
          return res.status(400).json({ msg: 'Bad Request: Model not found' });
        }

        return res.status(200).json({ model });
      })
      .catch((err) => {
        // better save it to log file
        console.error(err);

        return res.status(500).json({ msg: 'Internal server error' });
      });
  };

  const _update = (req, res) => {
    // params is part of an url
    const { id } = req.params;

    // body is part of form-data
    const { value } = req.body;

    Model
      .findByPk(id)
      .then((model) => {
        if(!model) {
          return res.status(400).json({ msg: 'Bad Request: Model not found' });
        }

        return model
          .update({
            key: value,
          }).then((updatedModel) => {
            return res.status(200).json({ updatedModel });
          });
      })
      .catch((err) => {
        // better save it to log file
        console.error(err);

        return res.status(500).json({ msg: 'Internal server error' });
      });
  };

  const _destroy = (req, res) => {
    // params is part of an url
    const { id } = req.params;

    Model
      .findByPk(id)
      .then((model) => {
        if(!model) {
          return res.status(400).json({ msg: 'Bad Request: Model not found' })
        }

        model.destroy().then(() => {
          return res.status(200).json({ msg: 'Successfully destroyed model' });
        }).catch((err) => {
          // better save it to log file
          console.error(err);

          return res.status(500).json({ msg: 'Internal server error' });
        });
      })
      .catch((err) => {
        // better save it to log file
        console.error(err);

        return res.status(500).json({ msg: 'Internal server error' });
      });
  };

  // !IMPORTANT!
  // don't forget to return the functions:
  return {
    create:_create,
    getAll:_getAll,
    get:_get,
    update:_update,
    destroy:_destroy
  };
};

Models

Models in this boilerplate have a naming convention: Model.js and uses Sequelize to define Models, if you want further information read the Docs.

Create a Model

Example User Model:

const { DataTypes } = require('sequelize');
const database = require('#services/db.service');

// Password hasher.
const bcryptSevice = require('#services/bcrypt.service');


const User = database.define(
  'User',
  {
    email: {
      type: DataTypes.STRING(255),
      unique: true,
      allowNull: false
    },
    password: {
      type: DataTypes.STRING(255),
      allowNull: false
    },
  }
);

// Hooks:
User.beforeValidate((user, options) => {
  // Hash user's password.
  user.password = bcryptSevice.hashPassword(user);
})
// Hooks\

module.exports = User;

Policies

Policies are middleware functions that can run before hitting a apecific or more specified route(s).

Services

Services are little useful snippets, or calls to another API that are not the main focus of your API.

Example service:

Get comments from another API:

module.exports = {
  getComments:_getComments
};

async function _getComments() {
  try {
    const res = await fetch('https://jsonplaceholder.typicode.com/comments', {
      method: 'get'
    });
    // do some fancy stuff with the response.
  }
  catch(error) {
    // Process error.
  }
}

Configs

.env file

Database

Configure the keys with your credentials in .env file.

  DB_DIALECT=mysql
  DB_HOST=localhost
  DB_NAME=name
  DB_USER=root
  DB_PASSWORD=root
  DB_PORT=3609

Default dialect for the application is MySQL. To switch for PostgreSQL, type DB_DIALECT=postgres in .env file.

Note: if you use mysql make sure MySQL server is running on the machine

Note: to use a postgres run : npm i -S pg pg-hstore or yarn add pg pg-hstore

JWT

Set random secret access keys for your access and refresh tokens.

JWT_ACCESS_SECRET=<any random string>
JWT_REFRESH_SECRET=<any random string>

npm scripts

npm run dev

This is the entry for a developer. This command:

  • runs nodemon watch task for the all files conected to .app/app.js, except ./public directory;
  • Reads environment variable NODE_ENV from .env;
  • Opens the db connection for development;
  • Starts the server on 127.0.0.1:APP_PORT,

npm run production

This command:

  • Sets the environment variable to production;
  • Opens the db connection for production;
  • Starts the server on 127.0.0.1:APP_PORT.

Before running on production you have to set the environment vaiables:

  • APP_PORT - Port for your application (usually 80);
  • DB_DIALECT - mysql or postgresl;
  • DB_HOST - Host address of your database;
  • DB_NAME - Database name for production;
  • DB_USER - Database username for production;
  • DB_PASS - Database password for production;
  • DB_PORT - Database port for production;
  • JWT_ACCESS_SECRET - Secret for JSON web token for direct API requests;
  • JWT_REFRESH_SECRET - Secret for JSON web token to renew the Access-JWT.

npm start

This command:

  • Opens the db connection for default environment in .env file.
  • Simply start the server on 127.0.0.1:APP_PORT without a watcher.

npm run db:migrate

This command:

  • Ensures that database schemas are equivalent to the ones configured in /app/models/index.js.

npm run db:seed

This command:

  • Inserts all seeds, configured in /migrator/seeder.js into the database.

LICENSE

MIT 2018-present. By Mark Khramko

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].