Express中/api返回JSON经另一路由调用hbs渲染是否正确
产品接口+模板渲染实现方案校验
现有接口实现
当前已完成/api/product接口开发,功能为返回JSON格式的产品列表数据:
- 路由注册配置:
router.get('/', this.controlador.renderProducts); - 路由处理逻辑代码:
renderProducts = async (req, res) => { try { const docs = await this.ProductsDAO.mostrarTodos(); const productos = docs.map((p) => { return new ProductDTO( p.id, p.precio, p.stock ); }); res.status(200).json({ product:productos }); } catch (error) { logger.error('Error al renderizar productos', error); res.status(400).send('Status: No se ha renderizar productos'); } };
拟新增的模板路由实现
计划在server.js中新增/product路由,调用上述接口获取数据后通过hbs引擎渲染页面,拟编写的代码如下:
- 路由注册配置:
app.get('/product', new RequestViews().getProductAll) - 路由处理类代码:
class RequestViews { constructor() { this.url = 'http://localhost:8080/api/product'; } getProductAll = (req, res, next) => { request.get(this.url, (err, response, body) => { if (err) { return next(err); } res.render('products', JSON.parse(body)); }); } }
实现方案评估
该写法可以实现预期功能,但存在明显缺陷,不推荐在生产环境使用,具体问题如下:
- 存在冗余性能损耗:两个路由同属一个服务,不需要通过本地HTTP请求自调用接口,直接复用已有的DAO查询、DTO转换逻辑即可,自调用会额外增加一层网络开销,拉长响应时间,在多实例、容器部署场景下还可能出现本地地址访问失败的问题。
- 错误处理逻辑缺失:当前代码仅处理了HTTP请求报错的场景,没有校验接口返回的状态码,也没有捕获
JSON.parse的解析异常——如果接口返回400/500错误,响应体不是合法JSON格式时,会直接抛出未捕获异常导致服务报错。 - 配置硬编码灵活性差:代码中写死了接口地址
http://localhost:8080,后续服务更换端口、部署到测试/生产环境、加路由前缀时都需要手动修改代码,维护成本高。
优化建议
- 优先选择直接复用内部逻辑的实现方式,完全避免HTTP自调用,示例代码如下:
getProductAll = async (req, res, next) => { try { const docs = await this.ProductsDAO.mostrarTodos(); const productos = docs.map((p) => new ProductDTO(p.id, p.precio, p.stock)); res.render('products', { product: productos }); } catch (error) { next(error); } }
- 如果因架构原因必须通过HTTP调用接口,需要补全错误处理逻辑,示例代码如下:
getProductAll = (req, res, next) => { request.get(this.url, (err, response, body) => { if (err) return next(err); if (response.statusCode !== 200) return next(new Error('产品接口请求失败')); try { const renderData = JSON.parse(body); res.render('products', renderData); } catch (parseError) { next(parseError); } }); }
内容的提问来源于stack exchange,提问作者Jennifer
相关产品推荐
相关产品推荐

