0

Imagine an http request in a RESTful API that needs to request the database to perform validations before proceeding, but some of those database requests would need to execute again if the validation succeeds.

Assuming the validation is made in a separate layer, is there any design pattern that deals with this problem? I mean, by isolating the validation layer and the business logic layer I would need to perform the same database request again in the business layer if the request passes the validation which sounds very wrong. Should I cache the results of the database requests made by the validation layer in some way? What would be the correct way to deal with this?

3
  • Caching is potentially super complex, since there is the possibility of using outdated data. This could even be security-relevant in some cases, especially if caches are improperly shared across requests. Adding a caching layer can also reduce performance in some cases. So I wouldn't consider caching unless the time spent waiting for queries is preventing you from achieving your performance goals.
    – amon
    Dec 28, 2021 at 14:52
  • 1
    There are 2 hard problems in computer science: cache invalidation, naming things, and off-by-1 errors. Dec 28, 2021 at 15:38
  • I'm a little unsure about how and why you are doing validation in the database layer. Are you executing commands and then rolling them back?
    – JimmyJames
    Dec 28, 2021 at 17:22

1 Answer 1

8

It sounds like you have a problem with the "API" first approach (not the design pattern, but the knowledge of the infrastructure).

If you forget that you have an API, how would you handle this? The HTTP layer shouldn't know anything about the validation. If you decide to expose the functionality over gRPC for example, you should not have to change anything other than core method calls.

I imagine you have some sort of filter/middleware that makes a DB request and aborts if the request fails. Stay away from such approaches as they fracture your domain logic and hide it away from you.

Which brings me to the main point: validation is not a layer. It is a domain rule and as such should be encapsulated inside the domain logic. Instead of thinking about the API like this: http request -> validation -> (db ->) (http controller ->) business logic -> db -> http response, think of it like http request -> business -> http response. The API layer should not know about the validation. It should only map the parameters to the business logic calls.

If you know NodeJS for example, don't do the following:

app.post('path', validateStuff, (req, res) => {
  // req mapping
  business(mappedParam)
})

instead do:

app.post('path', (req, res) => {
  // req mapping
  const result = business(mappedParam)
  // result mapping (mostly for exception handling)
  res.json(mappedResult)
})

function business(param) {
  validateStuff(param)
  // business stuff
  return result
}

Having this leads you to fetch the data first and then validate it.

Another thing to think about is that even if your architecture is a bit backwards, and even if it does too much requests to the DB, does it matter? Is the impact significant enough that you have to optimize it? Because introducing caching is way more complex and refactoring is sometimes just not worth the effort. Remember, the current code works, if it doesn't interfere with nothing else, why change it, just take a note that what you did was not optimal and do not repeat the mistake.

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.