Is middleware a NodeJS or ExpressJS (or similar) concept? - node.js

I keep seeing questions to explain the middleware concept in NodeJS, and it always seems to me that they're poorly formulated. Do people always mean ExpressJS middleware, or there is a practice to use this concept in pure NodeJS?
I checked different abstract explanations here and here among others, and I definitely understand, that the concept exists beyond either NodeJS and Express. I'm rather curious if NodeJS middleware is always understood as the one implemented by Express or another library, or NodeJS in itself has the concept built-in.

No, middleware doesn't exist in pure Node.js (at least at the way we're used to seeing them), this concept came to Node.js with Express.js. But nobody forbids you to write your own implementation in Node.js, you need to start with the next function, which is responsible for all middleware. The point of this function is that it should be called at the very end and either terminate the process or pass objects req/res to the next middlewares. The implementation can be seen here.

The middleware mentioned in your references isn't the same category as nodejs / express middleware.
In express, middleware is the name (a bombastic name in my opinion) for Javascript functions with this signature.
function mWare (req, res, next) {
/* do something useful with req and res */
next()
}
These express middleware functions are invoked, by the express framework, typically before the .get() or other function handling each specific request. This concept of middleware comes from the express framework, not from nodejs itself.
Other web frameworks built on nodejs have other ways of intercepting requests. For example, hapi uses server extension points.
The middleware mentioned in your references is not the same thing at all. It is made of larger components. Queuing, load balancing, database access, logging and caching systems are all examples of that kind of middleware. You could make the case that your entire express / nodejs / Linux server is middleware by that definition. An nginx reverse-proxy server sitting between your nodejs program and the network is definitely that sort of middleware.

Related

What is the benefit of using Express with GraphQL instead of simply using Node.js with GraphtQL?

What are the benefits of using Express with GraphQL? All the advantages of GraphQL can also be used with a simple Node.js application without Express. As GraphQL has only one endpoint and no middleware concept like in case of Express, why would we want to use Express and not just Node.js?
Express uses the Node.js http module under the hood but through middleware provides a way for you to implement various features for your endpoint. For example, to process POST requests (which you would need to do for GraphQL), you would need to parse the request body into a usable format -- if you don't utilize Express and a middleware like body-parser, you'd have to do this by hand. The same goes for other common functionality you're likely to need, like CORS, session management, etc. -- why reinvent the wheel when there's a middleware for it?
GraphQL itself might not have a concept of middleware (although there is a library that effectively does just that), Express's middleware still applies to your GraphQL endpoint as a whole. That means you can set up middleware that is ran before the GraphQL endpoint. Outside of features already described above, this also allots you the opportunity to implement authorization logic for your endpoint. For example, you could prevent access to the entire endpoint to users that fail to provide an appropriate custom header.
In reality, your app may need more than just your GraphQL endpoint. Authentication is commonly handled outside of GraphQL by exposing one or more additional endpoints -- this is particularly true if you implement an OAuth flow for your app. Likewise you may interface with third-party services that utilize webhooks, which would require you to expose additional endpoints on your server specifically for that purpose. The same often goes for health checks, like those used by load balancers.

Recommended way for using Express.js with React.js?

I have found two ways to combine React and Express:
[OPTION 1] ExpressJS serve React static files
Fundamentally, the idea here is to have pre-compiled JavaScript files at your disposal before spinning up the server. And then in Express middleware:
app.use(express.static(path.join(__dirname, '../client/build')));
And then in tandem have other endpoints that execute logic on server-side.
[OPTION 2] Host React files separately
Basically, decouple the logic in entirety of Frontend and Backend with one server just for serving static JS files. And then another Express server for running any queries against the database. And returning simple JSON responses.
Which one is the recommended way? Is there an advantage of using one approach over the other?
This is an opinionated question, and so I can only give an opinionated response.
I personally recommend OPTION 1 because you'll run into Cross-Origin-Resource-Sharing (CORS) issues in a number of places when you decouple your front and back ends. This isn't to say that it can't be done, but it will be an annoying thing you'll have to deal with.
With option 2 you'll also most likely have to be sending any requests to your back end with absolute URL paths, which can be very tough to maintain when an application scales.
With option 1 you'll have more flexibility, less to maintain, and less annoying workarounds to implement.

What (in layman's terms) is Authentication Middleware?

Getting started with server-side and especially Node.js. Stumbled upon this authentications framework called Passport.js, built specifically for Node. Would someone take the liberty to explain this Authentication Middleware thing to me? In layman's terms, if possible. Thanks ;)
Authentication Middleware is any number of authentication-related functions that are executed prior to passing the request to its final route. For example, any routes requiring the user to be logged in would run Authentication Middleware before serving the resource.

Express.js middleware integration testing

I am writing some middleware for express.js 2.5.8. The intention is to amend the request object with additional attributes based on the session. I have unit tested the middleware function. Now, I would like to perform some lower-level integration testing to confirm that the middleware is being used by the express server.
My typical approach to this would be to spy on the middleware function. However, this is not the most effective way of proving that the middleware is working as intended.
What I would like to do (if possible/feasible) is load the application, inject arbitrary session data (it does not need to be valid), request/visit a test route which sends the result of the middleware. From there, I can make assertions on that result.
I have been using supertest (superagent), zombie, and request for testing, each with varying degrees of success. What I am struggling with currently is the injection of session data into the request, in whichever form it will end up taking.
I would appreciate some guidance. What approaches have people used when testing this type of behavior?
By making the assumption that express middleware handling is not broken: Why don't you try to write an injection middleware that is responsible to inject the desired session data and place the injection middleware before your middleware function you want to test?
With this approach you don't test client code directly but isolate the injection in your injection middleware.

Restrict Express session middleware to certain routes

I'm using Express to build a web site. I'm serving static files and have a REST API. For the static files I'm using the session middleware to restrict certain pages to logged in users. The downside to this is that the REST API has cookies in the HTTP header. Can I restrict certain routes to not use cookies? Is this what the mount function is for?
Well, if you're setting or requiring cookies, you must be using some sort of middleware function to do so (since there's nothing in Express per se that would do it). If you wrote the middleware function yourself, you just need to rewrite it to be a little more picky about when to set/require cookies. If you're using a pre-written middleware function, try putting it later in the stack than any route functions that shouldn't be requiring cookies (this will generally mean putting app.use(express.router); ahead of any app.use(...) call that invokes a cookie-dependent middleware function).
If this doesn't make sense to you, please post what you're doing (after stripping it down to a minimal test case).

Resources