Skip to content

Bonekyaw/node-express-sql-rest

Repository files navigation

This is Simple Nodejs Express Starter Kit

Node express + Sequelize ORM ( MySQL / PostgreSQL ) + REST api

You can use it for your project.
If it is useful for you, don't forget to give me a GitHub star, please.

In this node/express template

  • Express framework
  • RDBMS - MySQL or PostgreSQL
  • Sequelize ORM
  • RESTful api
  • JWT auth
  • bcrypt
  • express-validator
  • error handler
  • file uploading
  • Authorization
  • Pagination ( offset-based & cursor-based ) etc.

In order to use it,

Create a .env file and add this.
For MySQL

DB_HOST=localhost
DB_USER=root
DB_PASSWORD=12345678
DB_MYSQL=lucky
DB_DIALECT=mysql
DB_TIMEZONE=+06:30
TOKEN_SECRET="should be something hard to read"

For PostgreSQL

DB_HOST=localhost
DB_POSTGRES_USER=postgres
DB_POSTGRES_PASSWORD=12345678
DB_MYSQL=lucky
DB_POSTGRES_DIALECT=postgres
DB_TIMEZONE=+06:30
TOKEN_SECRET="should be something hard to read"

Please note.
TOKEN_SECRET should be complex and hard to guess.

If you use file uploading feature in this kit,
create nested folders uploads/images in the root directory.
But making directories is up to you. You can configure in middlewares/uploadFile.js.
For large projects, it is the best solution to use aws S3, DigitalOcean space, etc., instead of using file system.

Step by Step Installation

mkdir lucky
cd lucky
git clone https://github.com/Bonekyaw/node-express-sql-graphql.git .
rm -rf .git
npm install
npm start

Before you run, make sure you've created .env file and completed required information.

I'm trying best to provide the latest version. But some packages may not be latest after some months. If so, you can upgrade manually one after one, or you can upgrade all at once.

npm install -g npm-check-updates
npm outdated
ncu --upgrade
npm install

If you find some codes not working well, please let me know your problems.

API Endpoints

List of available routes:

POST /api/v1/register - Register
POST /api/v1/verify-otp - Verify OTP
POST /api/v1/confirm-password - Confirm password
POST /api/v1/login - Login
POST /api/v1/refresh-token - Refresh for expired Token
PUT /api/v1/admins/upload - Uploading file or files
GET /api/v1/admins - Get admins' list by pagination

Explanation

Auth routes:
POST /api/v1/register - Register

Request
{
  "phone": "0977******7"
}

Response
{
    "message": "We are sending OTP to 0977******7.",
    "phone": "77******7",
    "token": "3llh4zb6rkygbrah5demt7"
}

POST /api/v1/verify-otp - Verify OTP

Request
{
  "phone": "77******7",
  "token": "3llh4zb6rkygbrah5demt7",
  "otp": "123456"
}

Response
{
    "message": "Successfully OTP is verified",
    "phone": "77******7",
    "token": "xdyj8leue6ndwqoxc9lzaxl16enm0gkn"
}

POST /api/v1/confirm-password - Confirm password

Request
{
  "token": "xdyj8leue6ndwqoxc9lzaxl16enm0gkn",
  "phone": "77******7",
  "password": "12345678"
}

Response
{
    "message": "Successfully created an account.",
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWIwZDhmNmUwNGJiOGMzNWY0MTlkNiIsImlhdCI6MTcxNzI0MzI4MCwiZXhwIjoxNzE3MjQ2ODgwfQ.dvJT2UsGsC1za3lhcu3b3OrMR8BCIKvSlbiIgoBoLJQ",
    "user_id": "1",
    "randomToken": "p1jlepl7t7pqcdgg1sm0crbgbodi67auj"
}

POST /api/v1/login - Login

Request
{
    "phone": "0977******7",
    "password": "12345678"
}

Response
{
    "message": "Successfully Logged In.",
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NTVlMDI5NzE2ZjljYTU1NTRjYTU4NCIsImlhdCI6MTcxNzQwMjQ1OSwiZXhwIjoxNzE3NDA2MDU5fQ.tZNAwjt4rM3tiZgl1LdwfYScbPqoOnMTtaKOTI1pEXY",
    "user_id": "1",
    "randomToken": "25uzndvz1lzu65fpjn9b6suaxj8gm91k"
}

