How to access a MongoDB database from a different Server - node.js

In a microservice architecture, I have 2 separate services with different mongoDb databases. Teacher-Service and Student-service.
Now I'm trying to create a login function, once a user submits an email I'd love to query both databases to determine if the user is either a teacher or a student.
How do I implement this in Node.js using the express framework.

I guess you can make HTTP requests to both services (synchronous communication).
For e.g. GET http://teachers.service.com/api/users?email=<input-email> and GET http://students.service.com/api/users?email=<input-email> with some auth header with mind of course :).
Or another way to communicate through services is using asynchronous communication transporters like RabbitMQ, Kafka, NATS and so on. You can search for their documentations to get ground up.

Related

Best way to communicate between services in microservice architecture?

I have 2 microservice in nodejs. one user and other is courses. User service kept info of user info and also the enrolled courses id.
In user listing i need to show the user info + course info.
how do i implement this in microservice architecture so i have not need to wait for user query to return the ids of courses and the get the course info from course service and the combined the result and return it?
I am new to microservices.
You can achieve inter-service communication in two different ways.
Synchronous - Directly call REST APIs of other services
Asynchronous - Implement Asynchronous messaging using Kafka or RabbitMQ (non-blocking)
Both ways have their own advantages and disadvantages.
I am working on Microservices architecture for almost a year, I am using RabbitMQ messaging broker. if you want a highly reliable, highly available and fast mode of communication, you must use Async way only.

Advice on how to design a good architecture for a chat app?

Hello I'm going to implement a social chat app that I what it to meet some requeriments but I'm not sure how to achieve this.
Required:
The app "frontend" should be written in React Native
Support end to end encryption
Support user to user chats
OAuth2.0
Push notifications
History
Django or Node backend
The problems comes in the backend design. I'm thinking on Node.js with websockets or Django with channels but I don't know which is a good DB design to store chats (like telegram) nor how to build a message queue.
Can anyone give me some tips on the design of a chat app? Thanks
Here is my advise
You actually have 3 choices:
Build everything from scratch (as you wrote in your initial question).
It's actually does not matter here will you use Node.js Websockets, Django Channels or Rails Action Cable. They will have pretty the same performance (or maybe Node.js will be a little bit better). You also can use any DB for this: MySQL, PostgreSQL or MongoDB.
For example, you can have these DB tables structure:
Conversations
id
created_at
updated_at
type
name
description
avatar
participants_ids
last_message_id
owner_id
unread_messages_count
Messages
id
created_at
updated_at
conversation_id
text
sender_id
recipient_id
attachments_ids
read_ids
delivered_ids
Users
id
created_at
updated_at
login
fullname
avatar
Attachments
id
created_at
updated_at
type
link
Then, all your users will have a persistent websocket connection with your server and will use it to send/receive messages. Your server will store all messages in DB in appropriate tables.
Also, you Server will provide REST API to retrieve a list of conversations, messages, attachments, other users profile.
I would say, this option is for small load, small amount of users (because of chosen technologies (Node.js/Python/Ruby) and also because you will build it by yourself, not sure you have enough experience in real time apps building)
Use some open source Chat server, like Ejabberd, Tigase, Openfire. They actually already implemented all real time chat things and have good high-load capabilities (people spent 10 years for building them). You just need to integrate them with your App Server.
Probably your App server will provide REST API to retrieve a list of conversations, messages, attachments, other users profile.
Chat server will provide a way to connect, send/receive messages. You also need to write a plugin for chosen Chat server which will track all messages and put them in you Server App DB.
Use some ready to go Cloud Messaging platforms. There are also many examples in the wild, e.g Twillio, ConnectyCube, Layer etc.
For example - ConnectyCube - Messaging and Video calling provider with messaging capabilities, user base, push notifications, video calling, chat bots. You can integrate your App Server with its REST API. Or even do not write your own App Server at all and use completely this platform. Hence save lots of time and money.
With such platforms you do no care about server hosting, server monitor, server up-time and others server related stuff, you just use their APIs and SDKs in your app. Mostly such platforms provide FREE plans along with dedicated Enterprise solutions where you own your data (it is deployed on your own AWS account for example). So highly recommended.
So something like these is possible in your case.
Here is a tutorial of AWS. It uses Node and Redis as the backend.
I followed the tutorial and built a online chat app, which fulfills all your requirements except for the first one because my app only needs web clients.
BTW, I used Redis to do clustering and DynamoDB to save all messages because I am not quite sure about the reliability of Amazon ElastiCache for Redis. In my test Redis works well and it didn't lost any message in 3 months, but my workmates insist that Redis is not reliable(well, they did not provide any data to prove that), as a result I added DynamoDB to ensure the reliability.

Node.js, Socket.IO, Express: Should app logic be in socket handlers or REST api?

