2

We developed a monolithic API to be used as a SAAS. In the company we also develop custom build for some customers.

Some of our customers are asking for some features that are already implemented in the monolithic application.

We are thinking about splitting our API into microservices, but our major questions are the following :

  • Does microservices can be reuse across different projects ?
  • If we do split, do we create a microservice that everybody use or do we create an instance per custom build ?

E.G :

project A use "User", "Project" so we deploy 2 microservices
project B use "User", "Project", "Store" so we deploy 3 microservices

total number of microservices deployed : 5
  • If we create an instance of each microservice per custom build, won't be too hard to manage the communication between all the microservices within the same custom build ?
  • Or do we stick with one instance per microservice that everybody use and we specify the project source ?

As we are using C# GraphQL. We also thought about creating Nuget package for each component, so each package will contains :

  • Exposed GraphQL Queries / Mutations
  • His own db
  • His own logic

E.G :

- Api A install "User" & "Project" packages
- 3 db are instantiated "Api.A", "Api.A.User", "Api.A.Project"

- Api B install "User", "Project" & "Store" packages
- 4 db are instantiated "Api.B", "Api.B.User", "Api.B.Project" & "Api.B.Store"

But does it make sense to do that ?

In my mind it could very similar from Hangfire https://www.hangfire.io/

Note that we are currently using AWS Serverless to host our applications. An important point is that we are a small team 2-4.

We are very open minded so any suggestion is good to hear.

Thank you !

Cyrille
  • 17
  • 2

1 Answers1

1

First of all, I would like to say is that there is no right way here and I am providing my point of view from the way we have already done things hoping it will guide you in finding a solution best suited for your requirements.

So to understand your dilemma, you have a base vanilla product which is an API SAAS and there is a customized deployment for some customers as well. But as you are having to build custom deployments for each customer you are noticing a common pattern, wherein a lot of the functionality is repeated across the SAAS for each customer.

Now assuming I have the requirement correct, I would say micro-services will provide definite benefits in your case in terms of scaling and customer-specific customization which will be managed by independent teams.

But a lot of this depends on how your business logic is structured and how big and vast your customization is. Some of these questions should drive your solution are.

  1. Can you store Customer-specific data in a central data store or at customers' end ? & How are your databases going to be structured and how many of them?
  2. How big are the customizations ? are they cosmetic or workflow adhering?
  3. How much cross-communication you expect across various services like User, Store, and Project and if there is any communication across A.User - B.User or A.Project - B.Store, etc?

Now moving to some of the important things you might want to consider post answering the above questions.

Consideration 1. If the data stores can be allowed to be in a single central place you can go ahead with a single cluster where all your micro-services can be deployed. But looking at the data provided I can assume you have multiple databases per customer and I would recommend to keep them separate and not introduce any coupling between them. Thus you may end up with one microservice or microservice per customer which talks only to that customer's database. ( more in fig.1)

Consideration 2. The customization as far I the norm goes should be separated from the service itself and your every service should have an input for configuration loading which will drive the service behavior. Again depending on how big your customization is there can be a limit to this configuration and in those cases, I woul recommend creating a new service with customizations built-in.

Consideration 3. This is a major factor for deciding the number of microservices you may have, but the boundary of each service should be defined by the domain, for example, a User service, a Store service, and a Project service. These are the vanilla services that interact with each other to produce a valid business scenario. And each of the customers is just specialized instances of these services.

ok Now that this is done lets gloss over your primary questions...

  1. Des microservices can be reused across different projects? -- Yes you can, but again it depends on how you have designed the business workflow, configuration injection.

  2. If we do split, do we create a microservice that everybody uses or do we create an instance per custom build? -- Yes this would be an ideal scenario enabling separation of concerns across projects as we do not want to mix data boundaries and client-specific sensitive configurations. That said there might be a case where the single microservice solution is what is demanded but should be done with caution.

  3. If we create an instance of each microservice per custom build, won't it be too hard to manage the communication between all the microservices within the same custom builds? -- Communication across microservice is an important part or factor which is more often than not unavoidable in most cases. Thus considering you will be requiring some form of cross microservice communication you can look at an enterprise bus or API communication based on your requirement. But it is a known triviality is my opinion.

  4. Or do we stick with one instance per microservice that everybody uses and we specify the project source? -- I would not recommend this as the example stated in your question for a module for database injections doesn't sound a good idea to me. This will cause a highly coupled system design. And this might also mean if one service fails all your customer sites go down. you surely wouldn't want that !!!

Now as it is said a picture is worth a thousand words...

enter image description here

damitj07
  • 2,689
  • 1
  • 21
  • 40
  • Thank you for your detailed response and the time that you took to write it. Your response gave us some ideas about how to implement everything and even if it's still not crystal clear it surely helps. The communication between microservices is now our major concerns, as if a ms do a breaking change, how alert everybody that they have to update their code ? Each microservice has to own his own S.D.K ? I did a github [repo](https://github.com/CyrilleFormont/microservices-graphql). As I said I'm struggling on the implementation of the HTTP communication between the services. – Cyrille Jan 10 '20 at 04:06
  • Hello Cyrille, Thanks for the response. In terms of communication having an HTTP channel for communications across micro-services is possible but has its limitations. Are you guys open to use of any Enterprise Buses like Rabitmq in your projects? This simplifies and answers lot of questions, like alerting other services and etc. – damitj07 Jan 10 '20 at 04:20
  • Heres some references - https://stackoverflow.com/questions/45208766/microservices-why-use-rabbitmq – damitj07 Jan 10 '20 at 04:29
  • Well yes but in some cases we are forced to used a synchronous request or maybe we are misunderstanding something. We are using the message broker to alert all the services that something changed e.g : "RegisterUserEvent" or "RemoveUserEvent". But let's take another example : Content & Project are 2 ms, 1 content has a projectId and 1 project has multiple users, only the users in the project can access the content. So if I request a Content my ms Content has to check if the user is in the project, so I have to do a synchronous request from Content to Project to check if he can access it ? – Cyrille Jan 10 '20 at 05:54
  • Understood. Rabbitmq provides Pub-sub functionality as a service. On top of that, you can build interfaces or wrappers to provide for Synchronous ( RPC ) or Async ( Publisher-Subscriber) methods. Thus you can have 2 types of methods in your Bus utility class/ One for RPC and one For Publish which is fire and forget – damitj07 Jan 11 '20 at 07:07