Нормально ли для Express.js промежуточное программное обеспечение полагаться на предыдущее промежуточное программное обеспечение в цепочке?

#javascript #node.js #express

#javascript #node.js #экспресс

Вопрос:

Допустим, у меня есть запрос POST в моем API POST /api/comments , где я создаю комментарий. Комментарии принимаются в древовидной структуре массива (у каждого комментария есть дочернее свойство, у которого могут быть подпункты). У меня есть несколько «событий», которые происходят до отправки ответа.

Я могу поместить весь необходимый код в одну промежуточную программную функцию следующим образом.

 function postComments(req, res, next) {
    // handle general authentication
    if (!isAuthenticated()) {
        next("not authenticated ...");
    }

    // handle more specific authentication (ex. admin)
    if (!isAdmin()) {
        next("not admin ...")
    }

    // validate req.body.comments so that each comment has allowed form
    if (!areCommentsValid()) {
        next("not valid ...");
    }

    // modify comments for database insertion
    const modifiedComments = modifyComments();

    // database insertion
    db.insert(modifiedComments)

    res.sendStatus(201);
}
  

В приведенном выше примере общая аутентификация и проверка подлинности администратора могут использоваться на нескольких маршрутах, и следующие промежуточные программы не полагаются на них, код все еще работает. Итак, код этих двух имеет смысл.

В этом примере мое промежуточное программное обеспечение выполняет несколько действий.

Что я думал, что смогу сделать, так это разбить следующий код на несколько промежуточных программ.

 function userAuth(req, res, next) {
    // handle user authentication
}

function adminAuth(req, res, next) {
    // handle admin auth
}

function validateComments(req, res, next) {
    // handle req.body.comments validation
}

function modifyComments(req, res, next) {
    // modify comments
    // req.commentsForDb = modifiedComments;
}

function postComments(req, res, next) {
    // insert req.commentsForDb into database
}
  

Итак, теперь я разделил свое промежуточное программное обеспечение на 4 разных промежуточных программного обеспечения, но проблема в том, что промежуточные программы зависят друг от друга.

postComments требуется modifyComments установить req.commentsForDb , modifyComments требуется validateComments и т.д.

Какой метод предпочтительнее?

Ответ №1:

Это совершенно допустимо, и на самом деле именно так и предполагается использовать промежуточное программное обеспечение. При условии, что вы правильно вызываете next с кодом ошибки, когда что-то идет не так в промежуточном программном обеспечении, где вы должны прекратить пересылку к следующему.

Дополнительным преимуществом здесь является то, что вы можете повторно использовать свои промежуточные программы многими различными маршрутами. Еще одна вещь, которую вы можете сделать, это генератор закрытия промежуточного программного обеспечения, например, промежуточное программное обеспечение auth на основе роли:

 function auth(role) {
     return function(req, res, next) {
          // get my user
          // ...
          // check user role
          if user.role != role {
              return next(new Error("Auth failed"))
          }
          return next()
     }
}

// this route is for admins
app.get(
    "/foo", 
    auth("admin"),
    foo
)

// this one for users
app.get(
    "/bar", 
    auth("user"),
    foo
)