samedi 5 octobre 2019

Node.js Router-Controller-Service pattern - Throwing multiple errors from Services (Business logic)

I am developing Node.js Express based API and I am trying to answer myself question if having multiple throws (exceptions) in single Service method is not an anti-pattern.

I am using pattern what can be called Router-Controller-Service (or Controller-Service-Model, etc.)

See this high-level example:

// router.js
controller = require('controller.js')

app.post('/user/create', controller.create)
// controller.js
service = require('service.js')
i18n = require('i18n')

exports create = (req, res, next) => {
  // Input data validator here

  try {
    await service.create(validated_data) // Calling business layer

    res.status(200) // Success
  catch (err) {
    res.json(i18n.__(err)) // Translated error message
  }
}
// service.js
{User, Db} = require('models')

exports create = (data) => {
  if(userExistsInDb(data.username, transaction))
    throw 'user.create.exists'

  newUser = await User.create(data, transaction)

  if(!newUser)
    throw 'user.create.failedToCreate'

  activationToken = generateTokenAndSaveItToDB(transaction)

  if(!activationToken)
    throw 'user.create.failedToCreateToken'


 if(!sendActivationEmail(activationToken))
   throw 'user.create.sendEmailFailed'


 return newUser
}

Keep inmind, that this is fast and high-level explanation pseudocode!

As you can see, I am throwing string keys from Service method create upper into controller and here I am handling it.

I still have feeling that this is anti-pattern and if it is not, than it is surely poorly written and not following best practices.

I would like to find someone who works on large commercial projects in Node.js (or other languages but same pattern) to show me how its handled there, because when I read some blog posts I still have feeling that those are not made for great scalability and they are more launchpad than long time runners (If you understand what I mean).

So is there someone who can tell me how to do it correctly, or in the other hand, tell me that I am over-engineering and over-thinking it and I should use what I want if I keep following basic rules of Router-Controller-Service pattern?

Aucun commentaire:

Enregistrer un commentaire