我正在开发一个网络服务器,目前正在为网络浏览器而非移动应用程序开发。
但是将来我们可能还需要为移动应用程序扩展它,所以我想在为它开发路线时更加小心。
现在我的结构看起来像这样
const controller = require('../../Controllers');
const libs = require('../../Lib');
/* GET users listing. */
router.get('/', libs.util.isLoggedIn, libs.util.checkPermission('/user-dashboard', 'view'), (req, res, next) => {
controller.UserController.getDashboardDetail(req, res, (error, result) => {
if (error) {
next(error);
return;
}
result.session = req.session;
res.render('consume/user-dashboard', {
coursearray: result,
username: req.session.displayname
});
})
});
在此路线'/'
中,我正在请求用户信息中心,因此在提供此信息之前,我使用middlewares
登录使用libs.util.isLoggedIn
功能验证用户,使用libs.util.checkPermission
的权限,然后我的controllers
提供所需的数据。
我们可以在获取无错误数据后使用View
呈现res.render
。
我的问题是,当我只需要向API
提供给某些移动应用程序的数据时,我如何才能使用相同的render
?
我不想为了做同样的事情而建立另一个API
。
我的API
不应关心是否在server
方或client
方建立了网页。
我应该如何修改我当前的API
来实现这一目标?
我使用routes
的结构是否存在错误?
答案 0 :(得分:0)
您可以选择使用两种方法,我个人建议采用方法二,以便更好地分离关注点,并在未来提高灵活性。虽然在理解了这两种方法之后,如果它是一个较小的应用程序而不太可能改变,那么你可能会认为这种方法更适合你的需求。
方法1 - 接受标题。
常见的惯例是检查->draw2DImage(image,
irr::core::position2d<irr::s32>(145,30),
irr::core::rect<irr::s32>(0,0,500,180),
0,
irr::video::SColor (255,255,255,255),
true);
标题(或类似标题)以查看它请求的格式。如果客户端要求HTML,那么您可以使用res.render响应(例如Web浏览器)进行响应,如果他们请求JSON或XML,那么您可以根据需要使用这些格式进行响应。您应该能够将其打包为路由的中间件,并在路由定义中传递模板名称,例如,如果使用JSON进行响应,则可以忽略该模板名称。
See HTTP docs for more information on the Accepted header.
方法2 - 统一业务逻辑,包含两个精简应用程序
另一种选择(大多数人都喜欢)是在某种“lib”模块中构建业务逻辑。然后构建两个瘦Web应用程序,一个用于提供HTML,另一个可能位于仅提供JSON的Accepted
端点上。
因此,如果用户请求/api
,他们将获得HTML页面。如果他们请求example.com/profile
,那么他们将获得JSON回复。这两个端点都向您的项目example.com/api/profile
文件夹中的user
资源发出请求,但是然后将其格式化为HTML格式,另一个格式化为JSON格式。这通常是理想的方法,因为HTML页面通常从多个资源中提取以构建页面。例如,此stackoverflow页面将显示一些用户配置文件方面,问题本身,答案,“热网络问题”和“相关问题”。如果您刚刚请求了JSON表示,那么您希望只得到问题和后续答案。