Description One of the strong points of Node.js is its easiness to setup a Web Socket server and its endpoints. If fact, nowadays every modern Web or Mobile Application makes use of Web Sockets to provide an ehnanced and more immersive User Experience.
Probably the most used Node.js library to setup Web Sockets is socket.io, which makes straightforward to handle the communication between two entities (usually server and client) through Web Sockets and additionally provides useful features to allow more complex patterns and the realization of sophisticated Web and Mobile Applications.
Let's add then a /random-jobs
endpoint which opens a Web Socket connection with a client.
It will then automatically emit an event randomJob
to the consumer (i.e. the connected client) with a random job taken from the public Github Jobs API.
It must also listen to the 'jobRequest'
event, with a location string as data.
It will then fetch a random job with the received location parameter (still from the public Github Jobs API) and emit an event randomJob
with the found job.
In order to test the backend API, you can use serve to use a simple frontend, located in the index.html
file of the lesson folder.
Goals
- Build a Web Socket
/random-jobs
Endpoint by using socket.io - The endpont should be able to receive a
jobRequest
event with alocation
data and answer with a random job from the free Gihub Jobs API - Once connected to the Web Socket endpoint, every 3 seconds it should automatically send a random job, taken from the same API and without location filter, to the connected client via a
randomJob
event
Allowed Npm Packages
axios
: http client used to perform http requestsbcryptjs
: password hasherbody-parser
: Express middleware to parse the body requestsexpress
: web serverjsonwebtoken
: create and verify Json Web Tokensmoment
: date managermongoose
: MongoDB clientnconf
: configuration files managernode-uuid
: library to generate uuidsredis
: Node.js Redis clientsocket.io
: Web Socket management libraryvalidator
: string validation librarywinston
: logger
Requirements
-
The results must be saved in
userdata/data.json
-
The logs must be saved under
storage/logs/nodeJobs.log
-
The Data Logger must reside into
libraries/dataLogger.js
-
The File Logger must reside into
libraries/fileLogger.js
-
The MongoDB configuration variables must reside into
config/secrets.json
, which MUST be gitignored -
A
config/secrets.json.example
file must be provided, with the list of supported keys and example values of theconfig/secrets.json
file -
Configuration values must be loaded by using
nconf
directly at the beginning of theindex.js
-
The Mongoose configuration must reside into a
mongoose.js
file, loaded directly from theindex.js
-
The Mongoose client must be made available in Express under the
mongooseClient
key -
The Users Model must be saved into
models/users.js
and have the following Schema :- username: String, required, unique
- email: String, unique
- password: string, required
-
The Users Model must be made available in Express under the
usersModel
key -
The
/users
routes must be defined in theservices/users/users.router.js
file by using the Express router -
Middlewares used in the
/users
endpoints must reside in theservices/users/middlewares/
folder -
Optionally use only
async
/await
instead of pure Promises in all/services/
files -
User input validation errors must return a
422
Json response with{ hasError: 1/0
,error: <string>
} as response data (payload) -
User passwords must be
bcrypt
hashed before being saved into the database -
JWT management (creation and verification) must be handled in
libraries/jwtManager.js
, which must export a Javascript Class. It must be available in Express under thejwtManager
key -
The Secret Key used to create the tokens must be stored in the
secrets.json
file -
/sessions
routes must be defined inservices/sessions/sessions.router.js
-
/users
API Endpoints must check for authenticated users through the use of aservices/sessions/middlewares/auth.check.js
middleware -
HTTP Status Codes must be coherent: 401 is no authentication is provided, 403 is the token is expired or invalid
-
Communication with Redis server must happen entirely inside
libraries/redis.js
which must export a Javascript Class. It must be available in Express under theredisClient
key -
The
Redis
class constructor must take the Redis password as an argument, which must be saved into theconfig/secrets.json
file. All methods insidelibraries/redis.js
must return a Promise -
The second argument of the
JwtManager
must be the aRedis
instance, in order to perform token invalidation -
The
auth.check.js
middleware must also check if the token has been invalidated -
The token invalidation of the
(DELETE) /sessions
route must happen inside atoken.invalidation.js
middleware -
All the Web Sockets code (i.e. the use of the
socket.io
package) must reside intoservices/randomjobs/randomjobs.js
-
The
/random-jobs
endpoint must periodically emit arandomJob
event with a random job data -
The
/random-jobs
endpoint must listen for ajobRequest
endpoint and alocation
data and emit arandomJob
event with a random job data for the requested location
Suggestions
- Since
socket.io
requires an instance of the Node.jshttp
server, modify your startingindex.js
file to use it
// index.js
[...]
const express = require('express');
const app = express();
const http = require('http').Server(app);
[...]
http.listen(3000, () => console.log('App listening on port 3000!'));
- You can customize the Web Socket endpoint with
const io = require('socket.io')(http, {
path: '/random-jobs'
});
- Use serve to test the Web Sockets. Just globally install it, run
serve -p 5001
from the/lessons/lesson10-SocketIo
folder and point your browser tohttp://localhost:5001/