Make request data available from different places - node.js

We are building a middleware with apollo-server, express, and nodejs.
There is some info in the HTTP request headers that we’ll like to be available from different places down the call stack without the need to be passing them as parameters or touching each resolver, some kind of java thread-local.
We have a solution using async_hooks, but in some cases, it doesn’t work, we tried AsyncLocalStorage with no success, so we are looking for alternatives.
Apollo → Express Middleware → Apollo Context -> Resolvers → Other Code ...→ A REST call needing the header in original HTTP request
We have a working solution with the context, we were looking for a more global solution using middleware

Related

Express Js Router methods

I am new to expressjs and nodejs .I have found few methods in express router using visual studio code vs intellisense .For few of them i didn't found any documentation regarding below methods ,how exactly it can be used in real world like get,post,put,patch .So i thought to ask in stackoverflow.It might help everyone who are looking similar to this
const router = express.Router()
router.options
router.head
router.checkout
router.connect
router.copy
router.lock
router.merge
router.mkactivity
router.mkcol
router.move
router.'m-search'
router.notify
router.propfind
router.proppatch
router.purge
router.report
router.search
router.subscribe
router.trace
router.unlock
router.unsubscribe
router.apply
router.bind
router.arguments
router.caller
router.call
Please see: https://expressjs.com/en/api.html#routing-methods
Express Routing methods
Express supports the following routing methods corresponding to the HTTP methods of the same names:
checkout copy delete get head lock merge mkactivity mkcol move m-search notify options patch post purge put report search subscribe trace unlock unsubscribe
The API documentation has explicit entries only for the most popular HTTP methods app.get(), app.post(), app.put(), and app.delete(). However, the other methods listed above work in exactly the same way.

Call NodeJS function from client-side

I have NodeJS on / path.
On /another.ejs path, I have a little website and I wanna get data from /value path.
I cannot do this call with pure JS and AJAX, because of CORS.
Can I do something like when I click on button, it calls function in NodeJS and return data?
I don't know why CORS is going on in same domain name, but you can try some other ways to get result from routes.
Using proxy to throw result between server and client.
You can use proxy things.
Means creating middle hand (link to another stackoverflow answer)
Also look: PHP: no.php
CORS Module
Also see above comment by codeherk.

expressjs repo documentation

I want to understand the internal working of Expressjs (just curious). Much of the thing are clear but I am not able to understand the chaining of routing and middleware. How expressjs add all the route and middleware to path / and how it keep the stack of route with middleware internally
So I will be very thankful to you if you provide some documentation or link from where I get the understanding how expressjs work internally
Thanks
ExpressJS is just an HTTP server allowing you to route and manipulate the received requests and returning a response.
So if you carefully look at the HTTP packet format below,
you can find the method and the path in the first line.
So, basically here express-router has a regex matcher that tries to match the HTTP request it receives to the predefined routes declared in the express application.
If you check L:43 Router, here it shows that the route you declare is just a function containing 3 constants:
path - That would be a path to match.
stack - Following a proper format, the URL is broken down using the / separator and a stack is formed in order of it's parsing, comprising another function called layer.
methods - Methods are the HTTP methods that we declare along with the path.
Parsing
So when a request is made, let's suppose: http://localhost:8000/user/1/test
We get the path: /user/1/test
The router's handle function is executed. Then this path is broken down into layers and formed a stack: ['user', '*', 'test']
This stack is then matched with that of the route objects that are pre-declared in the application and are used as Route functional objects.
As soon as it finds the match the callback is executed!

Possible to use http-parser-js in an Electron app?

