How to inject a request (bypass HTTP protocol stack) in nodejs express? - express

Imagine this sample Express app straight from the documentation:
const express = require('express')
const app = express()
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(3000)
What is the idiomatic way to invoke the '/' endpoint programmatically from a different point in the same application code? Assume that I already removed the last line app.listen(3000).
The reason for this is that I want to take something like express-pouchdb and write an adapter for a different wire protocol, but leveraging the extensive routes already defined. I want to invoke these routes directly from js code without going over the network.
The application has dozens of routes already defined so changing each one to direct function calls as suggested in the first comment is not an option.
UPDATE:
I tried calling app.route.dispatch() but nothing comes back on the rsp object.

Your question is a duplicate of this answer: Is it possible to call Express Router directly from code with a "fake" request?
You can use run-middleware module exactly for that. You create an express app a usual, and then you can call the app using your parameters

Related

What exactly does the Express.js next() function do and where does is live in the express package?

I am learning node.js and express.js in pursuit of becoming a full-stack javascript developer. Currently, I am learning express.js and the idea of middleware.
As I understand it, middleware is basically functions that have access to modify the request and response within the req-res cycle. Is this correct?
However, I am a bit gray in the idea of the next() function. I understand that it is designed to call the next middleware function in the flow of middleware functions, however, where does it come from. Where can I find it in the express.js package.
When you have, more middlewares, they will run in order, and each middleware will pass the result to next middleware. imagine you have a route that can be accessed only by authenticated users.
router.get("/products", adminController.getProducts);
this says, whenever a user makes a request to /products, run the controller for this route. However, if you want to show this route, only to authenticated users, you will write a custom middleware, check that a user is autenticated, is user authenticated you will let the adminController.getProducts otherwise you will show an error message. So you will be placing the middleware between.
router.get("/products", isAuth, adminController.getProducts);
Note that you could pass more than one middleware. (adminController.getProducts is also a middleware but I mean besides isAuth you could place as many as you want)
isAuth will be something like this:
export const isAuth = (req, res, next) => {
if (!req.session.isLoggedIn) {
return res.redirect("/login");
}
next();
};
Imagine you setup a session based project. When user logs in, express-session (you will get familiar) will add session.isLoggedIn=true to the req obj. So before user attemps to react "/products", you will be checking if req.session.isLoggedIn is true. If yes you will let the next middleware to run, if not you will be redirecting the user to "/login" route.

What is the function signature of app.render, how is app.render used in the Next.js example files?

I have a Next.js app with an Express server in server.js (using custom server deployment.)
In the Next.js example server.js file, app.render(req, res, '/a', req.query); is used.
I understand that res.render uses app.render and that app.render is used for serving 'raw' content by means other than the HTTP protocol.
The Express docs detail that app.render takes the arguments:
app.render(view, [locals], callback)
So in the the Next.js example files, app.render(req, res, '/a', req.query);
req=view,
res=locals,
'/a'=locals,
req.query=callback
I'm struggling to make sense of the use of app.render here, and the arguments passed to it.
What are the arguments passed here, and how do they correlate with the documented express function signature?
As a supplementary question -
Next.js docs define this pattern as: This is obviously a non-standard routing strategy.
In what way is it non-standard, and why not use a standard routing pattern for example purposes?

Express JS Basic Routing Template

Can someone explain this to me clearly?
const express = require("express");
const app = express();
I get the first line of code, but don't get the concept of initializing a variable "app" as express()? When we import express, we also have access to express()?
What does it do theoretically? What does that () of express() do?
Do we always have to do it like that?
Thank you.
If you are familiar with object-oriented programming, then the way to think of this is by creating an instance.
When you import express, you are importing the class. However, your server is an instance of that class. So, when you call
const app = express();
you are spinning up your server. You now have the encoding of a server you can interact with from app, whereas the original import just refers to the same class (i.e. like a template) for what that server is. The function express() is merely initializing a new server object for you.
Technically, you could have multiple 'servers' running:
const app1 = express();
const app2 = express();
You would want these to be independent of each other, which is why you don't just use the top-level import.
According to the documentation
The express() function is a top-level function exported by the express module
The function returns a app object which is essentially an Express application.
The app object has methods for
Routing HTTP requests; see for example, app.METHOD and app.param.
Configuring middleware
Rendering HTML views; see
Registering a template engine; see app.engine.

difference between app.use('/users', usersRouter); and require(./routes/users)(app)?

In the express tutorial from mozilla,
https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/skeleton_website
they write
var usersRouter = require('./routes/users');
app.use('/users', usersRouter);
In other tutorials, they write something like this,
require('./routes/authRoutes')(app);
Are the two pretty much equivalent?
Without seeing the code for the other tutorials that you mentioned I cannot be sure exactly how they consume the app object that is passed to the imported code, but I suspect that whatever code is implemented in the .routes/authRoutes module simply connects a router object to the specified app object. This would most likely be done in the same way as the code that you provided from the Mozilla Express tutorial.
In both cases, a route handler is being defined and then registered as a handler for any routes that match the specified route. In the case that you mentioned that route would be the /users route. So the usersRouter object would have a number of route handlers defined, for example, for routes /abc and /def. So registering the usersRouter object as a route handler for the /users route would mean that the routes /users/abc and /users/def would be handled.

Can I use multiparty for a single route in my express app?

I have an Express 3 app that uses bodyParser for most routes. (Most routes only accept multipart.) I have a single route that is going to be parsing files up to 1GB in size which bodyParser can't seem to handle. I would like to use multiparty for only this route so I don't have to rewrite the whole API. Is this possible?
You can supply middleware to a single route by doing this:
var multipartyMiddleware = function (req,res,next){
//put your code to parse multipart here and call "next" when done
}
app.post('/this/is/a/single/route', multipartyMiddleware, function(req,res){
//do normal business logic in this route and send the response
})
If you need to bypass the multipart parsing in the old bodyParser in express 3 you can replace this:
app.use(express.bodyParser())
with this:
app.use(express.json())
app.use(express.urlencoded())
This works because the source of the bodyParser middleware reveals that it is just a combo of three middleware parsers: multipart, json, and urlencoded.
see the connect 2.X source here: https://github.com/senchalabs/connect/blob/2.x/lib/middleware/bodyParser.js#L54