Seed project for a node.js express application with typescript.
# install 🧷
yarn
# or
npm i
# run 🏃🏾♀️
yarn start
# or
npm start
# run 🏃🏾♂️ with watcher 👀
yarn start:watch
# or
npm run start:watch
# build 🚧
yarn build
# or
npm run build
# run 🚀 in production
yarn start:production
# or
npm run start:productionIf you start the application a debugging web socket is started / an inspector enabled:
$ yarn start:watch
yarn run v1.15.2
$ nodemon
[nodemon] 1.19.1
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: C:\src\express-seed\src/**/*
[nodemon] starting `npm start`
> express-seed@1.0.0 start C:\src\express-seed
> node --inspect=5858 -r ts-node/register ./src/index.ts
Debugger listening on ws://127.0.0.1:5858/51141c14-bb7e-4bae-9932-ef1ceadb49cd # <- debugger
For help, see: https://nodejs.org/en/docs/inspector
Application is running on http://localhost:8080For more information visit https://nodejs.org/en/docs/guides/debugging-getting-started/.
# run tests 🎈
yarn test
# or
npm test
# run tests 🎈 with watcher 👀
yarn test:watch
# or
npm run test:watch
# run tests 🎈 with watcher 👀 on only changed git files 🎳
yarn test:watchChanged
# or
npm run test:watchChangedFor more information visit https://jestjs.io.
We think you should write less unit tests and more integration tests.
Spotify is using the Microservice Testing Hondeycomb for that. Read https://labs.spotify.com/2018/01/11/testing-of-microservices/ for more information.
To make real requests in your tests you can use the ./src/test/local-server.ts.
Just call await LocalServer.run(); and your application gets started. Do this await request(LocalServer.app).get('/v1'); to make a request against the started application.
The
./src/api/v1/routes/some-route/some.route.spec.tsfile shows how to use the local-server.
To send requests we user supertest.
For more information and how to use supertest visit https://www.npmjs.com/package/supertest.
To use the database in your integration test you can get the instance with await Database.getInstance();.
Look at
./src/services/hello-world.service.spec.tsfor a database example.
The clean up of the database and application service which are used in the tests runs automatically.
To clean the databse in between single runs you can call await LocalDatabase.clear().
In the
src/test/test-setup.tsfile theLocalServer.stop();andLocalDatabase.destroy();gets called after each test file.
The file
./src/config/config.tsdescribes the environment variables.
For passwords, database connections, log level and other stuff we need to set different values on different environments. The test environment should not use the production database and otherwise.
To set your environment variables you can just set them in your system:
# windows
set NODE_ENV=production
# mac
export NODE_ENV=production
# linux
export NODE_ENV=productionOr do it like we do it in the package.json for the start or start:production task:
# yarn
yarn run cross-env LOG_LEVEL=test yarn start
# npm
npm install -g cross-env
cross-env LOG_LEVEL=test npm startWe use apache couchdb as a database.
On local or test environment we start an express-pouchdb instance which acts like a couchdb server.
You have to set the environment variables to call a real couchdb in production:
- DATABASE_URL
- DATABASE_PORT
- DATABASE_NAME
The url should contain the password and username, for example
'http://admin:password@otherhost.com'.
Just call await Database.getInstance() from ./src/database.ts file to recieve an instance of the database.
To work with the database we use CouchDB nano, visit https://github.com/apache/couchdb-nano for more information.
To parse application/json or application/x-www-form-urlencoded requests, we use the expressjs/body-parser.
For more information and how to use it visit https://github.com/expressjs/body-parser.
The application is secured with helmet.js.
For more information visit https://helmetjs.github.io/.
To write async express controllers you should use asyncMiddleware:
this.router.get('/some/url', asyncMiddleware(
async (req: express.Request, res: express.Response, next: express.NextFunction): Promise<void> => {
res.send(await this.controller.someAsyncMethod())
})
);