Skip to content

A boilerplate for Node.js, Express, Mongoose, Heroku, mLab, Nodemon, PM2, and Babel. REST/GraphQL API Server | PaaS | SaaS | CaaS | CI/CD | Jest | Supertest | Docker | MongoDB | PostgreSQL | Sequelize | Lodash | RxJS | JWT | Passport | Socket.IO | Redis | CircleCI

License

olympikesoft/Backend-Starter-Kit

 
 

Repository files navigation

Backend Starter Kit

🚚 A boilerplate for 🌟 Node.js 🌟, Express, Mongoose, Heroku, mLab, Nodemon, PM2, and Babel.

Build Status Coverage Status // Dependency Status devDependency Status

Live Demo

This seed repository provides the following features:

  • ---------- Essentials ----------
  • API routing with Express.
  • Data query language with GraphQL.
  • Object document mapping with Mongoose.
  • Object relational mapping with Sequelize.
  • Utility functions with Lodash.
  • Reactive extensions with ReactiveX.
  • Secure authentication with JWT.
  • Authenticate requests with Passport.
  • Real-time bidirectional communication with Socket.
  • In-memory data structure store with Redis.
  • ---------- Tools ----------
  • Next generation JavaScript with Babel.
  • JavaScript static code analyzer with ESLint.
  • Type annotations with Flow.
  • Unit testing with Jest.
  • HTTP testing with Supertest.
  • Test coverage integration with Codecov.
  • Automatically restart application with Nodemon.
  • Keeping application alive with PM2.
  • Error tracking with Sentry.
  • API workflow with Insomnia.
  • ---------- Environments ----------
  • Server-side platform with Node.
  • Operating system with Linux.
  • Text editor with Atom.
  • Version control with Git.
  • Code repository with GitHub.
  • Fast and deterministic builds with Yarn.
  • Cloud application hosting with Heroku.
  • Cloud NoSQL database hosting with mLab.
  • Cloud SQL database hosting with ElephantSQL.
  • Cloud Storage‎ hosting with Cloudinary.
  • Cloud memory cache hosting with RedisLabs.
  • Monitoring service with UptimeRobot.
  • Log management service with Papertrail.
  • Performance and security with Cloudflare.
  • Software container with Docker.
  • Continuous integration with CircleCI.

Table of Contents

Getting Started

  1. Clone this Boilerplate
$ git clone --depth 1 https://github.com/Shyam-Chen/Backend-Starter-Kit.git <PROJECT_NAME>
$ cd <PROJECT_NAME>
  1. Install Dependencies
$ yarn install
  1. Run the Application
$ yarn start
  1. Test the Application
$ yarn test
  1. Build the Application
$ yarn build

Practical Examples

  • Database
    • REST
    • GraphQL
  • Storage‎
    • REST
    • GraphQL
  • Authorization (passport)
    • JSON Web Tokens (passport-jwt)
    • Facebook (passport-facebook)
    • Google (passport-google-oauth20)
    • Twitter (passport-twitter)
  • Realtime
    • WebSockets (socket.io)
    • GraphQL Subscriptions (subscriptions-transport-ws)
  • Messaging
    • Email (nodemailer)
    • SMS
  • Payment
    • Stripe (stripe)
    • PayPal (paypal-rest-sdk)
  • Playground
    • QR Codes
    • ...

Infrastructure:

Dockerization

  1. Build and run the Container
$ docker-compose up
  1. Run a command in a running container
$ docker-compose exec api <COMMAND>
  1. Remove the old container before creating the new one
$ docker-compose rm -fs

Configuration

Default configuration

// src/env.js
export const SECRET = process.env.SECRET || <PUT_YOUR_SECRET_HERE>;
export const MONGODB_URI = process.env.MONGODB_URI || <PUT_YOUR_MONGODB_URI_HERE>;
export const POSTGRES_URL = process.env.POSTGRES_URL || <PUT_YOUR_POSTGRES_URL_HERE>;
export const REDIS_PORT = process.env.REDIS_PORT || <PUT_YOUR_REDIS_PORT_HERE>;
export const REDIS_HOST = process.env.REDIS_HOST || <PUT_YOUR_REDIS_HOST_HERE>;
export const SENTRY_DSN = process.env.SENTRY_DSN || <PUT_YOUR_SENTRY_DSN_HERE>;

Development environments

# docker-compose.yml
version: '2'

