This is a node boilerplate meant to be used as a skeleton for a new node application. Its main purpose is to provide a generic API easily deployable to heroku with Redis and Postgres free addons in order to have a quick start point with robust authentication/authorization techniques without many dependencies.
- npm
- NodeJS
- Postgres
- Redis
{
"awilix": "^3.0.9",
"awilix-express": "^1.1.0",
"body-parser": "^1.18.3",
"chai": "^4.2.0",
"crypto": "^1.0.1",
"dotenv": "^6.1.0",
"express": "^4.16.4",
"express-jwt": "^5.3.1",
"express-session": "^1.15.6",
"glob": "^7.1.3",
"jsonwebtoken": "^8.5.1",
"mocha": "^5.2.0",
"pg": "^7.9.0",
"pg-hstore": "^2.3.2",
"redis": "^2.8.0",
"sequelize": "^5.2.12",
"sequelize-cli": "^5.4.0"
}
- 0 Environments
- 1 DB
- 2 Dependency Injection (IOC)
- 3 Authentication Endpoints
- 4 Tests
- 5 Error Handling
- Create a heroku account
- Create new application
- Add postgres and redis addons (you'll need to add a credit card to validate account but it's still free)
- Attach heroku application to your git master branch
- Push to master to deploy application (but fist follow the rest of the steps to configure the env)
- Create a .env file in the root folder with the following information:
PORT = 80
TOKEN_EXPIRESON = 30
DATABASE_URL = postgres:https://postgres:@127.0.0.1:5432/[database-name]
REDIS_URL = redis:https://localhost:6379
- To start developing use
npm run startdev
- Configure
/app/config/config.json
file with credentials to dev and production databases
{
"development": {
"username": "root",
"password": null,
"database": "database_development",
"host": "127.0.0.1",
"dialect": "postgres"
},
"test": {
"username": "root",
"password": null,
"database": "database_test",
"host": "127.0.0.1",
"dialect": "postgres"
},
"production": {
"username": "root",
"password": null,
"database": "database_test",
"host": "127.0.0.1",
"port": 5432,
"dialect": "postgres",
"ssl":true,
"dialectOptions":{
"ssl":{
"require":true
}
}
}
}
- Go to
/app
folder
cd app
- Run migrations in dev environment
npx sequelize db:migrate
- Run migrations in production environment
npx sequelize db:migrate --env production
- Go to
/app
folder
cd app
- Create a migration file that you need to edit (
app/models
folder)
npx sequelize migration:generate --name [name_of_your_migration]
The container placed in app/ioc/container.js
is configured to get by convention every file that meets the expression **/*.service.js
so that is the naming convention that you should follow for every service.
It is expected to split the architecture in app/domain-entity and inside that folder the following structure:
app/domain-entity/domain-entity.api
(api endpoints and particular middlewares for that api)app/domain-entity/domain-entity.application
(application services - to orchestrate the connection between db and domain entities)app/domain-entity/domain-entity.domain
(hard business logic)
Also the api endpoints are expected to meet the namig expression **/*.api.js
that app/ioc/router.js
sets.
It is possible to manually inject other classes or functions in the container if needed.
POST /api/sessions
{
"username" : "admin",
"password" : "123456"
}
{
"id": 1,
"username": "admin",
"token": "499eedc1-8e42-44b1-9e69-83139abd12d6"
}
Status Code | Type | Description |
---|---|---|
200 | OK |
Ok |
400 | BAD REQUEST |
Incorrect username or password |
500 | INTERNAL SERVER ERROR |
Unexpected server error |
POST /api/users
{
"username" : "admin",
"password" : "123456"
}
{
"id": 1,
"username": "admin"
}
Status Code | Type | Description |
---|---|---|
200 | OK |
Ok |
400 | BAD REQUEST |
Username already exists |
500 | INTERNAL SERVER ERROR |
Unexpected server error |
GET /api/users/:id
Status Code | Type |
---|---|
auth |
{{sessionToken}} |
{
"id": 1,
"username": "admin"
}
Status Code | Type | Description |
---|---|---|
200 | OK |
Ok |
401 | BAD REQUEST |
invalid token |
403 | BAD REQUEST |
Token expired |
404 | NOT FOUND |
Usern not found |
500 | INTERNAL SERVER ERROR |
Unexpected server error |
In /test/suite.js
every file that meets the expression **/*.test.js
is used when running the test script with mocha + chai. This allows you to place the tests right next to your logic to enable quick access to them for other developers.
You can see an example in /app/users/users.application/tests
.
To run tests:
npm test
In your entity/[entity.api]
folder, you should create another folder called middleware that has an errorMiddleware that catches every error specific to your entity's api.
This makes it easier to document the specific errors each endpoint returns. For more info about how to set up error middlewares in your api check awilix-express
documentation.