Возвращение статуса при сохранении в несколько БД в одном вызове API - PullRequest
0 голосов
/ 26 января 2020

Я всегда был в большей степени фронтменом. Latley, я разрабатывал бэкэнд, используя Node.js и Mon goose. Когда пользователь регистрируется, я хочу создать пользователя (user db), создать токен электронной почты (emailToken db), а затем отправить электронное письмо одним способом ... и я даже не уверен, что это правильный подход это.

Я с трудом пытался сформулировать это, так что извините, пожалуйста, мой мозг. Вопрос, который у меня есть, основан на возвращении статуса при вызове этой конечной точки. Насколько я знаю, можно вернуть только один статус, так что же на самом деле означает 200? В моем коде это означает, что все 3 вещи успешно? Я чувствую, что этот подход неверен. Ситуация может возникнуть, когда пользователь создан, но остальная часть функции завершается ошибкой ... возвращая 400 или что-то еще. Это тоже не идеально. Логически я чувствую, что хочу вернуть 200 для создания пользователя, затем 200 для создания токена электронной почты и 200 для успешной отправки электронной почты.

Буду признателен за любые рекомендации.

  const user = new User(req.body);

  user
    .save()
    .then(user => {
      const emailToken = new EmailToken({
        _userId: user._id,
        token: crypto.randomBytes(16).toString("hex")
      });

      emailToken
        .save()
        .then(token => {
          const transporter = nodemailer.createTransport({
            service: "Sendgrid",
            auth: {
              user: USERNAME,
              pass: PASSWORD
            }
          });

          const mailOptions = {
            from: "XXXXXX@gmail.com",
            to: user.email,
            subject: "Account Verification Token",
            text:
              "Hello,\n\n" +
              "Please verify your account by clicking the link: \nhttp://" +
              req.headers.host +
              "/verify/" +
              token.token +
              ".\n"
          };

          transporter.sendMail(mailOptions, (err, info) => {
            if (err) {
              return res.status(409).send({
                user,
                error: "Could not send verification email. " + err.message
              });
            }

            res.status(200).send({
              user,
              token: token.token,
              success:
                "A verification email has been sent to " + user.email + "."
            });
          });
        })
        .catch(error => {
          res.status(409).send({
            user,
            message: "Could not send verification email."
          });
        });
    })
    .catch(error => {
      if (error.name === "MongoError" && error.code === 11000) {
        return res.status(400).send({
          success: false,
          message: "Username or email already exists."
        });
      }
      res.status(400).send(error);
    });
});

1 Ответ

2 голосов
/ 27 января 2020

что на самом деле означает 200 здесь?

Это означает, что создание пользователя, генерация токена и отправка почты успешны.

Я чувствую это подход неверен. Ситуация может возникнуть при создании пользователя, но остальная часть функции завершается ошибкой.

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

Я чувствую, что хочу верните 200 для создания пользователя, затем 200 для создания токена электронной почты и 200 для успешной отправки электронной почты.

Вы можете отправить ответ только один раз, если это не поток.

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

const nodemailer_credentials = {
    service: "Sendgrid",
    auth: {
        user: USERNAME,
        pass: PASSWORD
    }
};


const user = new User(req.body);
let _token, _user;

user
    .save()
    .then(user => {
        _user = user;

        return new EmailToken({
            _userId: user._id,
            token: crypto.randomBytes(16).toString("hex")
        }).save();
    })
    .then(token => {
        _token = token;
        return nodemailer.createTransport(nodemailer_credentials);
    })
    .then(transporter => {
        return transporter.sendMail(mailOptions, (err, info) => {
            if (err) {
                const mailError = new Error('MailerError');
                      mailError.details = `Could not send verification email. ${err.message}`

                throw(mailError);
            }
            return;          
        });
    })
    .then(() => {
        res
            .status(200)
            .send({
                user: _user,
                token: _token.token,
                success: `A verification email has been sent to ${user.email}.`
            })
    })
    .catch(error => {
        if (error.message === 'MailerError') {
            return res.status(400).send({
                user: _user,
                message: error.details
            });
        }

        if (error.name === 'MongoError' && error.code === 11000) {
            return res.status(400).send({
                success: false,
                message: `Username or email already exists.`
            });
        }

        res.status(400).send(error);
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...