Accessing Routes in Node inside in a Domain Name - node.js

I have a node app which is up on running on port 3000. i.e say 139.59.43.234:3000.
139.59.43.234 is my server ip.
Then I went to go daddy and assign a domain name say mydomain.nik.in which is pointing to 139.59.43.234:3000/SomeRoute.
If i then go to my browser and types mydomain.nik.in then it works properly. I can easily access my route.
This is my sample code.
var express = require('express');
var app = express();
app.get('/SomeRoute',(req,res) => { // Route 1
res.send('hello nikhil');
})
// here i have another route which i wants to access.
app.get('/SomeRoute/:id',(req,res) => { //Route 2
res.send('hello user');
})
app.listen(3000);
Now if I go to my browser and types "mydomain.nik.in/someId" then it redirects me to the SomeRoute method i.e on Route 1.
I don't know what I am doing wrong here.
I wants to access Route 2.

According to this, there should be a Wild Card Redirect option in GoDaddy settings. And it does exactly what you are asking for.

Related

Node/Express Server on DigitalOcean only responding with "/" route even if I hit "/test" route

I'm trying to host a Node.js/Express server for the first time, and I'm currently attempting to use Digital Ocean's App Platform. I have it up and running, but my routes aren't working correctly. Digital Ocean allows me to set HTTP Request Routes, and I have "/" and "/test" set for two of them. No matter what route I hit, it only ever responds with the "/" route.
Here is my code for reference:
require("dotenv").config();
const { SERVER_PORT } = process.env;
const express = require("express");
const cors = require("cors");
const app = express();
app.use(cors());
app.use(express.json());
app.get("/", (req, res) => {
res.status(200).send("This is the / route")
})
app.get("/test", (req, res) => {
res.status(200).send("This the /test route");
})
app.listen(SERVER_PORT, () => {
console.log(`Server running on port ${SERVER_PORT}`);
});
When I make a GET request to "https://{DigitalOceanURL}/", I get the correct response of "This is the / route", however when I make a GET request to "https://{DigitalOceanURL}/test", I still get the response of "This is the / route" and not "This the /test route" as is in my code.
If I try and make request to a route that doesn't exist, however, such as "https://{DigitalOceanURL}/doesntexist" I get the response "Cannot GET /doesntexist". To me this suggests that the routes I'm entering into DigitalOcean are registering, but for some reason it's not seeing anything past the initial "/" in the route.
I've been trying to Google for a while now and I can't seem to diagnose what's wrong. I thought it might be something with app.use vs app.get, as on this answer on a SO post it says that app.use "...will match all requests beginning with..." your route, whereas app.get "...matches only GET request with exact match.". So it seems that, since I'm hitting the exact route, it should be working? But it feels like the general area of my problem, as it seems to only be registering the "/" in the route and nothing else?
Both the endpoints work when running the server on localhost, so it seems like there must be some disconnect with DigitalOcean.
Any help would be greatly appreciated - as I mentioned this is my first time trying to host and it's a bit overwhelming.
Thank you!
The issue was with my Digital Ocean settings. As I said in my question: "Digital Ocean allows me to set HTTP Request Routes, and I have "/" and "/test" set for two of them." It worked when I removed the "/test" route and only had one, "/" in my Digital Ocean settings. I interpreted it as "List all routes I had in my express app", but I guess that's not what it meant. There only should've been one set: "/".
Your / route declaration comes before the one for /test. Express matches in code order, so / picks up every incoming request, and none make it to the more specific route. Switch their order.
This isn't specific to Digital Ocean, of course.

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.

I have express on backend and react on frontend, but i also have admin page working on pug template, how can i run it on one domain

I have express on back-end and react.js on frontend, but i also have admin page with pug view engine, working on express routes, how can i use these in one domain
Expressjs is composable in a really nice way. You can have a top level express application which routes off to sub-express apps and serve your individual services.
Lets say you want to serve your react frontend from www.example.com, your admin (pug views) from www.example.com/admin, and you also want to have an api which serves the react frontend at www.example.com/api`.
You would want something a bit like the following code sample which demonstates the composition of express applications. I've not run the code but it should be enough to get you going.
// This parent app acts as a parent layer and router
// for all your "sub apps". Any middleware you apply
// to this express app will apply to *all your other
// sub-apps*.
const parentApp = express();
// We now create another express instance, this will
// house the API. It can be in another file and you
// could require in something like "require('api');"
// instead but for brevity we'll keep it all in one
// file.
const apiApp = express();
apiApp.get('/info', (req, res, next) => {
console.log('/info');
return res.sendStatus(200);
});
// Mount the sub app on the /api route. This means
// you can how hit 'www.example.com/api/info' and
// you'll get back a 200 status code.
parentApp.use('/api', apiApp);
// Now we setup the admin app which we'll add pug
// views into. This is an example so just pretend
// the views exist.
const adminApp = express();
adminApp.set('views', './views');
adminApp.set('view engine', 'pug');
adminApp.get('/login', (req, res, next) => {
return res.render('login', { title: 'Hey' });
});
// Mount the sub app on the /admin route. This way
// we can hit www.example.com/admin/login to get
// our login page rendered.
parentApp.use('/admin', adminApp);
// Now we create and mount the frontend app that
// serves our fully built react app. You could do
// this with nginx instead but you wanted to do
// it with express so lets do it that way.
const frontendApp = express();
frontendApp.use(express.static('/frontend));
parentApp.use('/', frontendApp);
If you'd rather not create yourself a top level express app (and thus creating a bit of a monolith application) then I'd recommend checking out the nginx documentation, or the docs for the HTTP server you use. You should be able to direct requests to particular endpoints to different node applications running on different ports. Static files can then be served natively by your HTTP server. This is definetely a more efficient and elegant approach, but since you asked about express I wanted to showcase that approach primarily.

Is it possible to render another express application from express?

Basically what happened was we have an app server that is running express and routes to a bunch of SPAs. This was great but then we wanted to have an app that runs its own node/express script (ghost). I can't figure out how to set the route /ghost to go to ./webapps/ghost/index.js
Is this just not possible?
You need to redirect incoming requests to the ghost express instance. I have done so in my personal site by adding a /blog route to my primary express instance and forwarding any request to it to the ghost expresss instance. Check it out here: https://github.com/evanshortiss/evanshortiss.com/blob/master/server.js
The basic gist is that you do the following:
app.use('/blog', function(req, res, next) {
// Forward this request on...
return next();
}, ghostServer.rootApp); //...but we forward it to a different express instance
If you're running both as separate processes then you could use Apache or nginx to just redirect the requests. If you absolutely must use an express application to forward requests then try the node-http-proxy module.
If you need to proxy from express you could do this using the http-proxy module by Nodejitsu:
var proxy = require('http-proxy').createProxyServer({});
app.use('/blog', function (req, res) {
// You may need to edit req.url (or similar) to strip the /blog part of the url or ghost might not recognise it
proxy.web(req, res, {
target: 'http://127.0.0.1:'+GHOST_PORT
});
});

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