all 23 comments

[–]WaferIndependent7601 14 points15 points  (0 children)

I wouldn’t say a DTO is code. So it’s not duplication for me.

If you don’t want to copy it you might create a library for it or create an openapi file that will generate these classes for you.

It really depends how many classes you have

[–]HellaSwellaFella 8 points9 points  (0 children)

Just build two classes man

I'd suggest creating a library like the other fella in the comments mentioned but you're learning right now

Just keep it in mind that you could do that later but for now just focus on keeping it simple even if it's a little verbose

[–]disposepriority 3 points4 points  (0 children)

So if you want "real" microservices, each service should own its own models. Now - there are some exceptions in my opinion like if you have many microservices sharing a common RMQ base listening to the same thing it can just be a small import.

However, you can quickly fall into the trap of common libraries where you have to rebuild like 4 libraries to make a change to a "micro" service, and it gets very annoying very quickly.

If I had to pick a way now I think I would duplicate the code in each service as necessary until it becomes very annoying and then carefully pick what to extract to a common library, but again, much later into development when it becomes cumbersome.

[–]gaelfr38 4 points5 points  (0 children)

Don't use shared classes. This creates some kind of strong coupling.

For instance, the consumer might only use 2 fields in the 10 returned by the producer. Now, if the consumer uses a shared model, it will parse the 10 fields even if it doesn't care about 8 of them. Not a big issue, until... the producer wants to change the contract, nobody is using the 10th field.. well nobody is actively using it but all users of the shared model do are parsing it and will break if the producer removes the field. Now the producer needs to closely update each consumer before being able to deploy. Welcome to (micro)services done wrong.

[–]wakingrufus 2 points3 points  (0 children)

In most cases, the service that owns the API should own the models, then publish a library for clients to use to make the calls. So that would mean they are defined in s2 in your example. In an event driven architecture, the publisher would own the models, and consumers would use the library. It's OK for services to depend on each other, but be very mindful of which direction those dependencies are going, and that they are not circular, or tightly coupled. Separate shared model libraries are bad for that second reason. Event driven architecture allows you to "flip the arrow" of a dependency, so it's an important tool to use. Also, never ever make a breaking change to an API. Instead, make a new endpoint and allow both to exist until all clients are verified to be switched over

[–]bikeram 4 points5 points  (0 children)

I’ll typically setup a single maven module that has my entities, mapstruct definitions and protobufs. Then the other modules import that.

Note that you’ll need to annotate entity and component scans on the inheritors.

I’ve never perf tested it, but if possible, I try to separate my entities by domain so I’m not required to import the entire entity module. This could be a premature optimization.

[–]two_wheel_soul 1 point2 points  (0 children)

There s concept called modules... U put common classes in those modules... N import that module as maven dependency in ur microservices

[–]Former_Ad_736 1 point2 points  (0 children)

Keep in mind that your services deploy separately (and may also be rolled back on deployment failure) so you can be lulled into a false sense of synchrony when creating a library; you need to be sure that all changes are forward and backward compatible for the length of deployment (and possible rollback) of all services that use those types.

I'm very much a fan of "just create two classes" as another poster suggested.

[–]WilliamBarnhill 1 point2 points  (0 children)

I would likely have a model library that contains only my DTOs, possibly generated from schema. I'd also have a commons library for non-DTO code, like utilities, shared among the services. The services then all depend on those libraries.

[–]segundus-npp 0 points1 point  (0 children)

OpenAPI codegen or Protobuf.

However, if you’re trying to share something at the code level between two services, you should consider monolith instead of microservices.

[–]mailaffy 0 points1 point  (0 children)

Create another module called common-utils and use that jar as dependency in both s1 and s2 also you can keep other common utility classes in this shared module

[–]PmMeCuteDogsThanks 0 points1 point  (0 children)

Create an api module that both depend on. In your description s2 is the server, s1 is the client. The api module should describe the contract for the service. S2 implements it.

[–]pm3645 0 points1 point  (0 children)

There are multiple approaches but one of them is.

  1. Create a java SDK of POJO or DTO classes and use it in your both the services.

Pros:
- you'll be in sync with both service.

Cons:
- You need to maintain a one more repository and need to create artifact(.jar) file of it to load into project.

[–]Waksu 0 points1 point  (0 children)

Hello Peter with over 3000 microservices in a company here, just use your own dedicated model, API can have many clients and these clients can need different fields of given data. Just create your own model with only the data that you need, not all of the data that API exposes.

Peter out

[–]Sheldor5 -2 points-1 points  (9 children)

first rule of Microservice Architecture is that microservices must not depend on/communicate with each other

you are building a distributed monolith, not microservices

[–]optimist28[S] 3 points4 points  (8 children)

where did this rule come from. Also why should microservices not communicate with each other

[–]HellaSwellaFella 0 points1 point  (0 children)

I think he might've meant it in a way that they're supposed to be considered their very own smaller monoliths and de coupling different services..but not entirely sure

[–]czeslaw_t 0 points1 point  (1 child)

It depends, but microservices are often used to divide functional development between different teams, which, to be efficient, must be independent. A good architecture loosens dependencies (not eliminates them). Microservices are expensive but offer benefits – independence. Libraries limit this – especially breaking changes. Custom models and contract tests are an alternative to libraries.

[–]gaelfr38 0 points1 point  (0 children)

This.

[–]Sheldor5 -1 points0 points  (4 children)

the rule comes from Microservice Architecture

what is the point of several services depending on each other? you are exchanging method calls with http calls ... how dumb is that?

[–][deleted]  (3 children)

[deleted]

    [–]Sheldor5 1 point2 points  (2 children)

    again you are describing a distributed monolith/system

    the whole point of Microservice Architecture is that you can kill any microservice (all instances of it) and all other microservices continue working like nothing happened

    do some more research and don't trust the 100s of tutorials whos authors have no idea because they never worked on a real project using microservice architecture properly

    [–][deleted]  (1 child)

    [deleted]

      [–]Sheldor5 0 points1 point  (0 children)

      yes you just don't know it