Table of Contents
This repository contains implemented functionalities that can be reused and extended as required.
- NestJs, the progressive Node.js framework for building server-side applications.
- MongoDB, the no SQL database.
- NPM as package manager.
- Docker, a solution for building,sharing and running application images.
In order to run this project and extend its functionalities you need to follow some few steps :
- Make sure that Node.js (>= 10.13.0, except for v13) is installed on your operating system. ( Download Here)
- NestJs CLI (Command Line Interface)
npm i -g @nestjs/cli
- Any API platform for building and using APIs, i used Postman.
- Clone the repo
git clone https://github.com/hamza-mahjoub/nestjs-backend-template.git
- Install NPM packages
npm install
- Add a .env file
CONNECTION_STRING="MongoDb connection string" APPLICATION_PORT = 3000 // port is 3000 by default. MORGAN_ENV = "dev"
Or
- make sure you have docker installed.
- pull the image :
docker pull hamzamahjoub/nestjs-template
- run the following docker run command:
docker pull hamzamahjoub/nestjs-template
``` sh
sudo docker run -d -p 3000:3000 --name nestjs-template hamzamahjoub/nestjs-template
- Run the project using
npm run start:dev
Examples will be provided to showcase some features of this project.
- you can run all the tests at once using
npm run test
or select the file test
npm run test -- testfile.spec.ts
The user module is subject to two test types under src/user/test/
:
This test focuses on the component, so a mocking is required whenever there is a call to another component/service to focus on the tested code and not its behaviour with its external dependencies.
For the user.controller
, we mocked the service call using data stubs located under __mocks__
.
For the user.service
,which uses calls to the database, we mocked these calls by creating our own mongoose-like service.
const ApiServiceProvider = {
provide: UserService,
useFactory: () => ({
createUser: jest
.fn()
.mockResolvedValue(userStub(USER_STUB_ID, USER_STUB_EMAIL)),
getAll: jest
.fn()
.mockResolvedValue([userStub(USER_STUB_ID, USER_STUB_EMAIL)]),
get: jest
.fn()
.mockResolvedValue(userStub(USER_STUB_ID, USER_STUB_EMAIL)),
deleteById: jest.fn().mockResolvedValue({ deletedCount: 1 }),
updateUser: jest
.fn()
.mockResolvedValue(userStub(USER_STUB_ID, 'FlenBenFelten')),
updatePassword: jest
.fn()
.mockResolvedValue(userStub(USER_STUB_ID, USER_STUB_EMAIL)),
}),
};
user stub represents a user instance.
This test focuses on the behaviour between different component, assuming that unit tests were done in a good manner, any error in this level will generate from the relation between a component and its external dependencies.
in our case we tested the relation between user.component,user.service and the mongodb database.
const apiClient = () => {
return supertest(app.getHttpServer());
};
it aims to test the functionalities and performance in this application. In this test we used the Cypress which is a fast and easy to learn end to end testing framework.
Run this command to open cypress interface then choose the corresponding test.
npm run cypress:open
As the name suggests, this test is conducted by the user to verify wether the developed functionalities meets the requirements or not and finally accepting it or not. It represents the final test phase.
Check user-acceptance-test-plan.pdf.
The project pipeline code can be found under .github/workflows
and its structure is as follows
At first two jobs will run in parrallel:
- One will take care of eslint to make sure that code is clean and homogeneous.
- The other will run the tests via commande
npm run test
.
eslint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: stefanoeb/eslint-action@1.0.2
with:
files: src/
Test:
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '14'
- name: 'Create .env file'
run: |
touch .env
echo CONNECTION_STRING="${{ secrets.MONGO_DB_CONNECTION_STRING }}" >> .env
- run: npm install
- run: npm test
This part of the pipeline is packaging and depends on the two other tests via this code snippet:
needs:
- Test
- eslint
We will build our poject, create a Docker image then login to our docker hub and push the image.
This part of the pipeline is deploiement and depends on the packaging phase. The project is deployed on an Amazon Ec2 instance.
It follows these steps:
1- Login to the instance via ssh.
2- Shut down the running container.
3- Pull the new released image.
4- Launch a new container via docker run
commande with port and name of the container specification.
In order to acces the site a security group must be configured to let access on port 3000(default nestjs port).
You can view the backend via the following link : http://13.125.232.134:3000/
- ✅ Morgan middleware
- ✅ Setting up Configuration .env .
- ✅ Setting up MongoDB Database.
- ✅ User Module
- ✅ User model.
- ✅ CRUD (Create,Read,Update,Delete)
- 🔲 Swagger.
- 🔲 Authentification Module.
- 🔲 Mailing Service.
- 🔲 RBAC (Role Based Access Control)
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Hamza Mahjoub - mahjoubhamza036@gmail.com
Project Link: https://github.com/hamza-mahjoub/nestjs-backend-template.git