问题
I have several "api" endpoints in my application that are used by the front-end framework for its AJAX processes. For organizational purposes, I would like to re-use the code for these endpoints to retrieve data for server-side rendering, which I do in some instances to play nicely with search engines. So, ideally I would implement some sort of HMVC setup to simply access a route on the API endpoint. Specifically I would like to get the response and perform additional actions on it before issuing the top-level response (e.g., render a view with results).
For example:
app.get('/post/recent', function(req, res) {
app.doRequest('/api/posts/', req, function(res2) {
var data = res2.body;
res.render('posts/index', data);
});
});
What's the best way to do this?
So far the best option I've come up with is:
Expose all logic in an endpoint as a method, which would be used in app.get('...', myFunction)
, and then I could call myFunction
elsewhere outside of the express flow for that path. However, this would not give me a reliable way to run middleware specific to the endpoint (which I would also want to run on the HMVC request) unless I wrote my own middleware implementation that did not rely on express. The API endpoint has middleware that does something like if(!hasAccess) res.send(403)
, which I specifically do NOT want to happen in my main route since I'd want to render a nice error page instead of just sending an error code.
Example:
var getPosts = function(req) {
var deferred = q.defer()
doDatabaseQuery(req.query).then(function(response) {
deferred.resolve(response)
});
};
app.get('/api/posts', myMiddlewareFunction(), function(req, res) {
getPosts(req).then(function(response) {
res.send(response);
});
);
app.get('/post/recent', function(req, res) {
// I want to run middleware here, not in root level
getPosts(req).then(function(response) {
res.render('post/index', response);
}, function(err) {
res.render('error/noaccess');
});
});
Any better ideas? Is there a way to programmatically access an express route and get the result?
回答1:
I figured this out by diving into the Express source code. There is a method called handle
which I can manually invoke with modified request
and response
objects to get the effect I want:
app.get '/posts', (req, res) ->
req.url = '/api/posts'
newRes = _.clone(res)
newRes.send = (data, code)->
if code is 200
return res.render('posts/index', data)
else
return res.render('error')
app.handle(req, newRes)
来源:https://stackoverflow.com/questions/22723575/how-to-implement-hmvc-structure-in-node-express