I am learning to be a full stack developer and have been building out an application using Node JS as a backend. Since I have lots of experience using Angular I love RxJS. So naturally I was tempted to use RxJS for some types of tasks. Are there any down sides to using RxJS on the backend, more specifically are there any downs sides I can learn about from the following code implementation?
Im using Sequalize and Postgres. As you can see in the Invite Service I have used the Observable stream to first check if the Invite id is valid and then it checks if the recipient email is found in the database as a current user account or not. From either of the three returned values to the route I can now tell the front end what it must do next.
Other notable things:
I am using typical JWT authentication which in this case is a special user in the db since the request is being made from a web app and there is no actual logged in user.
I decided to pass the invite id and the recipient email in the headers which I know is kind of unusual.
This web app is actually just a mediator to deal with a complicated invite process which is being initialized from a React Native app.
Entry Point:
import inviteGenRouter from './routes/invite.routes';
let inviteRouter = inviteGenRouter(services);
api.use('/invite', inviteRouter);
app.use('/api', [passport.authenticate('jwt-bearer', {
session: false,
failWithError: true
}), (err, req, res, next) => {
if (err) {
Logger.error('Authentication Handshake: ', err);
let error = {
error: err.name,
message: err.message
};
let statusCode = err.status || 500;
return res.status(statusCode).json(error);
}
return next();
}], api);
Invite Routes:
router.route('/').get((req, res) => {
if (req.headers.data) {
return services.InviteService.authenticateInvite(req.headers.data)
.subscribe(
_res => {
// Return options for front end.
// If string the invite code was not found.
// If null the associated email was not a user account.
// If user the associated email was found.
},
_error => {
// Some stuff when wrong...
}
);
} else {
// return some sort of error code.
}
});
Invite Service:
class InviteService {
constructor(models) {
this.models = models
}
findInviteById(id) {
return Observable.defer(() => {
return Observable.fromPromise(this.models.Invite.findOne({
where: { inviteId: id }
}));
});
}
findUserById(email) {
return Observable.defer(() => {
return Observable.fromPromise(this.models.User.findOne({
where: { email: email }
}));
});
}
authenticateInvite(token) {
let payload = jwt.verify(token, appConfig.SESSION_SECRET);
return this.findInviteById(payload.inviteId)
.map(_invite => _invite ? _invite : Observable.of('Invalid Invite ID'))
.mergeMap(_invite => _invite._isScalar ? _invite : this.findUserById(payload.email));
}
}
module.exports = InviteService;