4

I work in a small company and we are about to delve into the Microservices world. As expected, we are hitting a few bumps.

Let us focus on a small bounded context: work order.
This bounded context is composed of a technician, a team and the actual work order. A team is composed of a group of technicians and a team manager, who is also a technician.
One aspect of the software: a technician should be able to see all the work orders issued to them and, if they happen to be the manager of a team, they should be able to see all the work orders issued to any members of that team.

Should I create a single service, or two: one to manage the teams and technicians and one to actually manage the work orders. The problem with the second approach is that part of the logic that controls which orders should be retrieved will have to be placed inside the API Gateway / BFF.
As the work orders have no knowledge of teams (which I actually think it is the correct design), the API Gateway would have to retrieve the teams in which the technician is the manager in order to retrieve all the work orders for all members of those teams.

My concern here is that it seems some business logic is leaking to the API Gateway and I am not sure that is all right. I am also afraid of creating anemic microservices. On the other hand, this bounded context might be used on a different software, which may not make use of the concept of teams.

I also thought about creating a third service to coordinate this work but have not found any reasons to support the idea as of now.

So, to summarize: should I create one, two or three services? I am bound to creating two, but cannot seem to decide just yet.

0

I would go with 1 service with well designed modules, so it can be easily split into multiple services in future.

Also do not put any logic into API gateway, that will clutter up your system and make future maintenance / resource balancing / updates harder to do. API gateway should only care about what message send to what service, it shouldn't care about internal logic of those services.

Set-up monitoring of the service and pay attention of problems in development/production. If you see that spliting service into multiple can yield more benefits than the cost, do it.

I would look for balancing / performance issues (eg work orders are bottleneck and slowing whole system) and development issues - lot of people working on service, divided into teams, which take care only of part of system, and having lot of conflicts between them.

One general note - microservices will add lot of complexity and cost to your system. They can pay off, but lot of systems will do just fine without microservices. Best way how to adopt microservices I have seen so far, was to build one service / monolith and split up when needed. And always take care to modularize the service / monolith, so you can split up (or merge) easilly.

0

Are you sure the bounded context (Technician, Team, WorkOrder) is optimal?

Team and WorkOrder sound like two separate entities to me. I imagine a WorkOrder could be created before assigning it to a Team. Perhaps a WorkOrder could also be re-assigned to another Team if it wasn't assigned correctly in the first place.

I'd consider two separate bounded contexts and two services: Teams and WorkOrders. There would be a dependency between these contexts, but that should be easily manageable. Teams and WorkOrders probably have an ID anyway, so it shouldn't be too hard to keep track of the WorkOrders assigned to a team without direct object references.

If that sounds like overengineering, which it could be, you could also begin with a single service and single bounded context but keep the option to divide it later on by making sure your design is as modular as possible. Direct references like Team->List or WorkOrder->Team could prove problematic if a WorkOrder could be created before assigning it to a Team or it could be reassigned to another Team at any point. I would avoid them inside a service and in the interface of a service. You can always provide a separate query to get the orders currently assigned to a team.

0

Services are about data ownership and business logic, not about entities, and you don't want to put in the same service data and logic that don't belong together. So it is expected that different services own different data related to the same entities. For example, a service will own the technicians names and birthdays and another will own the team each technician belong to.

To me, it it seems desirable that the service that owns the logic of the teams structure is not the same service that manages work orders, as work orders business logic should be independent of teams. From what you say, work orders are assigned directly to technicians, regardless of their team.

So, given these conditions, on one hand, you have a service that allows you to query the work orders of a given TechnicianId or a list of TechnicianIds. Where you get these TechnicianIds is not a concern of this service.

On the other hand, you have a service that given a TechnicianId can tell you the team it belongs to and the list of TechnicianIds of that team if the calling TechnicianId is the manager.

Now you only need to put the things together: - Call the first service to get the Teams TechnicianIds if you are the team manager (the service knows it) - Call the second service passing the list of TecnicianIds (or only one if you are not manager)

How you put these two requests together is a technical issue that can be solved in many ways (from the UI directly on from an API gateway) and, as it's a technical issue, you are not leaking business logic there. The most important part is that these two services don't know about each other. They are autonomous and decoupled.

0

The choice of microservices already tells you that you want multiple services here. A single service might be a good choice, but it isn't microservices.

The API Gateway knows about all the different services. But it shouldn't know any details. This demands increased communication between the services. But the API Gateway doesn't know about that. It knows about the part the client knows about; and how to route that to a service. That's all it knows.

You probably need three services.

Technicians request a list of their workorders through the technician service. The technician service knows about the workorder service, but not how it works. It tells the workorder service which technician is making the request.

The team service knows that technician exist, and knows that some technicians are managers. (or you can make them separate; doesn't matter here) And it knows that workorders exist, but not anything about them. So you can add a service capability here that gets the team members under the manager, and then for each team member it contacts the technician service and asks for the workorders for that technician. Then the technician service can go and get the workorders.

There is a lot more network traffic than a monolithic service, but that's how the decoupling is achieved. If you change the concept of teams so that you have subteams, or different roles in the teams with different capabilities, you only change the team service.

If you're worried about anemic services or models or whatever, diagram out the relationships, and walk through what happens from end to end when a request is made. The anemic ones will show up as extra useless steps in the middle where the inputs and outputs are merely passed through with no aggregation, filtering, or side effects.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.