如何解决在基于组件的结构中为服务注入依赖
我遵循模块化或基于组件的结构。我找到了一个示例存储库。
https://github.com/sujeet-agrahari/node-express-clean-architecture
因此,有一个主要的component.module.js文件,它负责连接所有其他部分,例如控制器,路由和服务。
对于控制器,正在使用更高阶的函数注入服务。现在,控制器超级容易测试,我可以轻松地对服务进行存根或模拟。
auth.module.js
const router = require('express').Router();
const {
makeExpressCallback,makeValidatorCallback,} = require('../../middlewares');
// validator
const AuthValidator = require('./auth.validator');
// service
const { doRegister,doLogin,doCheckUserExist } = require('./auth.service');
const { BadRequestError } = require('../../utils/api-errors');
// controller
const controller = require('./auth.controller');
const register = controller.register({ BadRequestError,doCheckUserExist,doRegister });
const login = controller.login({ doCheckUserExist,doLogin });
const AuthController = { register,login };
// routes
const routes = require('./auth.routes')({
router,AuthController,AuthValidator,makeExpressCallback,});
module.exports = {
AuthController,AuthService: {
doCheckUserExist,doRegister,},AuthRoutes: routes,};
auth.controller.js
const login = (doCheckUserExist,doLogin) => async (httpRequest) => {
const { username,password } = httpRequest.body;
const userData = await doCheckUserExist({ username });
const loginData = {
username,role: userData.role_id,passedPassword: password,actualPassword: userData.password,};
const loginResult = await doLogin(loginData);
return {
statusCode: 200,body: {
success: true,message: 'Successfully logged in!',data: loginResult,};
};
const register = ({ BadRequestError,doRegister }) => async (httpRequest) => {
const { username,password } = httpRequest.body;
try {
await doCheckUserExist({ username });
} catch (error) {
// user doesn't exist
const registerResult = await doRegister({ username,password });
return {
statusCode: 200,body: {
success: true,message: 'Registered successfully!',data: registerResult,};
}
throw new BadRequestError('User already exist!');
};
module.exports = { register,login };
控制器一切正常,现在问题出在服务上。我找不到任何可以使它们薄而干净的图案。
auth.services.js
const {
JWT_ACCESS_TOKEN_SECRET,ACCESS_TOKEN_EXPIRES_IN,SIGN_OPTION,} = require('config');
const bcrypt = require('bcryptjs');
const { User } = require('../../db');
const { generateJWT } = require('./jwt.service');
const { NotFoundError,BadRequestError } = require('../../utils/api-errors');
const doRegister = async ({ username,password }) => {
const user = await User.create({
username,password,role_id: 1,// assign role id here
});
// generate access token
const payload = {
username,role: user.role_id,};
const token = await generateJWT({
secretKey: JWT_ACCESS_TOKEN_SECRET,payload,signOption: {
...SIGN_OPTION,expiresIn: ACCESS_TOKEN_EXPIRES_IN,});
return {
access_token: token,...payload,};
};
const doLogin = async ({
username,userRole,passedPassword,actualPassword,}) => {
const isValidPass = bcrypt.compareSync(passedPassword,actualPassword);
if (!isValidPass) throw new BadRequestError('Username or Password is invalid!');
// generate access token
const payload = {
username,role: userRole,};
};
const doCheckUserExist = async ({ username }) => {
const user = await User.findOne({
where: {
username,});
if (!user) throw new NotFoundError('User not found!');
return user;
};
module.exports = { doRegister,doCheckUserExist };
服务,模型导入,常量导入和其他实用程序正在发生很多事情。
现在,服务变得非常难以测试。
有什么方法或模式可以将某些逻辑与服务分离并使它们更轻巧吗?
我可以为db方法实现重新存储模式,但是我不知道如何使用sequelize来实现?
是否应该像我对控制器所做的那样使用更高阶的函数将所有utils和常量注入服务中?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。