- Create new repo with name
<your_app>-api
or<your_app>-backend
- Create new app with name
<your_app>-api
or<your_app>-backend
- Connect to previously created github repo
- Download heroku CLI tools
- Install heroku postgres plugin
git clone https://github.com/kemalelmizan/<your_app>-api.git
npm init
- Fill details
npm i --save express
npm i --save body-parser
npm i --save pg
npm i --save db-migrate
npm i --save db-migrate-pg
- Add
"start": "node index.js"
inpackage.json
scripts
npm i -g db-migrate
db-migrate -v
- Add
database.json
config file DATABASE_URL=postgres://xxx db-migrate create <table_name> --sql-file -e production
- Repeat previous step for every tables
- Fill in SQL up and down script in
./migrations/sqls
DATABASE_URL=postgres://xxx db-migrate up -e production
- Setup express routers
- Setup queries
- Generate random tokens by
Array(64).fill(0).map(x => Math.random().toString(36).charAt(2)).join('')
- Setup
API_TOKEN
in heroku DATABASE_URL=postgres://xxx SSL=true npm start
heroku auth:login
heroku auth:whoami
heroku apps
heroku addons --all
heroku logs --tail -a si-backend
- to restart app:
heroku restart -a si-backend
- Install and run docker
docker -v
docker run -p 5432:5432 --name si-backend -e POSTGRES_PASSWORD=sibackend -d postgres
docker ps -a
- to start container:
docker start si-backend
- Add
dev
environment indatabase.json
db-migrate up -e dev
DATABASE_URL=postgres://postgres:sibackend@localhost:5432/postgres npm start
- Create DB migration using local docker:
db-migrate create <table_name> --sql-file -e dev
db-migrate create users --sql-file -e dev
- Fill in SQL up and down script in
./migrations/sqls
db-migrate down -e dev
db-migrate up -e dev
DATABASE_URL=postgres://postgres:sibackend@localhost:5432/postgres API_TOKEN=abc npm start
- Single Responsibility Principle
- Add folders according to folder structure
- Restructure
index.js
into correspondingcontroller
s andmodel
s - Add
controller/helper/response.js
to wrap the response - Add
controller/helper/validation.js
for validation libraries - Add
controller/access/admin.js
,buyer.js
andseller.js
for access control matrix - Add
controller/auth/api.js
forAPI_TOKEN
validation - Separate
controller/auth/user.js
andmodel/auth/user.js
- Add
controller/auth/access.js
to validate module access rights - Set environment variables in postman for easy access, add
host
,API_TOKEN
,user_email
andaccess_token
npm install --save dotenv
- Create
.env
file - Register Google API Credential to get Client ID
GOOGLE_KEY
and Client secretGOOGLE_SECRET
here
https://console.developers.google.com/apis/credentials
- Add following values to
.env
file
SESSION_SECRET=abcd
PORT=8080
DATABASE_URL=postgres://postgres:sibackend@localhost:5432/postgres
SSL=false
API_TOKEN=abc
GOOGLE_KEY=xxx.apps.googleusercontent.com
GOOGLE_SECRET=xxx
CLIENT_ORIGIN=http://localhost:3000
npm install --save passport
npm install --save passport-google-oauth
const googleAuth = passport.authenticate('google', { scope: ['profile'] })
inindex.js
- Route triggered by the React client
app.get('/google', googleAuth)
- Routes that are triggered by callbacks from OAuth providers once the user has authenticated successfully
app.get("/google/callback", googleAuth, (req, res) => {
const io = req.app.get("io");
const user = {
name: req.user.displayName,
photo: req.user.photos[0].value.replace(/sz=50/gi, "sz=250")
};
io.in(req.session.socketId).emit("google", user);
res.end();
});
- Setup socket
app.use((req, res, next) => {
req.session.socketId = req.query.socketId;
next();
});
- Clone
https://github.com/funador/react-auth-client
for frontend test, changeAPI_URL
inconfig.js
tohttp://localhost:8080
- Finish CRUD for each modules (model, controller and route)
- Create all requests template for CRUD in postman
- unit tests and test coverage
- third party libraries: file upload, nodemailer
- third party APIs: mailgun, user ID APIs https://github.com/sahat/hackathon-starter#obtaining-api-keys
- ngrok for public testing
- caching using redis
- timeout and circuit breaker handling
- security: penetration testing, injection, OWASP
- documentation: swagger