A progressive Node.js framework for building efficient and scalable server-side applications.
Nest framework Chat App as a proof of concept.
- Node v12 LTS
- MongoDB
- Postman
# build docker image for the app
$ docker build -t mokhaled3003/chatapp .
$ docker pull mongo:latest
$ docker-compose up
# development mode
$ npm install
$ npm start
## Test
# unit tests
$ npm run test
- visit Chat App Api Docs to find Users Module Api Docs.
- visit Socketio client tool to test the Chat Gateway Events
- please provide the access token from the responce Login ENDPOINT in the following object and provide it to socketio-client-tool in the 'socketio options json' to initiate the connection successfully else you won't be able to connect to the websocket server.
{
"query":
{
"token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXJ0ZXN0IiwiaWF0IjoxNjA2NjAwNTg4fQ.J04x78GKIChkAodMDeNUhmsrM7OI2Lun1k8mkegq-NM"
}
}
{
"text": "Hello World!"
}
- please note that in development mode you must change mongoose connection string in '.env' file at MONGODBDEV
- please note that in running from docker-copmose file you will be in production mode it will switch connection to MONGODBPROD so please if you have any mongod service running in your host on port 27017 it will stop excutting containrization process,because i run the mongo service inside the container in the same port and exposing it to 27017.
# stop mongo local server before docker-compose up
$ service mongod stop
- now the container won't run as root user
//making sure that container isn't running as root
RUN addgroup nodejs && adduser -S -s /bin/bash -g nodejs nodejs
RUN chown nodejs:nodejs /var/
USER nodejs
- i have used passport-jwt as my third party authentication service , so in './src/users/jwt.strategy.ts' you will find i have made custom jwt token extractor to extract token from query param in websocket connection to allow only authenticated users to connect to messages service websocket server.
jwtFromRequest : function(client) {
var token = null;
if (client && client.handshake.query.token) {
token = client.handshake.query.token;
}
return token;
},
i have extended the Logger Class in nestjs to provide saving logs to file './log.txt' you can find implementation
import { Logger } from '@nestjs/common';
import * as fs from 'fs'
export class MyLogger extends Logger {
log(message: string, trace: string) {
console.log(trace)
fs.appendFile('logs.txt',`${trace} ${message}\r\n`,(err)=>{
})
super.log(message, trace);
}
verbose(message: string, trace: string) {
console.log(trace)
fs.appendFile('logs.txt',`${trace} ${message}\r\n`,(err)=>{
})
super.verbose(message, trace);
}
}
i have implemented validation pipe for user registration
import { ApiProperty } from '@nestjs/swagger';
import { IsString,MinLength,MaxLength, IsNotEmpty } from 'class-validator'
export class CreateUserDTO {
@ApiProperty()
@IsString()
@MinLength(4)
@MaxLength(10)
@IsNotEmpty()
readonly username: string;
@IsString()
@MinLength(4)
@MaxLength(10)
@IsNotEmpty()
@ApiProperty()
password: string;
}
as per our technical interview you asked me what will happen if database container crashed , i used volume to persist data
volumes:
- mongodata:/data/db
- Author - Mohamad Khaled