Search code examples
node.jsmongodbmongooseservercloud

How can I orchestrate my 3 Nodejs servers to work together with shared MongoDB Models


The title probably is a bit misleading but I couldn't word it properly. I'll try and be super explanatory and try to even draw something if necessary. I am aware this is a huge topic of web development/ cloud development/ backend, and I am now mostly looking for direct answers to this problem I am facing and some high-level introduction as to what I can expect if I get to scale. When the time comes I'll start reading up on the topics in more depth.

My setup is as follows. 3 backend servers using Nodejs+Express and Typescript. Two for serving two types of different customers and one admin server. I'll name them Server A, B and Admin. I use MongoDB for the Database, and now sure if I'll use Azure or AWS for hosting these.

My requirements are as follows:

  1. Shared Models called Thing1, Thing2, should be accessed by all 3 servers. Admin primarily interacts with them and creates them, but the ServerA/B needs to access them to be able to send them to the customers. Thing1 is accessed by ServerA while Thing2 by both A and B

  2. I need a way to communicate between servers, as something that happens in ServerA should update a model contained in ServerB as well. One solution could be splitting this part of the interaction into a totally new service and let it handle communication between servers with maybe an event queue or socket connection. Or should I just make HTTP requests from ServerA to ServerB?

Problems:

  1. Typescript requires all of the src to be under same root directory, so I am not sure how to share the MongoDB Models.

  2. I was thinking of using a socket connection and maybe a fourth server to serve as a bridge in the interactions but I am confused at how would that work in the cloud if I had multiple instances and so on. (How do HTTP requests work in this case as well? Probably a load balancer that directs traffic to different instances)

So a flow would be,

  1. Admin creates Thing1 ->
  2. ServerA interacts with it ( Admin should somehow access model from ServerA and update it to reflect new thing being created, eg add the thing id to the model ) ->
  3. ServerA Model gets updated ( we're already in ServerA so simple) and Model from ServerB should also get updated, Thing1 deleted and Thing2 created. This step is pushing me towards having fourth service to handle this, as it has to communicate with both other services. Both ServiceA/B need to access Thing2.

I am so sorry for the explanation but I am confused a bit as well on how to approach this. I'll explain further whatever is needed. My current problem is just how to access different MongoDB collections from these different services and how to propagate changes/ events to all services.


Solution

  • We can split the big problem in:

    1. Architecture
    2. Deployment
    3. Tools

    Architecture

    I suggest you follow a pattern like DDD and Mediator Pattern, the last one is very effective in your case (communication between things) check this page for an intro on Typescript, but it is better to read Eric Evans DDD the inventor of DDD.

    Deployment

    If you are unsure where to host your app I suggest you to use Docker. With it, you build an image deployable either on AWS or Azure.

    Tools/Framework

    I suggest you read about:

    • monorepo like rush for splitting app.
    • inversify for DI
    • DISCLAIMER: I'm the author of this package MediatR-ts I have made a porting on Typescript of the famous MediatR