services:
  api:
    build:
      context: .
      dockerfile: Dockerfile.dev
    ports:
      - "3000:3000"
    environment:
      - SECRET=<PUT_YOUR_SECRET_HERE>
      - MONGODB_URI=<PUT_YOUR_MONGODB_URI>
      - POSTGRES_URL=<PUT_YOUR_POSTGRES_URL_HERE>
      - REDIS_PORT=<PUT_YOUR_REDIS_PORT_HERE>
      - REDIS_HOST=<PUT_YOUR_REDIS_HOST_HERE>
      - SENTRY_DSN=<PUT_YOUR_SENTRY_DSN_HERE>
    tty: true

Production environments

# Dockerfile.prod
ENV SECRET <PUT_YOUR_SECRET_HERE>
ENV MONGODB_URI <PUT_YOUR_MONGODB_URI>
ENV POSTGRES_URL <PUT_YOUR_POSTGRES_URL_HERE>
ENV REDIS_PORT <PUT_YOUR_REDIS_PORT_HERE>
ENV REDIS_HOST <PUT_YOUR_REDIS_HOST_HERE>
ENV SENTRY_DSN <PUT_YOUR_SENTRY_DSN_HERE>

Using Libraries

  1. Example of REST
import { Router } from 'express';

import { List } from '~/document';

const router = Router();

router.get('/', async (req, res, next) => {
  try {
    const data = await List.find({}).exec();
    res.json(data);
  } catch (err) {
    next(err);
  }
});

export default router;
  1. Example of GraphQL
import gql from 'graphql-tag';

import { List } from '~/document';

export const listTypeDefs = gql`
  type List {
    _id: ID!
    text: String!
  }

  type Query {
    list: [List]
  }
`;

export const listResolvers = {
  Query: {
    async list(root, { text }) {
      try {
        const data = await List.find({}).exec();
        return data;
      } catch (err) {
        console.error(err);
      }
    }
  }
};
  1. Example of Document
import mongoose, { Schema } from 'mongoose';

const listSchema = Schema({
  text: String
});

export const List = mongoose.model('List', listSchema);
  1. Example of Relational
export default (sequelize, DataTypes) => {
  const List = sequelize.define('List', {
    text: DataTypes.STRING
  });

  return List;
};
  1. Example of Lodash
import { Observable } from 'rxjs';
import { of } from 'rxjs/observable';
import { lowerFirst, pad } from 'lodash';

Observable::of(lowerFirst('Hello'), pad('World', 5))
  .subscribe(value => console.log(value));
  // hello
  // World
  1. Example of ReactiveX
import { Observable } from 'rxjs';
import { timer, of } from 'rxjs/observable';
import { mapTo, combineAll } from 'rxjs/operator';

Observable::timer(2000)
  ::mapTo(Observable::of('Hello', 'World'))
  ::combineAll()
  .subscribe(value => console.log(value));
  // ["Hello"]
  // ["World"]
  1. Example of JWT
  1. Example of Passport
  1. Example of Socket
import socket from 'socket.io';

const io = socket.listen(server);

io.on('connection', socket => {
  console.log('WS: Establish a connection.');
  socket.on('disconnect', () => console.log('WS: Disconnected'));

  socket.emit('A', { foo: 'bar' });
  socket.on('B', data => console.log(data));  // { foo: 'baz' }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.1/socket.io.js"></script>
<script>
  const socket = io();

  socket.on('connect', () => console.log('WS: Accept a connection.'));

  socket.on('A', data => {
    console.log(data);  // { foo: 'bar' }
    socket.emit('B', { foo: 'baz' });
  });
</script>
  1. Example of Redis
client.hmset('thing', {
  foo: 'js',
  bar: 'html',
  baz: 'css'
});

client.hgetall('thing', (err, object) => {
  console.log(object);
});

Directory Structure

.
├── flow-typed
├── src
│   ├── document
│   │   └── index.js ...
│   ├── graphql
│   │   └── index.js ...
│   ├── relational
│   │   └── index.js ...
│   ├── rest
│   │   └── index.js ...
│   ├── api.js
│   ├── config.js
│   └── pm2.js
├── test
│   ├── graphql
│   │   └── xxx.spec.js ...
│   └── rest
│       └── xxx.spec.js ...
├── .babelrc
├── .editorconfig
├── .eslintrc
├── .gitattributes
├── .gitignore
├── Dockerfile.dev
├── Dockerfile.prod
├── LICENSE
├── Procfile
├── README.md
├── circle.yml
├── docker-compose.yml
├── package.json
└── yarn.lock

About

A boilerplate for Node.js, Express, Mongoose, Heroku, mLab, Nodemon, PM2, and Babel. REST/GraphQL API Server | PaaS | SaaS | CaaS | CI/CD | Jest | Supertest | Docker | MongoDB | PostgreSQL | Sequelize | Lodash | RxJS | JWT | Passport | Socket.IO | Redis | CircleCI

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 100.0%