The best deployment architecture for angularjs nodejs app - node.js

I have Moto Adverts application in angularjs and nodejs.
Angularjs-client-side is running on Apache HTTP Server (localhost:8000) but nodejs-server-side is runnning as node.js http server (localhost:3000).
Piece of client-side code (angularjs):
var motoAdsServices = angular.module('motoAdsServices', ['ngResource']);
motoAdsServices.factory('Brand', ['$resource', function($resource) {
return $resource('http://localhost\\:3000/api/:id', {}, {
query: {
method: 'GET',
params: {
id: 'brands'
},
isArray: true
}
});
}]);
Piece of server-side code (nodejs):
var express = require('express');
var path = require('path');
var http = require('http');
var brands = require('./routes/brands');
var app = express();
var allowCrossDomain = function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
};
app.configure(function() {
app.set('port', process.env.PORT || 3000);
app.use(express.logger('dev')); /* 'default', 'short', 'tiny', 'dev' */
app.use(express.bodyParser()),
app.use(allowCrossDomain);
app.use(express.static(path.join(__dirname, 'public')));
});
app.get('/api/brands', brands.findAll);
http.createServer(app).listen(app.get('port'), function() {
console.log("Express server listening on port " + app.get('port'));
});
My questions are:
What I should do to run client-side and server-side on the same server.
a) On Apache HTTP Server (localhost:8000).
b) On Node.js self http server on (localhost:3000).
What architecture will be the best for production use - two independent servers for client-side and server-side or only one?
Is it good practise to use Cross-origin resource sharing (CORS) on server-side (if I should hava two independed servers)?
What I should do to not hard code address http://localhost:3000/api/brands to server-side (best practise)?

Node.js
One server will be more maintainable. To optimize you can cache static files with nginx later if you need to. (Just search 'nginx Node.js static' but it will work fine without that if you have light traffic and not a ton of static files). I would not use Apache for anything.
Here is a sample nginx config:
server {
listen 80;
server_name myserver.net;
root /mnt/app;
index index.html index.htm;
location /static/ {
try_files $uri $uri/ =404;
}
location /api/ {
proxy_pass http://127.0.0.1:8080;
}
}
You won't need CORS with one.
The ports will be the same so that isn't an issue.

I believe this is the most popular architecture for apache nodejs angularjs.
(A) in the figure.
I recommend for you to serve all files including static files via nodejs server as I wrote in my figure.
On the other hand, you could use node server only for dynamic contents and use apache to serve static files including your client side codes if you like.
But if you do so, you need apache server ALWAYS even when you develop your application. I feel that will be troublesome.
(B) in the figure.
You can serve your client side codes including other static files by locating them in public directory.
If you decide to serve all files from nodejs server, you can develop without apache and avoid to write specific port number in your code.
I think your application code should not be conscious about the port number you will use.
I hope this could be answer for your all questions.

What I should do to run client-side and server-side on the same server. a) On Apache HTTP Server (localhost:8000). b) On Node.js self http server on (localhost:3000).
Ans : you don't need to run nodejs as self hosted.instead run nodejs through Apache server and use fusion passenger too. fusion passenger will take care of running your node application in background forever. Personally I prefer Nginx + fusion for my nodejs applications.
What architecture will be the best for production use - two independent servers for client-side and server-side or only one?
Ans : I don't understand what you mean by having two servers one for client and one for server-side. Keep your client and server code on single server.
Is it good practice to use Cross-origin resource sharing (CORS) on server-side (if I should have two independent servers)?
Ans : if your server and your client are under same domain then you don't need to worry about CORS but if in future you want to expose your API to any of your client apps, then you will need to do CORS configurations.
What I should do to not hard code address http://localhost:3000/api/brands to server-side (best practice)?
Ans : I use constant to declare my base path and then do the DI in my services and factory that make the API Calls.
motoAdsServices.constant("API", {
"endpoint": "http://localhost:8080",
})
motoAdsServices.factory('Brand', ['$resource','API', function($resource,API) {
return $resource(API.endpoint + '/api/:id', {}, {
query: {
method: 'GET',
params: {
id: 'brands'
},
isArray: true
}
});
}]);

Related

How to forward http/https request to socks5 in node js

