sna*_*nda 1 javascript node.js
所以这是我当前的代码:
/**
* User Registration
* Sends a response object with success true if user was registered.
* Sends a response object with success false if user couldn't be registered.
*/
router.post('/', function(req, res, next) {
var userInfo = req.body;
userInfo.email = sanitize(userInfo.email);
userInfo.password = sanitize(userInfo.password);
if(!validEmail(userInfo.email) || !validPassword(userInfo.password)) { //If the request info is invalid
sendJsonResponse(res, false, error, 400);
}
else {
//Check if e-mail already exists
User.find({email: userInfo.email}, function(err, docs) {
if(err) {
console.log(err);
sendJsonResponse(res, false, "There was an error processing your request.", 400);
}
else if(docs.length > 0) { //If e-mail was found in database, generate error
sendJsonResponse(res, false, "This e-mail already exists, please login or use another e-mail.", 409);
}
else {
//Create user based on data submitted.
var user = new User({email: sanitize(userInfo.email), password: bcrypt.hashSync(sanitize(userInfo.password), 10), permission_level: 'REGULAR'});
//Save it in the database.
user.save(function (err) {
if (err) {
sendJsonResponse(res, false, "There was an error processing your request.", 400);
}
else { //If everything is fine
//Create token to login the registered user
var token = jwt.sign(user, config.secret, {
expiresIn: '24h' // expires in 24 hours
});
sendJsonResponse(res, true, "You have been registered!", 200, token);
}
});
}
});
}
error = "";
});
Run Code Online (Sandbox Code Playgroud)
此代码用于用户注册。我正在使用我编写的函数 (validEmail/validPassord) 来验证发送到我的 REST API 的电子邮件和密码。
还有 sendJsonResponse,它发送带有特定错误和错误代码的响应。
我觉得我做的还不错,但我仍然觉得这里还有改进的空间。我特别不喜欢所有的 if/else。我可以在这里做些什么来提高最佳实践/代码质量?
如果我们只查看您的代码,那就没问题了(逻辑、错误处理、格式化响应的函数......)。但是看看你的代码,我假设你正在使用Express微框架来创建你的后端服务(API?),所以你的 API 设计和你使用 Express 的方式有一些需要改进的地方......
对您的数据库的一个请求可能会导致不同的错误(重复键、某些约束、错误值......)并提供不同的看法。所以最好创建模块来处理与数据库的交互,这样错误处理会更清晰,代码更可重用。
例子 :
创建一个模块userModel将包含多种方法来处理数据库中的用户。
考虑getBy允许您通过“键” ( getBy({name: 'Doe', age: 25}))过滤用户的方法。
这个方法可以被不同的路由使用并返回不同类型的错误,所以最好将它写在模块内部。
它将减少代码重复,使代码更具可读性并帮助您改进错误处理。
我看到您正在使用 Express 路由器 ( router.post('/', ... ))。
由于您正在设计 REST API,因此您的方法 GET、POST、PUT 和 DELETE 将共享相同的路由名称。
Express 路由器允许您使用以下语法执行此操作:
router.route('/routeName')
.get(...)
.post(...)
.put(...)
.delete(...);
Run Code Online (Sandbox Code Playgroud)
这不是什么大事,但它使代码更好,并迫使您尊重 REST 架构约束。
我看到您正在使用函数对请求正文进行验证并格式化您的响应。这通常由中间件管理。
中间件是 Express(带路由器)最重要的特性之一。它们是具有以下“签名”的函数:function(req, res, next){}可以链接。
每个中间件可以:
req参数)res参数(例如:res.status(200).json({created: true}))next()因此,中间件允许您使用一个简单的函数列表来构建程序的逻辑,这些函数将一个接一个地被调用。
例子 :
[check req.body](1) --> [write user in the DB](2) --> [format response](3)
Run Code Online (Sandbox Code Playgroud)
中间件真是太棒了,会让你写出更好、更简洁、设计良好的 API :)
我们都讨厌回调地狱,这是事实,这就是为什么我们通常使用诸如Promise. 但即使是 Promises 有时也会很痛苦,所以我们async/await让事情变得更简单:
它允许您像编写同步代码一样编写异步代码!
|___models/
| |___users.js
|
|___controllers/
| |___users.js
|
|___routes/
| |___register.js
|
|___middlewares/
|___validation.js
Run Code Online (Sandbox Code Playgroud)
// models/users.js
import db from 'dbModule';
const save = async (userObj) => {
const testUserMail = await db.users.find({email: userObj.email});
if (testUserMail.length > 0)
return {success: false, err: "The email already exists"};
await db.users.save(userObj);
const savedUser = await db.users.findById(userObj.id);
return {success: true, user: savedUser};
}
exports default {save};
Run Code Online (Sandbox Code Playgroud)
// controllers/users.js
import userModel from '../models/users';
const register = (req, res, next) => {
console.log(req.example); // "hey I'm here"
const dbReq = await userModel.save(req.body);
if (dbReq.err && !dbReq.success)
return res.status(400).json({success: false, data: dbReq, message: "failed !"})
const registeredUser = dbReq.user;
res.json({success: true, data: {user: registeredUser}, message: "User is registered !");
}
export default {register};
Run Code Online (Sandbox Code Playgroud)
// middlewares/validation.js
const checkUser = (req, res, next) => {
req.example = "hey I'm here";
if (isOk(req.body.email) && isOk(req.body.password))
return next();
else
return res.status(400).json({success: false, data: null, message: "failed: bad request body"}))
}
export default {checkUser};
Run Code Online (Sandbox Code Playgroud)
// routes/register.js
import express from 'express';
import validation from '../middlewares/validation';
import userCtrl from '../controllers';
const router = express.Router();
router.route('/')
.post(validation.checkUser, userCtrl.register)
Run Code Online (Sandbox Code Playgroud)
快速和最后(我发誓)的解释:
userCtrl.register)。req与先前的中间件进行修改(这里,我们添加的example关键是我们的req对象)。awaiting for) 一个async函数将用户保存在数据库中--> 避免回调地狱如果你喜欢上面的 API 架构/设计,你可以看看!
希望它有所帮助,阅读时间不会太长,
最好的问候,
| 归档时间: |
|
| 查看次数: |
2594 次 |
| 最近记录: |