http.request vs http.createServer - node.js

What is the difference between the request in this line of code:
http.createServer(function(request,response){. . .}
and request in
http.request()
Are both requests done to the server?
I am new to node.js and I am sorry if I sound dumb!
How does http.request() work?
In http.request() we fetch data from another site but in order to fetch data from another site we first need to go to our site and then make a request? Explain it with a simple real-life example!

http.request() makes a request to another HTTP server. Suppose for some reason I wanted to go download Stack Overflow's home page...
http.request('https://stackoverflow.com/', (res) => {
// ...
});
http.createServer()... it creates an HTTP server. That is, it binds your application to a socket to listen on. When a new connection is made from somewhere or something else, it handles the underlying HTTP protocol of that request and asks your application to deal with it by way of a callback. From the Node.js documentation:
http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('okay');
});
These two methods have absolutely nothing to do with each other. http.request() is for making a request to an HTTP server. http.createServer() is for creating your own HTTP server. Don't get confused by the callbacks.

Based on the source code of nodejs (extract below), createServer is just a helper method to instantiate a Server.
Extract from line 1674 of http.js.
exports.Server = Server;
exports.createServer = function(requestListener) {
return new Server(requestListener);
};
The http.request() API is for when you want your server code to act as a client and request content from another site and has GET, POST, PUT, DELETE methods.

Related

How to ensure HTTP trigger will be called only via HTTPS?

I'm building an API on Cloud Functions with NodeJS and Express (Firebase) and I'd like to accept only calls via HTTPs so calls made over plain HTTP will fail.
Is it possible to do it?
You should examine the request object being passed to your function. It's going to be an Express type Request object. Request has a property called protocol that should be "https". So:
functions.https.onRequest((req, res) => {
if (req.protocol !== "https") {
// reject the request
res.sendStatus(403)
}
})
Generaly you want a application running for each protocol listening to a different port. To solve your problem you could simply ignore the requests for the http instance or redirect every http request to a https request.
Here's a middleware for that:
app.use(function(request, response){
if(!request.secure){
response.redirect("https://" + request.headers.host + request.url);
}
});
See the express documentation.

What does http and https module do in Node?

Can someone help me in understanding what does http and https module do in Express?
I was going through the following docs on w3schools
From definition it says
Node.js has a built-in module called HTTP, which allows Node.js to
transfer data over the Hyper Text Transfer Protocol (HTTP).
With following example
var http = require('http');
//create a server object:
http.createServer(function (req, res) {
res.write('Hello World!'); //write a response to the client
res.end(); //end the response
}).listen(8080); //the server object listens on port 8080
This is the example to live demo
First, I am unable to comprehend their example like Where are they making (route) request so that they are receiving response?
Second by the definition, to make a request, using libraries like axios can be alternative?
third, when we make an api request, isn't the data transferred over http/https?
app.post("/", (req, res) => {
In short, Can someone please explain me in more human words the use of http package in express?
Update: I might be confusing this with express, I am used to using express and here we aren't using express
1- They aren't defining any route. That piece of code only creates a server running on port 8080 that when it's created or accessed on the home route (/) returns "Hello World". If you want to define routes you should take a closer look to a module called express that it's used by most of node users due to its simplicity and documentation (https://expressjs.com/en/starter/hello-world.html) In that link you have an example for creating the server and a basic route
2- Yes it can and should be because they are way better than the default from nodeJs. Take a look at axios or superagent, superagent it's better if you want to use formdata to send images or attachments.
3- By default, all servers created using http or express are http servers (don't have a certificate to encrypt the data so they aren't secure). If you want a https server, you can buy certificates or use https://letsencrypt.org/ this module that generates free SSL certificates with 1 month validation.
http module has multiple functions, it can be used to create a server, to make http requests and so on. It's up to you to decide which submodule from the package you want to use. Express is built over the http module making everything easier.
If you need more explanation, tell me and I will try to explain a little better.

Post request to third party service from node server

What is the best way to send POST request from node server which has received the request parameter from a client? Reason I am asking for best practice because it should not affect the response time if multiple clients are calling the node service.
Here is the Backbone Model which sends the request to node server:
var LoginModel = Backbone.Model.extend({
url:'http://localhost:3000/login',
defaults: {
email:"",
password:""
},
parse: function(resp) {
return resp;
},
login: function() {
console.log('Here in the model'+JSON.stringify(this));
this.save();
}
});
var loginModel = new LoginModel();
Node Server
var http = require('http'),
express = require('express');
var app = express();
app.listen(3000);
app.post('/login', [express.urlencoded(), express.json()], function(req, res) {
console.log('You are here'); console.log(JSON.stringify(req.body));
//Send the post request to third party service.
});
Should I use something like requestify inside app.post() function and make a call to third party service?
I like superagent personally but request is very popular. hyperquest is also worth consideration as it resolves some issues with just using the node core http module for this.
Reason I am asking for best practice because it should not affect the response time if multiple clients are calling the node service.
First, just get it working. After it's working you can consider putting a cache somewhere in your stack either between your clients and your api or between your server and the third party api. I'm of the opinion that if you don't know exactly where you need a cache, exactly why, and exactly how it will benefit your application, you don't need a cache, or at the very least, you aren't prepared instrumentation-wise to understand whether your cache is helping or not.

nodejs configuration httpd.conf

I'm used to apache and putting configuration items in httpd.conf
Where do these types of configurations go in a node environment. For example, I want to make sure that only GET, POST, and PUT are accepted and Head and Trace are not accepted. Where does a config like that go?
Additional things like Cache-Control and limiting request and response sizes.
Node.js is just a JS framework with a system API. Technically, you could reimplement Apache HTTP Server in Node.js, mimicking its behaviour and its configuration structure. But would you?
I believe you are using Node.js' HTTP module. Look at the docs: there's no way to read configuration from a file. The server is programmatically created using http.createServer. You provide a callback that listens to requests. This callback provides an http.IncomingMessage parameter (first parameter) which contains everything you need.
Here's an example:
// load the module
var http = require('http');
// create the HTTP server
var server = http.createServer(function(request, response) {
// use the "request" object to know everything about the request
console.log('got request!');
// method ('GET', 'POST', 'PUT, etc.):
console.log('HTTP method: ' + request.method);
// URL:
console.log('HTTP URL: ' + request.url);
// headers:
console.log('HTTP headers follow:');
console.log(request.headers);
// client address:
console.log('client address: ' + request.socket.address().address);
});
// listen on port 8000
server.listen(8000);
If you really want a configuration file, you will have to forge it yourself. I suggest creating a JSON configuration file as this can be turned directly into a JS object using JSON.parse(). Then just use your configuration object programmatically to achieve what you want.

Pass additional arguments to node.js callack

I have created a rest client to make calls outside of my application. I want to send the data I receive back from the rest calls to the client's web browser.
Something like the following, but what is the best way to structure the code to allow access to the response to write back to the web browser with as loose coupling as possible? I don't want to define the rest client within a request handler.
var servReq = http.request(options, function(restResponse){
var status = restResponse.statusCode
var headers = restResponse.headers
restResponse.setEncoding("utf8");
d='';
restResponse.on('data', function(chunk){
d += chunk;
})
restResponse.on('end', function(restResponse){
// res would be a response to write back to the client's web browser
// with the data received from the rest client.
res.writeHead(200, {"content-type":"text/plain"})
res.write(d)
res.end();
})
}
Using request, you can pipe the API response straight to your application's response. This way it'll be completely loosely coupled—your server will return precisely what the API returns.
request(options).pipe(res);
https://github.com/mikeal/request#streaming

Resources