背景
最近正在看cnode-egg的源码,碰到问题就直接拿cnode的api来测试了,但是根据测试结果,感觉线上运行的代码和cnode-egg行为的不一致。
cnode 代码重构的说明在此
get /topics 主题列表
预测结果
根据源码的行为预测,如果 querystring 的 limit 或者 page 传入的是非数字的话,应该会被转成 NaN,然后直接传给模型层的 skip 和 limit,然后出错。
源码如下:
// app/middleware/pagination.js
module.exports = () => {
return async (ctx, next) => {
if (!ctx.pagination) {
const query = ctx.query;
const config = ctx.app.config;
const pagination = {};
// 这里限制了最大 limit,不知道实际上需不需要
pagination.limit = Math.min(100, parseInt(query.limit || config.default_limit, 10)); // 每页数量取最小
const page = Math.max(1, parseInt(query.page || config.default_page, 10)); // 页码取最大
pagination.skip = (page - 1) * pagination.limit; // 转换成偏移量
ctx.pagination = pagination;
}
await next();
};
};
实际结果
实际上如果传入的都是字符的话,也不会报错,会按照默认的数量和页码返回主题列表,页码是默认数字 1,但是每页显示的数量不是默认的 20,而是 40;
get /user/:loginname 用户详情
预测结果
查询用户详情的时候,根据代码显示,会一并返回用户发布的所有主题,并且没有用户发布的回复贴;
源码如下:
async show() {
const { ctx } = this;
const loginname = ctx.params.loginname;
const user = await ctx.service.user.getUserByLoginName(loginname); // 获取用户
if (!user) { // 判断用户是否为空
ctx.status = 404;
ctx.body = { success: false, error_msg: '用户不存在' };
return;
}
const userId = user._id;
const topics = await ctx.service.topic.getTopicsByQuery({ author_id: userId }); // 获取话题列表, @todo 取多少个?
const returnUser = _.pick(user, [ 'loginname', 'avatar_url', 'githubUsername', 'create_at', 'score' ]); // 筛选用户返回属性
const returnTopics = topics.map(topic => { // 筛选话题返回属性
return {
id: topic._id,
last_reply_at: topic.last_reply_at,
title: topic.title,
author: {
loginname: user.loginname,
avatar_url: user.avatar_url,
},
};
});
const data = returnUser;
data.recent_topics = returnTopics;
ctx.body = {
success: true,
data,
};
}
实际结果
因为发的帖子比较少,不知道一并返回的最近发布的主题贴会不会被限制数量,但是发现了响应体中还包含了 recent_replies
属性,表示用户发布的回复贴,但是源码中缺没有相关的逻辑;
{
"success": true,
"data": {
"loginname": "mehunk",
"avatar_url": "https://avatars2.githubusercontent.com/u/10388497?v=4&s=120",
"githubUsername": "mehunk",
"create_at": "2015-10-10T09:14:19.927Z",
"score": 80,
"recent_topics": [
{
"id": "58759b172d086de6340db33f",
"author": {
"loginname": "mehunk",
"avatar_url": "https://avatars2.githubusercontent.com/u/10388497?v=4&s=120"
},
"title": "如何提升mongodb中group的效率",
"last_reply_at": "2017-01-12T01:55:05.696Z"
},
{
"id": "567fa3d7435249f221f53ac9",
"author": {
"loginname": "mehunk",
"avatar_url": "https://avatars2.githubusercontent.com/u/10388497?v=4&s=120"
},
"title": "静态资源路径设置问题(已解决)",
"last_reply_at": "2015-12-27T15:05:31.901Z"
}
],
"recent_replies": [
{
"id": "5b769226944cb8340c27e161",
"author": {
"loginname": "littledu",
"avatar_url": "https://avatars2.githubusercontent.com/u/1784673?v=4&s=120"
},
"title": "egg.js 中 validate 的最佳实践",
"last_reply_at": "2018-08-25T01:16:04.369Z"
},
{
"id": "58759b172d086de6340db33f",
"author": {
"loginname": "mehunk",
"avatar_url": "https://avatars2.githubusercontent.com/u/10388497?v=4&s=120"
},
"title": "如何提升mongodb中group的效率",
"last_reply_at": "2017-01-12T01:55:05.696Z"
},
{
"id": "5800a897487e1e4578afb50b",
"author": {
"loginname": "xcatliu",
"avatar_url": "https://avatars0.githubusercontent.com/u/5453359?v=4&s=120"
},
"title": "「Yarn 中文文档」 一起来翻译吧",
"last_reply_at": "2016-10-14T15:39:42.162Z"
},
{
"id": "562adf63004756b058c237b1",
"author": {
"loginname": "welchwsy",
"avatar_url": "https://avatars3.githubusercontent.com/u/11153910?v=4&s=120"
},
"title": "短信验证模块",
"last_reply_at": "2017-06-15T03:26:00.362Z"
},
{
"id": "57e8dca7a61dacb35502be75",
"author": {
"loginname": "Samurais",
"avatar_url": "https://avatars1.githubusercontent.com/u/3538629?v=3&s=120"
},
"title": "NodeParty@北京 #16期总结",
"last_reply_at": "2016-10-12T01:35:48.147Z"
}
]
}
}
点击底部的 【源码地址】和 egg-cnode 的 html : https://github.com/cnodejs/egg-cnode/blob/master/app/view/layout.html#L130 不一样
@zhuweiyou 是这样的,但是这个帖子里面说现在线上运行的已经替换成了egg-cnode。 https://cnodejs.org/topic/5aae1cc8f5dfc27d7ad98909
https://egg.cnodejs.org/ 线上地址是这个吧
@mehunk 这个帖子我看过。有可能当前运行的是比较早 commit 版本,目前 master 并未发到线上。
刚和朴大确认了一下,因为github-passport的原因,切回原版了。