I need to make an HTTP request to a service that returns malformed headers that the native Node.js parser can't handle. In a test script, I've found that I can use the http-parser-js library to make the same request and it handles the bad headers gracefully.
Now I need to make that work within the Electron app that needs to actually make the call and retrieve the data and it's failing with the same HPE_INVALID_HEADER_TOKEN. I assume, for that reason, that the native HTTP parser is not getting overridden.
In my electron app, I have the same code I used in my test script:
process.binding('http_parser').HTTPParser = require('http-parser-js').HTTPParser;
var http = require('http');
var req = http.request( ... )
Is there an alternate process binding syntax I can use within Electron?
This was not an electron issue. My app makes several different requests and most of the are to services that return proper headers. Originally, I was using the request-promise library to handle all calls, but I needed to modify the one call that returned bad headers.
The problem was that I was still using request-promise for the other calls and that library conflicts with the custom code I had to write to deal with the malformed headers. Once I modified my custom code to handle all requests, things worked much more smoothly.

node.js body on http request object vs body on express request object

I'm trying to build an http module that suppose to work with an express server.
while reading the http module api, I see that it doesn't save the body inside the request object.
So my questions are:
If I want to build an express server which works with the official http module, how should I get the body?
I consider to implement the http module in the following way: listening to the socket, and if I get content-length header, listetning to the rest of the socket stream till I get all the body, save it as a memeber of the http request, and only then send the request object to the express server handler.
What are the pros and cons of my suggestion above vs letting the express server to "listen" to the body of the request via request.on('data',callback(data))
I mean , why shouldn't I keep the body inside the 'request' object the same way I keep the headers?
It's hard to answer your question without knowing exactly what you want to do. But I can give you some detail about how the request body is handled by Node/Express, and hopefully you can take things from there.
When handling a request (either directly via Node's request handler, or through Express's request handlers), the body of the request won't automatically be received: you have to open an HTTP stream to receive it.
The type of the body content should be determined by the Content-Type request header. The two most common body types are application/x-www-form-urlencoded and multipart/form-data. It's possible, however, to use any content type you want, which is usually more common for APIs (for example, using application/json is becoming more common for REST APIs).
application/x-www-form-urlencoded is pretty straightforward; name=value pairs are URL encoded (using JavaScript's built-in encodeURIComponent, for example), then combined with an ampersand (&). They're usually UTF-8 encoded, but that can also be specified in Content-Type.
multipart/form-data is more complicated, and can also typically be quite large, as vkurchatkin's answer points out (meaning you may not want to bring it into memory).
Express makes available some middleware to automatically handle the various types of body parsing. Usually, people simply use bodyParser, though you have to be careful with that middleware. It's really just a convenience middleware that combines json, urlencoded, and multipart. However, multipart has been deprecated. Express is still bundling Connect 2.12, which still includes multipart. When Express updates its dependency, though, the situation will change.
As I write this, bodyParser, json, urlencoded, and multipart have all been removed from Connect. Everything but multipart has been moved into the module body-parser (https://github.com/expressjs/body-parser). If you need multipart support, I recommend Busboy (https://npmjs.org/package/busboy), which is very robust. At some point, Express will update it's dependency on Connect, and will most likely add a dependency to body-parser since it has been removed from Connect.
So, since bodyParser bundles deprecated code (multipart), I recommend explicitly linking in only json and urlencoded (and you could even omit json if you're not accepting any JSON-encoded bodies):
app.use(express.json());
app.use(express.urlencoded());
If you're writing middleware, you probably don't want to automatically link in json and urlencoded (much less Busboy); that would break the modular nature of Express. However, you should specify in your documentation that your middleware requires the req.body object to be available (and fail gracefully if it isn't): you can go on to say that json, urlencoded, and Busboy all provide the req.body object, depending on what kind of content types you need to accept.
If you dig into the source code for urlencoded or json, you will find that they rely on another Node module, raw-body, which simply opens the request stream and retrieves the body content. If you really need to know the details of retrieving the body from a request, you will find everything you need in the source code for that module (https://github.com/stream-utils/raw-body/blob/master/index.js).
I know that's a lot of detail, but they're important details!
You can do that, it fairly simple. bodyParser middleware does that, for example (https://github.com/expressjs/body-parser/blob/master/index.js#L27). The thing is, request body can be really large (file upload, for example), so you generally don't want to put that in memory. Rather you can stream it to disk or s3 or whatnot.

Resources