#Is it a bad practice to pass entities in DTO between microservices, as opposed to the id?

1 messages · Page 1 of 1 (latest)

buoyant creek
#

Hi, bit of a newbie here when it comes to best practices!

So I was trying out microservices, and here's the scenario that I have a question about:

I have an API gateway, with a guard applied to one of its controllers

@VerifyThingsAboutRecordGuard("")
@Patch(":id")
doSomethingWithExistingRecord...

Inside the guard, I use the "id" route parameter of the request to fetch the record using the provided id, and do some checks on it.

If it passes all checks, I want to append it to the request, similar in fashion to how passport does with the user (req.user).

Then, in the controller, I'll have a decorator to grab that appended record, and i will pass it along to the service.

The record I pass in is quite a bit more "hefty" than if I would just send over the id of it. And I can't really validate it either - in my DTO it simply looks like this

@IsNotEmpty()
@Type(() => Record)
record!: Record;

If it wasn't clear why I thought it was an issue to send in the recordId instead, it's because, the work to find the record was already done. So if I just passed in the id I'd have to fetch it again.

Are there any pitsfalls here or am I thinking the right way? Is any of the ways bad practice?

Thanks a lot in advance!

#

Also, this is probably a very, very dumb question, but I was worried, what if the requesting client instead appends their own req.record ? is there any scenario where this would not be overwritten by me in the guard?

faint rune
#

@buoyant creek - One thing that is a big MUST is to always, always, always validate and sanitize incoming data into your system, when it is coming from an untrustworthy source. There can be absolutely no "what if"s.

A couple of rules of thumb about microservices and see if you want to incorporate them or not.

Usually microservices are done because of the scale of the app and the team working on it. And, those teams MUST be autonomous. That means, any changes they make shouldn't affect anyone else. Not unless there has been mutual agreement between the teams. And that is where their API comes in and also where data and business logic autonomy comes in.

API - You can, in effect, do whatever is necessary. No rules on how the API is done and why there are a plethora of techniques, from message buses to gRPC. The only rule is, the API is agreed upon between the consumers (client teams) and the microservice team. That being said, in order to keep that autonomy up as best as possible, you want to have APIs that break rarely and if possible, never. They should also be as simple as possible.

And in most cases, "simple" means just sending what is absolutely necessary to get the information or action required out of the microservice.

Data and business logic autonomy - microservices should depend rarely, if at all, on other microservices for their data storage needs. And, nothing but microservices should be grabbing or manipulating database data. They might use the same database, but they shouldn't make changes in data schema "on their own". So, if entities are shared, and they really shouldn't be, there needs to be agreement between the consumers of the entity, if a change is needed. (and why you can hopefully see why microservices should have their own data stores).

Ok - so there you have the basics.