[英]Node/Express - use API JSON response to (server-side) render the app
Preamble: I'm new to web dev so maybe this might be a very basic question for you vets. 序言:我是网络开发人员的新手,所以这对你们来说可能是一个非常基本的问题。
I'm using MVC architecture pattern for this basic app. 我正在为这个基本应用程序使用MVC架构模式。 I've models (MongoDB), views (Express Handlebars), and controllers (functions that take in req, res, next and returns promises (.then > JSON is returned, .catch > error is returned). I'll be routing the paths reqs to their corresponding api endpoints in the controllers.
我有模型(MongoDB),视图(Express Handlebars)和控制器(接受req,res,next和返回promises的函数(.then>返回JSON,返回.catch>错误。)我将路由路径需要控制器中对应的api端点。
This makes sense (right?) when I'm purely working on API calls where JSON is the res. 当我纯粹处理JSON是res的API调用时,这是有意义的(对吧?)。 However, I also want to call these api endpoints > get their res.json > and use that to render my HTML using Handlebars.
但是,我也想调用这些api端点>获取他们的res.json>并使用它来使用Handlebars呈现我的HTML。 What is the best way to accomplish this?
完成此任务的最佳方法是什么? I can create same controllers and instead of resp being JSON, I can do render ("html view", res.json).
我可以创建相同的控制器,而不是resp是JSON,我可以做渲染(“html视图”,res.json)。 But that seems like I'm repeating same code again just to change what to do with the response (return JSON or Render the JSON).
但这似乎是我再次重复相同的代码只是为了改变如何处理响应(返回JSON或渲染JSON)。
Hope I'm making sense, if not, do let me know. 希望我有意义,如果没有,请告诉我。 Please advise.
请指教。
ps try to ELI5 things for me. ps为我尝试ELI5的东西。 (:
(:
Edit: 编辑:
//Model Example
const Schema = require('mongoose').Schema;
const testSchema = new Schema({
testText: { type: String, required: true },
});
const Test = mongoose.model('Test', testSchema);
module.exports = Test;
//Controller Example
const model = require('../models');
module.exports = {
getAll: function(req, res, next) {
model.Test.find(req.query)
.then((testItems) => {
!testItems.length
? res.status(404).json({ message: 'No Test Item Found' })
: res.status(200).json(testItems);
})
.catch((err) => next(err));
},
};
//Route Example
const router = require('express').Router(),
controller = require('../controllers');
router.get('/', controller.getAll);
module.exports = router;
I want the endpoints to return JSON and somehow manage whether to render (if the req comes from a browser) or stay with JSON (if called from Postman or an API web URL for example) without repeating the code. 我希望端点返回JSON并以某种方式管理是否渲染(如果req来自浏览器)或保留JSON(如果从Postman或API Web URL调用),而不重复代码。 I'm trying to not create two endpoitns with 99% of the code being the same, the only difference being .then > res.status(200).json(testItems);
我试图不创建两个endpoitns,99%的代码是相同的,唯一的区别是.then> res.status(200).json(testItems); vs .then > res.status(200).render('testPage', { testItems}).
vs .then> res.status(200).render('testPage',{testItems})。
对于邮递员,您可以在req.headers
检查req.headers
postman-token
的存在,然后您可以相应地进行渲染,如下所示:
req.headers['postman-token'] ? res.json({ /* json */ }) : render('view', {/ * json */});
If you want to go with checking postman token
then you can use similar to method1
. 如果你想
checking postman token
那么你可以使用类似于method1
。
if you want to check with query params in this case you can get json
response or html even from browser for future use also and is not dependent on postman then use similar to method2
of the following example. 如果您想在这种情况下查询查询参数,您甚至可以从浏览器获取
json
响应或html以供将来使用,并且不依赖于postman然后使用类似于以下示例的method2
。
const express = require('express')
const bodyParser = require('body-parser')
const app = express()
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
const port = 5000
app.get('/method1', (req, res) => {
const isJSONResp = req.headers['postman-token']
const resp = { status: "hello" }
if (isJSONResp) {
res.json(resp)
} else {
res.render('some.html', resp)
}
})
app.get('/method2', (req, res) => {
const params = req.params
const resp = { status: "hello" }
if (params.resp === 'json') {
res.json(resp)
} else {
res.render('some.html', resp)
}
})
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.