2

What would be the best practice of handling input validation in microservice? Especially for the duplicated data?

To give context, say I have 3 services:

User

Typical user service with User object with a lot of details (~40 fields in the object)

Asset

Has Asset object like

{
  id,
  name,
  companyId,
  descripton
}

News

News service has a Feed object that have reference to both User and Asset however for News it only care subset of both User and Asset fields (ie. only need 10 of User field)

{
  id,
  title,
  description,
  asset,
  user

I'm aware of the concept that News should have its own view of User and Asset and data consistency can be done through message hub. So the question now becomes if I have an http post request for new feed so the request body looks something like

{
  "title": "title",
  "description":"description",
  "asset": {
    "id": "asset1",
    "name": "phone",
    "companyId": "company-1"
  },
  "user": {
    "id: "user-1",
    "name": "name",
    "comapnyId": "company-1",
    "roles": ["reporter"]
  }
}

How should I perform the input validation for both user and asset field in News service? Say the input validation for user is something like:

  • user role can't be mix of reporter and manager (either one)
  • name < 120 char
  • companyId must be null if user role is a client, otherwise it must be set

Should I then have this input validation sits in both News and User service? Using a common/shared object with validation seems simpler but I always thought it's kind of antipattern or am I missing something here?

PS - I tried to avoid direct service to service call (also client can't perform multiple requests due to limited network bandwidth) so just storing assetId and userId in the Feed won't work

PSS - the backend code is written in Go so OOP approach may not be best suited

5
  • 1
    Why would you post user and asset data to the news service? Imo you should only accept a userId and assetId in that post request and do a lookup on the locally cached data for those objects.
    – Rik D
    May 12, 2020 at 18:29
  • Because I need to avoid multiple calls on either side (If performed on client side because network is limited and if performed on server side it creates dependency and if user/asset service is down then news won’t work)
    – GantengX
    May 13, 2020 at 0:28
  • A Microservice architecture solves a set of very specific problems and causes some very challenging technical side effects. It seems you’re now running into these side effects and have to spend a lot of effort trying to ‘get it right’, which might not even be possible given your last comment.
    – Rik D
    May 13, 2020 at 6:06
  • Is the role of a user fixed (always a manager, always a client, etc.) or can it depend on the news-item in question (user-1 is a reporter on news-1 and a manager on news-2)? What should happen if the User service knows user-1 by the name "John Doe" and the News service gets the request as you showed in the question (so a different name)? What if I use different names for the same user-id in requests to the News service? May 13, 2020 at 6:24
  • 1
    @GantengX: If you're trying to keep the amount of network calls to a minimum, then microservices aren't the right approach. Microservices come with the drawback of needing to perform multiple calls when you need interaction with multiple bounded contexts.
    – Flater
    May 13, 2020 at 13:18

1 Answer 1

1

As is already visible from the comments, there is neither an easy nor an ideal way. It all depends on your application and your requirements.

Nevertheless, an approach that might be possible for your system is, that the news service passes validation requests on to the user service and asset service when a new news object is created. So, when you receive the post in your example, news service asks user service: "hey, someone says he has userid-1, name 'name', and company 'company-1' - is this ok and can that person create news?". If the answer is "OK", then store the fields you need, but do not depend on the user service every time someone reads that object.

If the user service is down, you'll need some kind of backup strategy. You might store the object as a "request" and decide when the user service is up again, or simply retry a given number of times before reporting failure. Note that in a productive live environment, "down" usually means that the monitoring system is already aware of the problem and in the process of restarting the service. Therefore, "down" is a condition over a few seconds at most.

1
  • Yeah this seems to be the most reasonable solution. It can simplify the request not to include the full user object and just the user id and News service can store only partial value of the user object once it's fetched from the user service. I suppose this is the cost of separating into multiple services. It also can ensure that user is a valid user (exists, correct validation rule, etc).
    – GantengX
    May 13, 2020 at 16:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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