The initial problem is nginx proxy_pass with a socks5 proxy?
I decided to proxy_pass to localhost with node js server. So then I need to somehow convert http/https requests to socksv5.
I have very simple node js server let's it handle simple get and post requests like
const express = require('express');
const app = express();
app.get('/', function(req,res) {
// need to forward via socks5
});
app.post('/', function(req,res) {
// need to forward via socks5
});
app.listen(3000,() => {
console.log("Started on PORT 3000");
})
There are some libraries like https://www.npmjs.com/package/socks or https://github.com/mattcg/socks5-https-client but it can only do get requests and also without handle 301 redirect response.
It seems that it's very easy and simple task but I still can not find the turnkey solution. Is there some or at least some good libraries to convert post and get (put, delete) to socks5?

Getting started with parse server and node.js basics

I have installed bitnami parse server from the AWS market place to provide the backend for an iOS app. In the iOS app the API is configured under http://myURL.com/parse and when I go to what I thought would be the homepage, http://myURL.com, it instead redirects me to the parse dashboard located at http://myURL.com/apps. I would like to have http://myURL.com serve a homepage for my app instead of redirecting to the parse dashboard so that a web application can be constructed that shares the same data the app uses. This is my first project using node.js so I am hoping someone could point me in the right direction on a couple of topics. My previous web application work was always on a LAMP stack so I am curious:
Am I correct to assume that the parse backend that iOS uses can also be the backend for a web application accessed through a browser?
When I analyze the code in server.js at /home/bitnami/apps/parse/htdocs I don't see a function that is redirecting to myURL.com/apps, is there a different area I should be focussed on to understand how myURL.com gets redirected to the apps folder?
I noticed that a folder exists at /home/binami/apps/rockmongo with installation instructions of php scripts, can my AWS instance run php AND the node.js or will installing a LAMP stack interfere with the node.js stack?
I am sure there is some great documentation and/or tutorials on this, can you help me get started by providing the correct way to phrase google searches or even better any links to tutorials themselves?
For context my iOS lets users log on and lets them upload images to parse server classes, I simply want to let the users log on and upload an image from a web browser using the same parse server which has the user/file classes.
For Reference below is the server.js which appears to somehow be directing requests from myURL.com to myURL.com/apps:
require('dotenv').config();
var express = require('express');
var ParseServer = require('parse-server').ParseServer;
var app = express();
// Specify the connection string for your mongodb database
// and the location to your Parse cloud code
var api = new ParseServer({
databaseURI: "mongodb://root:9dh********#127.0.0.1:27017/bitnami_parse",
cloud: "./node_modules/parse-server/lib/cloud-code/Parse.Cloud.js",
appId: "19defd7********",
masterKey: "cd8********",
fileKey: "3bce6********",
serverURL: "http://54.**.**.**:80/parse",
filesAdapter: {
"module": "#parse/s3-files-adapter",
"options": {
"bucket": process.env.S3_BUCKET,
}
},
});
// Serve the Parse API on the /parse URL prefix
app.use('/parse', api);
var port = 1337;
app.listen(port, function() {
console.log('parse-server running on port ' + port);
});
//Parse Dashboard
var ParseDashboard = require('parse-dashboard');
var dashboard = new ParseDashboard({
apps: [
{
appName: "My Bitnami Parse API",
appId: "19defd7********",
masterKey: "cd8d*******",
fileKey: "3bce6********",
production: true,
serverURL: "http://54.**.**.**:80/parse"
}
],
users: [
{
user: process.env.ADMIN_USER,
pass: process.env.ADMIN_PASSWORD
}
], useEncryptedPasswords: true
});
var allowInsecureHTTP = true;
// Serve the Parse Dashboard on the /parsedashboard URL prefix
app.use('/', dashboard);
var portdash = 4040;
app.listen(portdash, function() {
console.log('parse-dashboard running on port ' + portdash);
});
Mount point for Parse Dashboard is definded in this line:
app.use('/', dashboard);
When you want to use a separate mount point for dashboard you can do this:
app.use('/dashboard', dashboard);
After changing if you hit http://myURL.com/dashboard it will load the dashboard in /dashboard/apps. '/apps' endpoint is handled by parse dashboard itself.
Now if you want to load your website in root route (/) or the http://myURL.com, you need to create another route (assuming you want to serve a static site for now)
app.use('/public', express.static(path.join(__dirname, '/public'), {
etag: true
}));
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, '/public/index.html'));
});
To serve a static site you need to create a folder from where you will server the static site. In this case, I created a folder named as public and place all of my html,css,js there. Now I need to specify the static folder in express. That's what I did in the first line. After that, I simply serve the index.html by creating a 'GET' route.
You can do a lot of other things too like creating APIs or serve a dynamic website as well as using parse server. But to do that you must understand express framework with nodejs first.
Update:
Parse API and Dashboard are two separate things. You can run only parse-server without dashboard and vice-versa. In your code, you mount the parse-server in /parse endpoint. Look at this line
app.use('/parse', api);
So now the parse-server is available in /parse endpoint. You can change it to anything. Make separate endpoints for both parse-server and dashboard.

