use different routes for different ports in express app - node.js

Is it possible in express/node app to have different routes configured to different ports?
Example:
'/foo/bar' accessible to only localhost:3000
'/bar/foo' accessible to only localhost:3002

Yes, but you just create two servers, each on its own port and then create an express app object for each server and register routes for the desired server on the appropriate app object. A given server only listens on one port.
const express = require('express');
// first server
const app3000 = express();
app3000.get('/bar/foo', function(req, res) {
// code here for port 3000 handler
});
app3000.listen(3000);
// second server
const app3002 = express();
app3002.get('/foo/bar', function(req, res) {
// code here for port 3002 handler
});
app3002.listen(3002);

Related

Routes are not working in cPanel deployed json-server

I recently tried to deploy json-server to my interserver's shared hosting plan via cPanel.
I uploaded the app and configured a Node.js app and I'm able to access the endpoint via 'https://soltonbaev.com/json-server/api/contacts' however the jsonServer.rewriter() is not rewriting the "/api/" route to the "/".
In addition I cannot access the individual object via it's id, like for instance "https://soltonbaev.com/json-server/api/contacts/1". Server returns 404.
So clearly, JSON server is not picking up the routes when it is supposed to.
Here is the content of my server.js file
require('dotenv').config();
const jsonServer = require('json-server');
const cors = require('cors');
const server = jsonServer.create();
const router = jsonServer.router('database.json');
const middlewares = jsonServer.defaults();
const port = process.env.PORT || 3000;
server.use(
jsonServer.rewriter({
'/api/*': '/$1',
})
);
server.use(cors({origin: process.env.REMOTE_CLIENT_APP, credentials: true}));
server.use(middlewares);
server.use(router);
server.listen(port, () => {
console.log(
`🚀 JSON Server is running on ${process.env.REMOTE_CLIENT_APP}:${port}}`
);
});

Confused about Express, node.js terminology