I'm planning a non-trivial realtime chat platform. The app has several types of resources: Users, Groups, Channels, Messages. There are roughly 20 types of realtime events having to do with these resources: for instance, submitting a message, a user connecting or disconnecting, a user joining a group, a moderator kicking a user from a group, etc...
Overall, I see two paths to organizing all this complexity.
The first is to build a REST API to manage the resources. For instance, to send a message, POST to /api/v1/messages. Or, to kick a user from a group, POST to /api/v1/group/:group_id/kick/. Then, from within the Express route handler, call io.emit (made accessible through res.locals) with the updated data to notify all related clients. In this case, clients talk to the server through HTTP and the server notifies clients through socket.io.
The other option is to not have a rest API at all, and handle all events through socket.IO. For instance, to send a message, emit a SEND_MESSAGE event. Or, to kick a user, emit a KICK_USER event. Then, from within the socket.io event handler, call io.emit with the updated data to notify all clients.
Yet another option is to have certain actions handled by a REST API, others by socket.IO. For instance, to get all messages, GET api/v1/channel/:id/messages. But to post a message, emit SEND_MESSAGE to the socket.
Which is the most suitable option? How do I determine which actions need to be sent thorough an API, and which need to be sent through socket.io? Is it better not to have a REST API for this type of application?
Some of my thoughts so far, nothing conclusive:
Advantages of REST API over the socket.io-only approach:
Easier to organize hierarchically, more modular
Easier to test
More robust and elegant
Simpler auth implementation with middleware
Disadvantages of REST API over the socket.io-only approach:
Slightly less performant (source)
Since a socket connection needs to be open anyways, why not use it for everything?
Slightly harder to manage on the client side.
Thanks for reading !
This could be achieve this using sockets.
Why because a chat application will be having dozens of actions, like ..
'STARTS_TYPING', 'STOPS_TYPING', 'SEND_MESSAGE', 'RECIVE_MESSAGE',...
Accommodating all these features using rest api's will generate a complex system which lacks performance.
Also concept of rooms in socket.io simplifies lot of headache regarding group chat implementation.
So its better to build everything based on sockets[socket.io or web cluster].
Here is the solution I found to solve this problem.
The key mistake in my question was that I assumed a rest API and websockets were mutually exclusive, because I intended on integrating the business and database logic directly in express routes and socket.io handlers. Thus, choosing between socket.io and http was important, because it would influence the core business logic of my app.
Instead, it shouldn't matter which transport to use. The business logic has to be independent from the transport logic, in its own module.
To do this, I developed a service layer that handles CRUD tasks, but also more specific tasks such as authentication. Then, this service layer can be easily consumed from either or both express routes and socket.io handlers.
In the end, this architecture allowed me not to easily switch between transport technologies.

Communication between RESTful API's on same server with NodeJS

I am building two sets of services on a website (all written in NodeJS on the server), both are using a RESTful approach. For the sake of modularity I decided to make both services separate entities. The first service deals with the products of the site and the second specifically deals with user related functions. So the first might have functions like getProducts, deleteProduct etc... The second would have functions like isLoggedIn, register, hasAccessTo etc... The product module will make several calls to the user module to make sure that the person making the calls has the privilege to do so.
Now the reason I separated them like this, was because in the near future I foresee a separate product range opening up, but will need to use the same user system as the first (even sharing the same database). The user system will use a database that spans the entire site and all subsequent products
My question is about communication between these projects and the users project. What is the most effective way of keeping the users module separate without suffering any significant speed hits. If the product API made a call to the user API on the same server (localhost), is there a signifcant cost to this, versus building the user API into each of the subsequent projects? Is there a better way to do this through interprocess communication maybe? Is simply having the users API run as its own service an effective solution?
If you have two nodes on same server (machine) then you have not bad performance in terms of network latency because both are on localhost.
Then, nodes will be communicating using a rest api, so on the underground, you will use node js sockets. You could use unix sockets instead of http sockets because are faster BUT are worst to debug, so I recommend you don't to that (but it's ok know alternatives).
And finally, your system looks like an "actor design pattern". At first glance this design patter is a little difficult to understand but you could have a look at this if you want more info about actor model pattern:
Actor model for NodeJS https://github.com/benlau/nactor
Actor model explanation http://en.wikipedia.org/wiki/Actor_model

Switching from stored messages to real time chatting in node and express

I am new to server-side development. I'm trying to learn by doing so I'm building an application with express on the server, mongodb as my database and angularjs with twitter bootstrap on the client-side.
I dont know if this is the most practical way but when thinking about how to implement messaging between users I thought of a mongodb model called Conversation with an id and an array of the ids of every user in the conversation and another array of strings that correspond to messages. And then add this model to my REST API.
But lets say all/some of the users in the conversation are online, why not benefit from socket.io. So how can i switch from this to real time chat? Does the interaction with mongodb occure exactly as explained and socket.io just notifies every online user that an interaction has occured? If yes, how? Or is it something else?
socket.io can send real time events to connected sockets, you can use a database for storing messages that are failed to deliver and for offline users.
also, you might want to use something like Redis for this as it has channels with subscribe and publish capabilities.

Resources