🚚 A boilerplate for 🌟 Node.js 🌟, Express, Mongoose, Heroku, mLab, Nodemon, PM2, and Babel.
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.
- Clone this Boilerplate
$ git clone --depth 1 https://github.com/Shyam-Chen/Backend-Starter-Kit.git <PROJECT_NAME>
$ cd <PROJECT_NAME>
- Install Dependencies
$ yarn install
- Run the Application
$ yarn start
- Test the Application
$ yarn test
- Build the Application
$ yarn build
- Database
- REST
- GraphQL
- Storage
- REST
- GraphQL
- Authorization (
passport
)- JSON Web Tokens (
passport-jwt
) - Facebook (
passport-facebook
) - Google (
passport-google-oauth20
) - Twitter (
passport-twitter
)
- JSON Web Tokens (
- Realtime
- WebSockets (
socket.io
) - GraphQL Subscriptions (
subscriptions-transport-ws
)
- WebSockets (
- Messaging
- Email (
nodemailer
) - SMS
- Email (
- Payment
- Stripe (
stripe
) - PayPal (
paypal-rest-sdk
)
- Stripe (
- Playground
- QR Codes
- ...
Infrastructure:
- Build and run the Container
$ docker-compose up
- Run a command in a running container
$ docker-compose exec api <COMMAND>
- Remove the old container before creating the new one
$ docker-compose rm -fs
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>
- 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;
- 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);
}
}
}
};
- Example of Document
import mongoose, { Schema } from 'mongoose';
const listSchema = Schema({
text: String
});
export const List = mongoose.model('List', listSchema);
- Example of Relational
export default (sequelize, DataTypes) => {
const List = sequelize.define('List', {
text: DataTypes.STRING
});
return List;
};
- 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
- 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"]
- Example of JWT
- Example of Passport
- 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>
- Example of Redis
client.hmset('thing', {
foo: 'js',
bar: 'html',
baz: 'css'
});
client.hgetall('thing', (err, object) => {
console.log(object);
});
.
├── 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