Node express-http-proxy not routing request to server

I am trying to create and express server that reverse proxies to multiple applications. What I am running in to is that when I go to one of the routes the request never makes it to the server. Here are some code snippets of what I am doing:
let app = express();
app.use('/app2', express.static(__dirname + '/build', {
setHeaders: (res, req, path) => {
console.log(path);
metrics.httpRequestDurationMicroseconds // handles http_request_duration_ms Duration of HTTP requests in ms
.labels(req, path, res.statusCode)
.observe(10)
}
}));
When I go to localhost:5000/app2 it loads fine. Here is my proxy server:
proxyApp.use('/app2', proxy('http://localhost:5000/app2' ) );
proxyApp.use('/', proxy('http://my-site.com/'));
I am running it on port 5001. When i go to localhost:5001 my-site.com loads as expected. When I go to localhost:5001/app2 I get nothing and i see no traffic on the server.
For a little more context, I originally had app2 being served at / instead of /app2 and then I was able to make my proxy server load app2. But when I changed app2 to serve static content at /app2 it started breaking.
Anyone have any ideas on how to make this work or what is going on? It looks like the proxy wants to always send requests to / instead of /app2 no matter what I put in.
I am using express-http-proxy:1.4.0 and express:4.16.4
Any help is appreciated.
Try to use proxyReqPathResolver option
app.use('/app2', proxy("http://localhost:5000", {
proxyReqPathResolver: function (req) {
return "/app2"
},
}

Should I use express static dirname or use Node.js as a remote server?

My Node.js folders hirarchy looks like the next image:
My folders hirarchy
While app.js it's the Node.js main file, routes it's the Node.js routes and src it's the client public html files.
This is the code in app.js:
var express = require('express');
var app = express();
var server = require('http').createServer(app);
global.io = require('socket.io').listen(server);
var compression = require('compression');
var helmet = require('helmet');
var session = require('express-session');
var bodyParser = require('body-parser');
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
app.use(express.static(__dirname + '/src'));
app.use(helmet());
app.use(compression());
app.use('/rides', require('./routes/ridesServer'));
app.use('/user', require('./routes/userServer'));
app.use('/offers', require('./routes/offersServer'));
app.use('/notifications', require('./routes/notificationsServer'));
server.listen("8080", function() {
console.log("Connected to db and listening on port 8080");
});
This is another API in routes/userServer.js file:
router.post('/verifytoken', function(req, res, next) {
// some functions here
});
And this another HTTP REQUEST I am doing from client side, in page: ride.js:
$.ajax({
method: "POST",
headers: {
"Content-Type": "application/json"
},
url: "user/verifytoken",
data: JSON.stringify(something),
success: function(response) {
// some code
},
error: function(error) {
// some code
}
});
As you can see, client files and Node.js server files are on the same server, and Node.js serves those static files via this command:
app.use(express.static(__dirname + '/src'));
I think, that it should be avoided, and there is a better way!
If you are a Node.js expert and familier with best practices, please, tell me if the next method of working is correct, if it does not, please correct me:
I thought about putting static files on public_html directory
and Node.js files in server directory which is under public_html directory.
Then run pm2 start app.js --watch or, node app.js on the app.js which is located in server directory, and not in public_html.
In result, index.html file will be served as just as another static file without any relation to Node.js server, and Node.js will be in its own folder, not dealing with any kind of client the side.
In other words, seperate Node.js and static files and put Node.js files as a sub directory and not main directory.
Then the HTTP REQUEST will be looking like this:
$.ajax({
method: "POST",
headers: {
"Content-Type": "application/json"
},
url: "server/user/verifytoken",
data: JSON.stringify(something),
success: function(response) {
// some code
},
error: function(error) {
// some code
}
});
Please note that I have added SERVER directory.
Furthermore, I can exchange the
url: "server/user/verifytoken",
to an IP from a remote app (like Ionic):
url: "123.123.123.123:443/server/user/verifytoken",
And then my HTTP REQUESTS will be served via HTTPS (because I am sending for port 443), I can create multiple apps on the same server and I have no struggles with any Node.js express static folders.
What do you think?
Thanks!
First let me say I'm not an expert. But I have 3 years of continuous development of Node.js based solutions.
In the past I have created solutions mixing client side code and server side code on the same project and it has work. At least for a while. But in the long run is a bad idea for many possible reasons. Some of them are:
Client side code and server side code may require different processes to produce working code. For example client side code may require trans compiling from ES6 to more compatible ES5 using something as gulp or Webpack. This is normally not the case for server side code because the runtime is more targeted.
Mixing client side code and an API server may prevent you from horizontally scaling one of them without the other.
This is like a mono repo. And having a mono repo without a CI process tailor for this scenario may produce very long development times.
What we currently do at my work is as follow:
Create a separated API server project. This way you can concentrate on developing a good API while working on this specific project. Let cross-cutting concerns (like authentication) outside the API server.
Create a separated project for your client side code (SPA maybe). Set your dev environment to proxy API requests to a running API server (may be running locally).
Create a separated project for the deployment of the entire solution. This project will put together the serving of the client code, proxying requests to the API and implementing cross-cutting concerns like authentication, etc.
Having your code separated in this way makes easy developing each pieces and fast evolution. But it may introduce some complexities:
This multi-project structure require you to be able to trigger testing the hole product each time one of the project changes.
It surface the need of integration testing
Some other considerations are:
API server and Website server may run on the same machine but in different ports.
You may secure your API server using SSL (on node using the standard https module) but notice that in all cases you need another actor in front of the API server (a website proxying requests to the actual API server of a API gateway that implement cross-cutting concerns like authentication, rate limiting, etc). In the past I pose the same question you have made yourself regarding the apropriate of using SSL in this scenario and the answer is here. My answer is: depends on the deployment conditions.

How to combine two Node.js App server together.

I have two apps. which current run in two different ports.
script1.js:
var express = require('express'),
app = require('express').createServer(
express.cookieParser(),
// Parses x-www-form-urlencoded request bodies (and json)
express.bodyParser()
)
;
app.get('/s1/output', function(sReq, sRes){
// set cookie
sRes.send('<div>Out from 1!</div>');
});
app.listen(3000);
and here is script2.js
var express = require('express'),
app = require('express').createServer(
express.cookieParser(),
// Parses x-www-form-urlencoded request bodies (and json)
express.bodyParser()
)
;
app.get('/s2/output', function(sReq, sRes){
// set cookie
sRes.send('<div>Out from 2!</div>');
});
app.listen(3001);
ok.. it runs separately on two different ports and have no problem.
Now. the story is that, I can only use port 80 for production. System Admin doesn't want to open 3000 nor other ports.
Instead of merging code. (in fact, my real code is a lot. and have different config settings for script1 and script2), what can I do to make both of them on port 80? but calling /s1/output will go to script1, and /s2/output will go to script2?
I am thinking about having another scripts. script80.js that runs on port 80.
and it require both script1, and script2.
But, the question is, what should I export from script 1 and script2? should I:
define all get / post methods, and then,
module.exports.app =app?
and in script80.js, should I do soemthing like that:
app.get('/s1/*', function (res, req)) {
// and what do now? app1(res) ?
}
mmmm
If you have domains or subdomains pointing to this server, you can also use the vhost middleware:
app.use(express.vhost('s1.domain.com', require('s1').app));
app.use(express.vhost('s2.domain.com', require('s2').app));
app.listen(80);
Complete example: https://github.com/expressjs/express/blob/master/examples/vhost/index.js
You can use nginx listening on port 80 and reverse proxying traffic to the 2 different express app servers behind it.
location /s1/ {
rewrite /s1(.*) $1 break;
proxy_pass http://localhost:3000;
}
location /s2/ {
rewrite /s2(.*) $1 break;
proxy_pass http://localhost:3001;
}
You could also code this by hand in express as you are asking about, but why reinvent the wheel?

Resources