two node.js servers at one web address - node.js

I have two web application node.js servers and I need to have them under one web address.
It should work like this:
example.com/wa/* -> redirect to example.com:pppp
others example.com/* -> redirect to example.com:qqqq
I have experimented with http proxy module, but it doesn't work, maybe the problematic part is the fact, both servers are https not http.

Using Express you can do something like this
var express = require('express');
var http = require('http');
var app = express();
app.use('/wa/*', function(req, res){
req.redirect('example.com:pppp')
});
app.use('/*', function(req, res){
req.redirect('example.com:qqqq')
});
http.createServer(app);
Not tested, but it should work.
Note: The /wa/* route must come before the /* route. otherwise all requests will get redirected by the first middleware

Related

what is the difference between using Express GET method and HTTPS GET method in the below code?

const express = require("express");
const app = express();
const https = require("https");
app.get("/", function (req, res){
var url = "https://***";
https.get(url, function(response){
console.log(response);
});
res.send("server running");
});
Express is really just a layer on top of http.
I reckon those following links might help you out, this question has been asked.
what's the technical difference between express and http, and connect for that matter
Difference between a server with http.createServer and a server using express in node js
app.get() registers a listener for a specific INCOMING http request path on a local Express server.
https.get() makes an OUTBOUND https request TO some other https server to fetch content from that other server.
And, obviously, the https.get() is using https, not http. The app.get() could be listening for either - it depends upon how the server it is part of is started (as an http server or an https server) which the code you have in your question does not show.

How can I have multiple node applications on nodejs server?

I am trying to merge two (or more) nodejs apps. 1st is login application that takes you to your dashboard. When you are there you should see another app that is dedicated to you, that runs on different local IP and port.
So for login I am using Okta express login portal that grabs user data from Okta servers. Now this is dashboard in pug
block content
h2.text-center Dashboard
h2.user.profile.profileUrl
.row
.offset-sm-2.col-sm-8
.jumbotron.text-center.
Welcome to your dashboard page, #{user.profile.firstName}.
#{user.profile.profileUrl}.
and looks like this
dashboard
now I want that user.profle.profileURL actually opens when clicked on control panel but address not to be visible in browser so address would be same xydomain/dashboard
is it that possible?
Yes its possible.
The technology you want is node js reverse proxy. You want to create multiple server on same machine or different machine, but with same domain, but after the domain extension, the different url points to different server.
If multiple server on same local machine, use different port numbers! If different machines, use the ip number of the machine and its port number. Make sure firewalls are open for the ports!
Here's a reference for you to get you started: https://codeforgeek.com/reverse-proxy-using-expressjs/
Basic understanding is create the 3 different servers. For same machine, use different port numbers.
Then create a server and get that pointing to the different servers when the url is hit.
On all servers, run this command to setup node:
npm init -y
npm i -S express http-proxy
These are the codes for all 4 servers.
eg server1:
var express = require("express");
var app = express();
app.get('/app1',function(req,res) {
res.send("Hello world From Server 1");
});
app.listen(3001);
server2:
var express = require("express");
var app = express();
app.get('/app2',function(req,res) {
res.send("Hello world From Server 1");
});
app.listen(3002);
Server3:
var express = require("express");
var app = express();
app.get('/app3',function(req,res) {
res.send("Hello world From Server 1");
});
app.listen(3003);
Reverse Proxy Server:
var express = require('express');
var app = express();
var httpProxy = require('http-proxy');
var apiProxy = httpProxy.createProxyServer();
var serverOne = 'http://localhost:3001',
ServerTwo = 'http://localhost:3002',
ServerThree = 'http://localhost:3003';
app.all("/app1/*", function(req, res) {
console.log('redirecting to Server1');
apiProxy.web(req, res, {target: serverOne});
});
app.all("/app2/*", function(req, res) {
console.log('redirecting to Server2');
apiProxy.web(req, res, {target: ServerTwo});
});
app.all("/app3/*", function(req, res) {
console.log('redirecting to Server3');
apiProxy.web(req, res, {target: ServerThree});
});
app.listen(3000);
Now run ALL 4 servers.
Now go to url, type in:
localhost:3000/app1/ and it goes to your server 1
localhost:3000/app2/ and it goes to your server 2
localhost:3000/app3/ and it goes to your server 3
If you're on different local machine, change localhost to the ip numbers.
If you don't like using the / after app1, then you need to configure it. This is outside the scope of this question.
Good luck to you.
Edit: I forgot to mention, your original pug file you put into your reverse proxy server. It's homepage, you render your dashboard page in your proxy server.

How to emulate traffic in express.js

I have a node express server responding to http traffic:
const http = require("http");
const express = require("express");
const app = express();
const server = http.createServer(app);
app.use(function(req,res,next){
console.log(`logging: req: ${util.inspect(req)}`);
next();
});
and all that works fine. I'd like to have a program on my node server inject emulated http traffic into the express stack, without a network connection. I can't just magic up a (req,res) pair and call a middleware function like the one in app.use above, because I don't have a next to give it, and my req and res will not be the ones next passes on to the next middleware in the stack.
Edit: What I actually have is a websocket connection sending data packets of a different format, different data contents from http traffic that can also carry the same information. I can take those websocket packets and build from those a request that is in the same format that the http traffic uses. I would like to pass that transformed request through the express http middleware stack and have it processed in the same way. Going all the way back to create an http request having just dealt with a ws request seems a bit far.
What's the simplest way to emulate some traffic, please? Can I call a function on app? Call some express middleware, or write a middleware of my own to inject traffic? Call a function on server?
Thanks!
Emulation traffic by calling some Express.js internal functions isn't the right way. Much easier is to trigger the server by HTTP request from the same process
const http = require('http');
const util = require('util');
const express = require('express');
const app = express();
const server = http.createServer(app);
app.use(function(req, res, next) {
console.log(`logging: req: ${util.inspect(req)}`);
next();
});
const port = 8081;
server.listen(port);
http.request({ port }).end();
From your question
I'd like to have a program on my node server inject emulated http traffic into the express stack, without a network connection
Can you clarify, why without a network connection?
A few things:
You need to make an endpoint
You need to host your server somewhere
You need something to send requests to your server
Express provides you a way to receive requests (req, res) (might be from a browser, might not be), perform some operations, and return responses (req, res) to the requester.
The expression
app.use(function(req,res,next){
console.log(`logging: req: ${util.inspect(req)}`);
next();
});
is actually a middleware function. This will take every request to your server and change the request object created by express into a string, and print it in your server log.
If you want a testable endpoint, you would add this to the bottom of the snippet you posted
app.get('/test', function (req, res) {
res.json({success:true})
})
This tells your app to allow GET requests at the endpoint /test
Next you're going to need to host your express server somewhere you can send requests to it. Your local machine (localhost) is a good place to do that. That way, you don't need an internet connection.
Pick a port you want to host the server on, and then it will be reachable at http://localhost:<Your Port>.
Something like this will host a server on http://localhost:3000. Add this below the route we declared above:
server.listen(3000, function() {
console.log('Server running on port 3000');
});
Finally, you'll need a way to send requests to the server on localhost. Postman is a great tool for testing express routes.
I would suggest installing Postman and using that to emulate http traffic.
Once your server is running, open postman and send a GET request to your server by entering the server address and port, and hitting the blue send button (You'll be sending the request to http://localhost:3000/test).
Here's an image of what postman should look like if all goes well
You should also see your middleware fire and print out the request object in your terminal.
Good Luck!

Why combine http module with express module

Hello guys i'm new to node js and started researching and working on some tutorials. I just want a better understanding or clarification on a doubt i had. So i came across the in built module http. This helps in creating a a basic web server. Now express module is a web framework that is built on top the http module that makes it easy using a fully wedged web server without reinventing the wheel. Now I came across this code:
var express = require( 'express' )
, http = require("http")
http.createServer( options, function(req,res)
{
app.handle( req, res );
} ).listen(8080);
But in express one could simply just do this
var express = require('express');
var app = express();
app.listen(8080, function() {
console.log('Listening on ' + 8080);});
What's the difference between both? Don't they both accomplish the same thing. If not what's the difference and advantage of using the first approach. Should one adhere to the first approach as it's a good programming practice. That's my doubt as i just want a clear understanding if there's any difference.
Why combine http module with express module
There's really no reason to create your own http server using the http module. Express will just do that for you with app.listen() just fine and save you little bit of typing.
If you were creating an https server, then you would need to use the https module and pass security credentials to https.createServer(...) in order to create a properly configured server. Express does not have the ability to create a properly configured https server for you automatically.
If you look at the Express code in GitHub for app.listen(), it shows this:
app.listen = function listen() {
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
So, there's really no difference (other than a little less typing) when you use app.listen() or create your own http server and then use app as the listener to that server.
So, these two code snippets are identical in function:
var app = require('express')();
app.listen(8080);
app.get('/', function(req, res) {
res.send("hello");
});
The above code is functionally identical to:
var http = require('http');
var app = require('express')();
http.createServer(app).listen(8080);
app.get('/', function(req, res) {
res.send("hello");
});
Of course, if you're trying to set up https servers or add custom options to the .createServer() method, then you will set up your own server first and then pass app to it as the listener. app.listen(...) is just a shortcut when the default http.createServer() works fine.

URI bind Express.js

Hello I want to bind the URI of my app, for example lets imagine this scenario.
I am running express app on port 3000,
nginx on port 80, proxying requests of URI api to port 3000
And have this route on express
// Home
app.get('/', function(req, res) {
res.send('Hello!');
});
If I try access from localhost:3000 I get Hello! in my browser (that's expected),
but if I try to access from localhost/api I will get an error, of course he can't find the route I'm tryng to access.
If I change app.get to app.get('/api/... it works as expected, but this isn't what I want... I would need to prepend api in every route, there must be another way to do this, something like:
URI binding
URI filter ??
I read the documentation but can't find anything to solve my problem, and I'm thinking of doing a package that does URI bindings on express to solve this problem.
See my answer here for a solution that lets you point every request matching a leading /api to a particular express app. In the linked case, the user wanted to do some things without the leading fragment. You could leave out the app.use(app.router) for the main express app since you only care about the /api/ routes.
<snip>
var http = require('http');
var express = require('express');
var desktopApp = express();
var mobileApp = require('./mobile.js');
desktopApp.use('/mobile', mobileApp)
desktopApp.use(desktopApp.router);
</snip>
Also I am pretty sure that you can actually rewrite request.url yourself. I have never tried this so I can't promise it works! see docs http://expressjs.com/4x/api.html#req.originalUrl Also be sure to put this at the very top of your routing functions, so it is executed before any subsequent routes.
app.all('*', function(req, res, next){
req.url = req.url.replace(/^\/api/, '');
//the regex replaces leading /api with empty string
//req.originalUrl will keep the old url
next();
});

Resources