News for hackers. Stuff that matters.
Re:Give Me Back My Monolith by eweise on Wednesday March 13, 2019 @06:27PM (#19384567)
We use grpc instead of rest for internal synchronous communication but we've also found that by using event pub/sub between services, that there are not many uses cases where we have direct calls between services.

We used to have a parent maven pom and common libraries but got rid of most of that because it caused too much coupling. Now we create smaller more focused common libraries and favor copy/paste code over reuse to reduce coupling. We also moved a lot of the cross cutting concerns into Envoy so that the services can focus on business functionality.

Re:Give Me Back My Monolith by danmaz74 on Wednesday March 13, 2019 @09:33PM (#19385769)
> favor copy/paste code over reuse to reduce coupling.

This looks like a big step backwards to me.

Re:Give Me Back My Monolith by barbecue_sauce on Thursday March 14, 2019 @01:23AM (#19386710)
I would say it depends on the stability of what's being copy/pasted. If it's just boilerplate, it's less concerning.

In my opinion, decoupling should be prioritized over DRYness (within reason). A microservice should be able to live fairly independently from other microservices. While throwing out shared libraries (which can be maintained and distributed independently from services) seems like overkill, it seems much better than having explicit inheritance between microservice projects like the original poster is describing.

Re:Give Me Back My Monolith by danmaz74 on Thursday March 14, 2019 @05:11AM (#19387571)
Sure, no problem with boilerplate.

For any non trivial code, which needs to be maintained and be kept well tested, to the contrary of the OP, I would favor shared libraries over copy/paste.

Re:Give Me Back My Monolith by lucidone on Wednesday March 13, 2019 @09:30PM (#19385755)
How do you handle cases where your client is awaiting a response with a decoupled pub/sub backend? E.g a user creates an account and the client needs to know their user id.

Would that user object be the responsibility of one service, or written to many tables in the system under different services, or...?

Re:Give Me Back My Monolith by RhodesianHunter on Wednesday March 13, 2019 @10:55PM (#19386163)
For one, you could use something like snowflake IDs so that whatever server receives the user data first can generate and return an id for that user before tossing the data on a queue to be processed.
Re:Give Me Back My Monolith by lucidone on Wednesday March 13, 2019 @11:34PM (#19386327)
How would you approach a situation where a client updates a record in service A, and then navigates to a page whose data is returned by service B, which has a denormalized copy of service A's records that hasn't consumed and processed the "UpdatedARecord" event?

Do we accept that sometimes things may be out of sync until they aren't? That can be a jarring user experience. Do we wait on the Service B event until responding to the client request? That seems highly coupled and inefficient.

I'm genuinely confused as to how to solve this, and it's hard to find good practical solutions to problems real apps will have online.

I suppose the front end could be smart enough to know "we haven't received an ack from Service B, make sure that record has a spinner/a processing state on it".

Re:Give Me Back My Monolith by jdmichal on Thursday March 14, 2019 @06:11AM (#19387843)
You use eventing only when eventual consistency is acceptable. In your scenario, it sounds like it is not. So then you should use synchronous communication to ensure the expected experience is met. However, that also means that now you can't do stuff with service B without service A being up. So you're trading user experience against resiliency.

Also, you should check your domains and bounded contexts and reevaluate whether A and B are actually different services. They might still legitimately be separate. Just something to check.

Re:Give Me Back My Monolith by romanows on Thursday March 14, 2019 @12:15AM (#19386490)
Some people advocate that microservices own their data and only provide it through an API. In this scenario, Service B would need to query Service A for the authoritative copy of the record. I think the standard way to deal with the query and network time is, yes, to wait until Service A provides the data and timeout if it takes "too long".

Then your question is about optimizing on top of the usual architecture which hopefully is an infrequent source of pain that is worth the cost of making it faster. I could imagine some clever caching, Service A and Service B both subscribing to a source of events that deal with the data in question, or just combining Service A and B into one component.

Re:Give Me Back My Monolith by eweise on Thursday March 14, 2019 @10:27AM (#19389510)
I would create the account directly from the initial call and return its ID and then publish an account created message. Any other services could receive the message and perform some action such as send a welcome email or do some analytics.
Re:Give Me Back My Monolith by mirkules on Wednesday March 13, 2019 @06:33PM (#19384637)
gRPC and Envoy are exactly the things we are exploring now, although copy/paste would never fly in our org.
Re:Give Me Back My Monolith by praneshp on Thursday March 14, 2019 @11:58AM (#19390432)
I know copy paste is looked down upon, but it's even suggested as a good practice (a little bit) in golang. A little copying is better than a little dependency.

https://go-proverbs.github.io/