I am new to web development. I am currently learning express.js. The following chunk of code and text is from their documentation.
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => res.send('Hello World!'))
app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`))
This app starts a server and listens on port 3000 for connections.
I am confused as to what the server is here. Which line of code refers to the 'creation of the server'? Is the express app the server itself, or is it only listening for requests on port 3000, while the server is something else?
Thanks a lot!
Basically Express is a framework of Node Js, Like Python has Django, Java has Spring etc..
When you create server in node js you use HTTP module, In express by inside function they provide listen function.
When you create Server using Node you use below code
http.createServer(function (req, res) {
res.write('Hello World!');
res.end(); //end the response
}).listen(8080);
So in node http module have Listen function & in express js express module have listen function.
app.listen creates a new server. In express there is no any terminology of CreateServer. So express is very much flexible to use.
Please follow this url http://expressjs.com/en/guide/writing-middleware.html
At the minute you call listen the server is going to start running, listening to the PORT you have defined.
Here is a line by line commented version of your code :
//We are creating the express app by setting it to the app variable.
const express = require('express')
//The express object
const app = express()
//The port
const port = 3000
/*
.get is telling to the express object that when it gets that route ('/')
it should give the specified response : 'Hello World!' for our case.
It takes in 2 arguments:
(1) the url - the route
(2) the function that tells express what to send back as a response for the
request - the callback function
*/
app.get('/', (req, res) => res.send('Hello World!'))
//.listen is going to bind the application to the port 3000.
app.listen(port, () => console.log(`My awesome app is listening at
http://localhost:${port}`))
To find out about the difference between the concepts node and express, I found this response usefull.
As you said, that entire chunk "create" the server, its not only one line to "create" the server.
Using node and npm you install express const express = require('express')
In this line yo use express framework const app = express()
In this line you set a port const port = 3000
In this line you create the main root app.get('/', (req, res) => res.send('Hello World!'))
and this line use the port and up runnig your web server app.listen(port, () => console.log(Example app listening at http://localhost:${port}))
As you can see, all of then combined "creates" the server

Simple subdomain with Express

I am trying to use Express as my server in MEAN stack on AWS. However I've ran into a issue trying to setup subdomains. I have my main domain name domain.com and id like to have app.domain.com.. However I've tried everything I've found online to write the functionality into the server.js file and nothing works. How can I easily accomplish this to make the second function instead of loading on Port 8000 load up at my app.domain.com sub domain? Thanks in advance!
var express = require('express');
// Main Website
var web = express();
web.get('/', function (req, res){
res.sendFile('/web/index.html', { root: '.' })
});
var port = 9000;
web.listen(port);
console.log('Web Listening on port', port);
//Main Application
var app = express();
app.get('/', function (req, res){
res.sendFile('/app/index.html', { root: '.' })
});
var port = 8000;
app.listen(port);
console.log('Web Listening on port', port);
Update:
I tried using Vhost here but it loads the same thing for both the main domain and the sub domain and so it does not work. here is the code I used:
var express = require('express');
var connect = require('connect');
var http = require('http');
var vhost = require('vhost');
// Main Website
var web = express();
web.get('/', function (req, res){
res.sendFile('/web/index.html', { root: '.' })
});
var port = 9000;
web.listen(port);
console.log('Web Listening on port', port);
//Main Application
var app = connect()
app.use(vhost('app.domain.com', function (req, res) {
res.sendFile('/app/index.html', { root: '.' })
httpServer.emit('request', req, res)
}))
app.listen(8000)
I don't really need these to be on separate ports that was just something I was trying originally. But either way does not work still..
There's no need for any thing outside of node.js serving on one port. It's just a matter of routing based on the http header.
var express = require('express');
var http = require('http');
var vhost = require('vhost');
// Main Website
var webapp = express();
webapp.get('/', function (req, res){
res.sendFile('/web/index.html', { root: '.' });
});
//Main Application
var mainapp = express();
mainapp.use(function (req, res) {
res.sendFile('/app/index.html', { root: '.' });
}));
//Virtual Routing Application
var app = express();
app.use(vhost('app.domain.com', webapp));
app.use(vhost('domain.com', mainapp));
app.use(vhost('www.domain.com', mainapp));
app.listen(9000);
Since you're using AWS, you can use Application Load Balancer to achieve your goals.
Setup an ALB, and point both domains to the ALB CNAME.
Then you will need to create 2 target groups, one for app.domain.com and another one for domain.com.
Target Group: App
protocol: HTTP
port: 8000
Target Group: Web
protocol: HTTP
port: 9000
Attach your EC2 instance to both target groups
Target group > Targets > Edit > Add to registered
Finally you will have to add an HTTP listener to your ALB, and setup the rules to forward each domain to its target group.
After the rules are set, when you enter to app.domain.com the ALB will forward the request to your express app listening on port 8000, and when browsing domain.com the one listening on port 9000 will be used.
If you are using Route53 I recommend you to use Records Set to redirect both domain and subdomain to the same ec2 instance via the ip address then you can use ngix like the comments say in this post enter link description here
Using the load balancer (ALB) generates montly the minimum cost of 21.96USD but using Route53 it is minimum of 1USD or less.
If you dont want to use a proxy like nginx you can have s3 website hosting with a low cost, arround 6USD and the route 53 routing by 1USD minimum per month and if you have REST API services you can call from front end to your instance depending the site accessed with no problems.
Regards,

nodejs server remote connection

I just want a simple http server to control GET and POST request.
I made one using nodejs and express. It works great at localhost. But it's not possible to connect this server remotely.
I also set static ip address and port forwarding but it's still not possible.
I tried port number 80 and 9000 both are set port forwarding.
Can any one help me?
var http = require("http");
var express = require("express");
var app = express();
var port = 80;
app.get('/', function (req,res) {
console.log('app.get');
res.send('abc');
});
app.post('/test', function(req,res) {
console.log('app.post');
});
http.createServer(app).listen(port,function () {
console.log('createServer');
});

Host multiple websites using Node.js Express

I am having problems configuring two different Node.js applications with different domains. Have two directories
"/abc/" -> express-admin setup (backend) -> admin.abc.com
and
"/xyz/" -> express setup (frontend) -> abc.com
I need admin.abc.com to point to express-admin setup and abc.com to express setup. I have vhost installed and both the site listens to port 80.
Have added
app.use(vhost('abc.com', app)); // xyz/app.js file
app.use(vhost('admin.abc.com', app)); // abc/app.js file
My problems:
forever is installed, whenever i start both the apps, the second one is always stopped. I tried using different port for both apps but still having the same error. Individually they run without problems.
I think my setup is too complicated for domain forwarding. Any better suggestions? May be I have a master app.js file which I can use to route the domains to their respective apps without using the app.js of each applications.
I am not sure how you are using the vhost. First of all with vhost approach, you need to run only one express app. Not two. Here is an example.
var express = require('express');
var vhost = require('vhost');
/*
edit /etc/hosts:
127.0.0.1 api.mydomain.local
127.0.0.1 admin.mydomain.local
*/
// require your first app here
var app1 = require("./app1");
// require your second app here
var app2 = require("./app2");
// redirect.use(function(req, res){
// if (!module.parent) console.log(req.vhost);
// res.redirect('http://example.com:3000/' + req.vhost[0]);
// });
// Vhost app
var appWithVhost = module.exports = express();
appWithVhost.use(vhost('api.mydomain.local', app1)); // Serves first app
appWithVhost.use(vhost('admin.mydomain.local', app2)); // Serves second app
/* istanbul ignore next */
if (!module.parent) {
appWithVhost.listen(8000);
console.log('Express started on port 8000');
}
You just need to run the main express app with vhost enabled using forever.
You're hosting the applications on the same port, using the same network interface. So when the second app starts, it will always find the port in use. If you want to use multiple applications on the same port, they each need to have their own network interface. When using vhost, you would still need to listen on a different port for each app. See this example for details. If you would like your apps to be completely independent, you're better off using node-http-proxy. This allows you to host a proxy on port 80 which forwards requests to express apps listening on different ports. If one of these apps crashes, it will not crash the other app, unlike the vhosts approach. This post gives an example of the implementation using node-http-proxy.
Thanks #veggiesaurus for pointing up to node-http-proxy. Apologies for posting late.
Here is how I solved my problem using node-http-proxy
Folder Structure:
www/
server.js
abc/ [express setup]
app.js
xyz/ [express-admin setup]
node_modules/express-admin/app.js
"abc" and "xyz" have there own setup and running on port x.x.x.x:3001 and x.x.x.y:3002
I installed node-http-proxy and added server.js file with following codes. Referred this link
var http = require('http');
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxy();
var options = {
'abc.com': 'http://x.x.x.x:3001',
'xyz.com': 'http://x.x.x.y:3002'
}
http.createServer(function(req, res) {
proxy.web(req, res, {
target: options[req.headers.host]
});
}).listen(80);
Finally, used forever to run all 3 apps setup to run forever in port 3001, 3002 and 80.
const express = require("express");
const app = express();
const fs = require('fs');
app.use((req, res, next) => {
let reqDomain = req.get("host");
if (reqDomain.indexOf(":") > -1) {
reqDomain = reqDomain.split(":")[0];
}
if(reqDomain.endsWith(".local")) {
reqDomain = reqDomain.substring(0, reqDomain.length - 6);
}
const domainPath = "public/" + reqDomain;
let filePath = domainPath + req.originalUrl;
filePath = fs.lstatSync(filePath).isDirectory() ? filePath + "/index.html" : filePath;
console.log(__dirname + "/" + filePath);
res.sendFile(filePath, { root: __dirname });
});
const port = process.env.PORT || 80;
app.listen(port, () => console.log("Server Started on Port " + port));
Inside public directory put you folder like 'my-first-website.com', 'my-second-website.com'
To test locally add following in /etc/hosts
127.0.0.1 my-first-website.com.local
127.0.0.1 my-second-website.com.local

Resources