Refresh routes:
POST /api/v1/refresh-token - Refresh for expired Token

Request with Authorization Header
{
    "user_id": "1",
    "randomToken": "b6x9na0z5abc7wix1t2ojj5hdkk7aosm6"
}

Response
{
    "message": "Successfully sent a new token.",
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NTgzODYyNzliMmEzZjEzNDZhYjAwZCIsImlhdCI6MTcxNzA1NzY5NiwiZXhwIjoxNzE3MDYxMjk2fQ.4QyftFaMZE7MT_odGdP8yWsGrclaMstc_867PvTfV88",
    "user_id": "1",
    "randomToken": "x3y20n178w8m6fwptxx5pdwqao8ihpsl"
}

File Upload routes:
PUT /api/v1/admins/upload - Uploading file or files

Request with Authorization Header
Body form-data Key = avatar

Pagination routes:
GET /api/v1/admins - Get admins' list by pagination

Request with Authorization Header
Params Key = page, limit (OR) cursor, limit

How to develop your own products using this Starter Kits

When you add other route files, you can also create routes/v1/api routes/v1/web folders and use prefix for route defination. for example,

const adminRoutes = require("./routes/v1/web/admin");
...
app.use("/v1/admins", isAuth, authorise(true, "admin"), adminRoutes);

Hey, you see the words: isAuth & authorise ?
Yeah, these are custom middlewares. You can create and use them by yourself. I will show how to use my sample authorization middleware.

Authorization as a middleware

const authorise = require('./middlewares/authorise');
...
app.use("/api/v1", isAuth, authorise(true, "admin"), adminRoutes);

router.get('/admins', authorise(true, "admin"), adminController.index);

Authorization as a function

const authorise = require("./../utils/authorise");
...
authorise(true, user, "admin");

true, "admin" means the account is allowed only if its role is "admin". false, "user" means the account is not allowed if its role is "user".
ture, "admin" === false, "user", "supplier"
false, "user" === true, "admin", "supplier"

true, user, "admin" In these parameters, user param is an instance model of the database table.

Pagination

There are two ways in pagination: offset-based and cursor-based. You can read more about pros and cons here. But you can use my pagination logic very easily.

For offset-based

const { withCount, noCount, cursor } = require("./../utils/paginate");
...
const { page, limit } = req.query;

const filters = { status: "active" };
// const order = [['createdAt', 'DESC']];
const order = [["id", "DESC"]];     // For cursor
const fields = {exclude: ["password", "error", "randToken", "updatedAt"]};

const admins = await withCount(Admin, page, limit, filters, order, fields);
res.status(200).json(admins);

For cursor-based

const { withCount, noCount, cursor } = require("./../utils/paginate");
...
const cursors = req.query.cursor ?? null;
const limit = req.query.limit;

const filters = { status: "active" };
// const order = [['createdAt', 'DESC']];
const order = [["id", "DESC"]];     // For cursor
const fields = {exclude: ["password", "error", "randToken", "updatedAt"]};

const admins = await cursor(Admin, cursors, limit, filters, order, fields);
res.status(200).json(admins);

Please, note.
The cursor-based pagination with Sequelize ORM works well with MySQL DB. But it does not work well with PostgreSQL DB because filtering does not working.

I promise new features will come in the future if I have much time.

If you have something hard to solve, DM
phonenai2014@gmail.com
https://www.facebook.com/phonenyo1986/
https://www.linkedin.com/in/phone-nyo-704596135

Find more other Starter kits of mine ?

Nest JS for REST Api

Nest JS + Prisma ORM - REST api

Nest JS for Graphql Api

Nest JS + Prisma ORM - Graphql api

Node Express JS For REST Api

Express + Prisma ORM + mongodb - rest api
Express + Prisma ORM + SQL - rest api
Express + mongodb - rest api
Express + mongoose ODM - rest api
Express + sequelize ORM - rest api - Now you are here

Node Express JS For Graphql Api

Apollo server + Prisma ORM + SDL modulerized - graphql api
Express + Prisma ORM + graphql js SDL modulerized - graphql api
Express + Apollo server + mongoose - graphql api
Express + graphql js + mongoose - graphql api
Express + graphql js + sequelize ORM - graphql api

Mobile App Development

React Native Expo

About

Node express + Sequelize ORM ( MySQL / PostgreSQL ) + REST api

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published