what is the difference between ServerResponse and http.IncomingMessage? I'm new in Node,and I'm really confused about these two object.
The http.IncomingMessage object represents the request information from the client received by the server. See this link for the Node API docs. So, this object contains things like the headers, the method (GET, POST, etc...), the URL requested, etc... It implements the ReadableStream interface -- which means you can read data from it using a stream -- and has several events, methods and properties. (too many to list here...)
The ServerResponse object represents the http server's response to the client. See this link for the Node API docs. With this object, you can set the headers that will be sent to the client, the status code and status message of the response, as well as any data to be returned. It implements the WritableStream interface -- which means you can write to it using a stream -- and also has several events, methods, and properties.
In many server side programs you'll see something like:
function foobar(req, res) {
}
The req variable holds the http.IncomingMessage object -- it's short for request. The res variable holds the ServerResponse object -- it's short for response.
Please see the documentation links for a full explanation of both objects.
Hope this helps!
req is an IncomingMessage object and res is a ServerResponse object.
So check for unique properties on each, for example if the particular object has a writeHead() function, then it's the response object.
You may also be able to use instanceof to check: res instanceof http.ServerResponse.
Related
is it possible to extract and set as variable the "Payload Request" which has been pushed in order to receive particular response?
You can access the request object in the callback function by response.request.
This object is the request object itself, so it contains everything you passed in the request. It doesn't have a "payload" attribute though.
The equivalent should be response.request.body, assuming you had a body in the request. Everything else is still there, headers, cookies, meta, method, etc
More on the params of request here.
I'm brand new to Node.js and I'm having a hard time understanding this. How does Node know that these two parameters are objects? Where do they come from? Are they provided by Node itself?
Whenever you use a library in Node.js, via something like require(), you're actually importing all the code from that library, executing it, and generally getting a return value equal to that module's final module.exports variable. So when you call a function from a library, that function was defined inside the library, including the definitions of how it decides to invoke any callbacks you pass to it. The names "req" and "res" can be anything -- you could call them "John" and "Amy" (but please don't, for clarity) -- but the first parameter will always be the request object and the second will always be the response object. Because that's the order the library passes them when it invokes your callback.
Most frameworks stick to the (req, res) parameter structure simply because that's how the bundled HTTP library does it. They don't have to, but it's always nice when everyone is consistent, so you can easily guess how to use a new library :)
createServer() is a function that expects one parameter - callback function. It takes that callback function that you provide (as anonymous function in our case), stores somewhere and calls it every time new request comes. Native code parses request to javascript object request and passes it to your callback function alongside with object response (which is a collection of callback functions for handling request). It is not node it is you the one who should know that node call you back with two arguments to make things happen.
Check the documentation:
https://nodejs.org/api/http.html#http_http_createserver_options_requestlistener
https://www.w3schools.com/nodejs/nodejs_http.asp
https://www.w3schools.com/nodejs/met_http_createserver.asp
https://www.w3schools.com/nodejs/func_http_requestlistener.asp
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('Hello World!');
res.end();
}).listen(8080);
I'm struggling with the same issue. I've read the docs too and the answers here as well. I'll give an answer but I'm not pretty sure about it.
First of all, I'll write the inheritance tree down (from different entries of the Node's Docs):
Class: EventEmitter
Class: net.Server ---- Extends:
Class: http.Server ---- Extends: <net.Server>
http.createServer([options][, requestListener]) ---- Returns <http.Server>
Why http.createServer does have access to these two objects?. It does because of http.createServer returns a <http.Server> Class. This one has this "request" event that is "Emitted each time there is a request." and therefore, you have access to the request and response objects.
But what does link the two events referenced before?. I guess that since http.createServer inherits from an EventEmitter class the "requestListener" is added to the list of "request" events similarly as it works EventEmitters when you add a new listener to a EventEmitter object ("All EventEmitters emit the event 'newListener' when new listeners are added", further reading see below).
If you read the request event's docs you'll see that has a request and response objects that belong to an <http.IncomingMessage> and a <http.ServerResponse> respectively. Then if you take a look at the docs of each one (see at the bottom of this comment) you'll know that once you create an http.server it'll pass the <http.IncomingMessage> as the first argument and <http.ServerResponse> as the second argument to the 'request' event.
From the Node's Docs:
Event: 'request'
request <http.IncomingMessage>
response <http.ServerResponse>
Emitted each time there is a request. There may be multiple requests per connection (in the case of HTTP Keep-Alive connections).
Class: EventEmitter
All EventEmitters emit the event 'newListener' when new listeners are added and 'removeListener' when existing listeners are removed.
Event: 'newListener'
eventName | The name of the event being listened for
listener The event handler function
The EventEmitter instance will emit its own 'newListener' event before a listener is added to its internal array of listeners.
Listeners registered for the 'newListener' event are passed the event name and a reference to the listener being added.
The fact that the event is triggered before adding the listener has a subtle but important side effect: any additional listeners registered to the same name within the 'newListener' callback are inserted before the listener that is in the process of being added.
Class: http.IncomingMessage ---- Extends: <stream.Readable>
An IncomingMessage object is created by http.Server or http.ClientRequest and passed as the first argument to the 'request' and 'response' event respectively. It may be used to access response status, headers and data.
Class: http.ServerResponse ---- Extends: <http.OutgoingMessage>
This object is created internally by an HTTP server, not by the user. It is passed as the second parameter to the 'request' event.
I wonder how to access req object if there's no 'req' parameter in callback.
This is the scenarioļ¼
In ExpressJs, I have a common function, it uses to handle something with 'req' object, but not pass req into it.
module.exports = {
get: function(){
var req = global.currentRequest;
//do something...
}
}
My current solution is that I write a middleware for all request, I put the 'req' in global variable, then I can access the 'req' everywhere with 'global.currentRequest'.
// in app.js
app.use(function (req, res, next) {
global.currentRequest= req;
next();
});
But I don't know if it's good? Can anyone have suggestions?
Thanks a lot!
The only proper way is to pass the req object through as an argument to all functions that need it.
Stashing it in a global simply will not work because multiple requests can be in process at the same time if any requests use async calls as part of their processing and those multiple requests will stomp on each other making a hard to track down bug. There are no shortcuts here. Pass the current request as an argument to any code that needs it.
You cannot put request-specific data into a global in node.js, ever. Doing so will create an opportunity for two requests that are in-flight at the same time to stomp on each other and for data to get confused between requests. Remember, this is a server that is potentially handling requests for many clients. You cannot use synchronous, one-at-a-time thinking for a server. A node.js server may potentially have many requests all in flight at the same time and thus plain globals cannot be used for request-specific data.
There is no shortcut here. You will just have to pass the req object through to the function that needs it. If that means you have to change the function signature of several intervening functions, then so-be-it. That's what you have to do. That is the only correct way to solve this type of problem.
There are some circumstances where you may be able to use a closure to "capture" the desired req object and then use it in inner functions without passing it to those inner functions, but it does not sound like that is your function structure. We'd have to see a lot more of your real/actual code to be able to know whether that's a possibility or not.
Actually, this is possible with something like global-request-context
This is using zone.js which let you persist variables across async tasks.
Just yesterday got that I can't use one function that would return one template depending on cookies, and wich would be called by different methods of different routes. The reason is all the response.set_cookie() are not applied to main Bottle object HTTPResponse before the method finishes serving current route. So the question is there a way to explicitly cast application of all the changes to HTTPResponse object, so i could avoid passing complex structures to subroutines and etc.
Thank you for help!
UPD: there is a response.set_cookie('temp', 'sampletext') line for example. And then i am calling subroutine and it calls another one and so on. So In each of them i won't have request.get_cookie('temp') returning 'sampletext'. Because changes to cookies wasn't applied yet. There are in the Bottle.py code you can find following code:
class HTTPResponse(Response, BottleException):
def __init__(self, body='', status=None, headers=None, **more_headers):
super(HTTPResponse, self).__init__(body, status, headers, **more_headers)
def apply(self, response):
response._status_code = self._status_code
response._status_line = self._status_line
response._headers = self._headers
response._cookies = self._cookies
response.body = self.body
that seems to be executing once per request and changes from httpresponse objects are appliied to the response object only on finish of the rout's serving method termination.
I am asking if there is a way to apply changes to response object manually, during the route's serving method evaluation.
I am asking if there is a way to apply changes to response object manually, during the route's serving method evaluation.
No.
I'm not completely sure, but it sounds like you just want to store some state during a request.
The mechanism for this is to simply set attributes on the request object. E.g.
#route(...)
def index_page():
...
request.mydata = 'hello'
...
This is completely independent of cookies. If you need both, just set both; one on the request object and the other on the response.
Has anyone used node-rest-client? For POST and PUT methods, it says "To send data to remote site using POST or PUT methods, just add a data attribute to args object:" So how can I distinguish between a POST call and PUT call?
To make a put request, you just use the put method instead of the post or get methods.
client.put("http://remote.site/rest/xml/method", function(data, response){
// parsed response body as js object
console.log(data);
// raw response
console.log(response);
});