// Для начала разбиваем код на отдельные обработчики и храним все раздельно
// например в signup.ts
import { ERR_USER_EXISTS, ERR_USER_CREATION_FAILED } from './utils/error-codes.ts'
import { planAction, USER_CREATED } from './event-bus/rabbit.ts'
import { validateSignUpData } from './validator/signup.ts'
import { userModel } from './model/user.ts'
// собственно обработчик
export const signup = async (req, res) => {
const { body } = req // намного удобнее использовать destructuring
const { email, password } = body // и const позволяет контролировать неизменность
try {
validateSignUpData({email, password}) // зависит от бизнес-логики
const isUserExists = await userModel.isUserExists(email)
if (isUserExists) {
res.status = 400
res.json({
message: 'User exists',
code: ERR_USER_EXISTS // вместо написания сообщений об ошибках
// принято возвращать код ошибки
// это позволяет адаптивную локализацию на фронте
// этот код ошибки отличается от HTTP Status Code
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
})
return
}
// попытаемся создать пользователя
const userInfo = await userModel.createUser({email, password})
if (!userInfo) {
// в зависимости от того, как реализован createUser, он может выбрасывать исключение
// либо возвращать пустоту
res.status = 400
res.json({
message: 'User creation failed',
code: ERR_USER_CREATION_FAILED
})
return
}
// запланируем отсылку события, обычно этот код должен быть реализован асинхронным
// и не блокировать основной поток событий
planAction({
event: USER_CREATED,
playload: userInfo
})
// отправим успешный ответ на фронт
res.status = 200
res.json(userInfo)
} catch (e) {
// любая ошибка, где бы она не возникла, должна быть обработана
// в целом обычно применяется более сложная система с набором специфичных исключений
// и общим обработчиком ошибок
res.status = 501
res.json({
message: e.message,
code: e.code || 0
})
}
}
// далее в app.ts
// затем мы просто привязываем их
import { signup } from './signup.ts'
app.post('signup', signup)