Setting host and port when executing a .jar - javascript

I have an Angular + Spring Boot app that's deployed as a single .jar file, some .properties files and a bash script to execute the .jar depending on what properties we want to use.
Right now, my .ts classes have host and port set statically, e.g.:
const PATH: string = 'http://localhost:8080/(...)';
Is there a way to set them dynamically while executing the .jar?

The question is very broad and could not be answered definitely with such minimal information. I want to point some things though which you must consider in what ever solution you apply to this problem.
The backend which is a spring boot app, may as well run in localhost:8080 and that is fine. It is never however the case that an application backend is in the same machine as the Frontend. You have adopted angular as your frontend which means by default (if you haven't overridden this behavior) some static files would be served and executed in the browser of the end user.
So this in most cases means that the end user must know the ip-address or domain so that he can reach the machine that runs the backend server.
So the end situation you will have is backend running in for example localhost:8080 in some VM and frontend using a property like const PATH: string = 'http://my-backend-domain.com:8080/(...)'; so that an external user can reach the backend server from his browser.
In a very simplified scenario an effective solution would be to adapt your angular app with this answer then during deployment decide what is the domain for example where you are deploying the app like /my-backend-domain.com and go to assets/data/config.json and configure it there. This would not require any additional build of Frontend just a simple configuration.

There are many ways to do it
environmental variables
application arguments CommandLineRunner
configuration file

Related

Angular application to support both http and https

I built an application for demo purposes that uses an Angular front-end hosted on a web server (nginx). The nginx instance, in addition to serving the compiled JS code, also acts as a reverse proxy for an application server that the browser needs to connects to. The flow is such that when I deploy this nginx on an infrastructure with any IP/FQDN, I can connect to this IP/FQDN and subsequent calls to the application server happens against the same IP/FQDN. You can see the architecture and the flow in this diagram.
The way it works is that the JS code contains an endpoint that I configure in the environment.ts file which contains this:
export const environment = {
production: true,
envName: 'prod',
appserver_env: 'http://' + window.location.host
};
Every time the code needs to connect to the app server it uses the appserver_env variable that resolves to the same IP/FQDN it pulled the JS code from.
This works just fine if I deploy my application without any security (i.e. http). It doesn't work if my webserver only works with https. I can obviously change the environment.ts to specify https instead and that would work (in a secured environment) after recompiling the Angular code.
However, I am trying to figure out if there is an easy way to tell Angular that this configuration needs to be working with EITHER http or https depending on the deployment method I am using. This is a demo application that I want to use in the most flexible way.
Any suggestion? Thanks!

Parametrization of Angular application

I have an application that is comprised of an Angular front-end, an app layer and a DB layer. You can see the architecture in this image.
I am using an nginx instance to serve both the JS front-end bits to the client as well as to proxy requests from the client to the app layer. So let's say I deploy this nginx on a cloud VM with IP 18.1.1.1 (fake) I can point my browser to that IP, the client will download the JS code, and the JS code is configured, see here, to set the app server ip/fqdn to the same ip/fqdn I pointed my browser to download the ui.
At this point the nginx proxy configuration kicks in and forward all /api requests made by the JS code to a specific fqdn. Right now this is a specific FQDN just because I am deploying these components as containers and the nginx container always knows how to reach http://yelb-appserver:4567/api.
I would like now to create additional deployment methods and in particular I would like to host the Angular bits on an S3 bucket (or any other web server) and have the JS point directly to something like an API GW, a separate EC2 instance, a cloud load balancer, or anything that represents an IP/FQDN endpoint different from the IP/FQDN of the web server serving the JS files.
In this case I can no longer use the appserver_env: 'http://' + window.location.host that I have used here.
Since I would like to create a dynamic and repeatable deployment workflow (using cloudformation, or similar) I am wondering if there is a way to work with a single JS compiled artifact parametrizing the Angular code to point to the /api endpoint created at deployment time OR if my only option is, at every deployment, to 1) create/read the /api endpoint at deployment time, 2) programmatically customize the Angular code with the endpoint, 3) re-build the Angular app dynamically (now including the specific /api endpoint) and 4) finally deploy the web site with the JS code ad-hoc created with the custom /api endpoint for that specific application instance deployed.
Thanks.
Use environment variables and keep them in a config (like "environment.prod.ts" in your case), which will be given to a node process running your build. Your javascript angular code can use these variables, like for api endpoint, you can have process.env.API_ENDPOINT in you code wherever you need api endpoint. Now for supplying thses variables you can use something, as simple as, API_ENDPOINT='/api' npm run build or for more advanced approach, you can use Docker.

Where do I put front-end code in my backend project and how/when to run it?

The question is, say I have written a backend REST service using Python, and then some other guy wrote some frontend code in Angular JS. Is the typical workflow putting them into two separate folders and run them separately? So the process will look like below
python manage.py runserver
in Python colder and then probably
# in the angular2 folder
npm start
Or should I place all the JS code into some assets folder and when I start my server, all the JS code will run automatically with them? If so, how should I do it?
Another question related is, when is all the JS code sent to users’ browsers? If the app is a client-side rendering app, is the code sent to browser at the first time of server requesting? How does the server know it should package your JS code and ship it?
Q)The question is, say I have written a backend REST service using Python, and then some other guy wrote some frontend code in Angular JS. Is the typical workflow putting them into two separate folders and run them separately?
Both Angular and Python can be run differently as well as together.
You could choose to place the Angular files (which qualify for all practical purposes as public files) in the public (or related folder) depending on which framework you're using - Django, Flask, Web2py or so on.
You can also choose to run them independently as standalone apps.
Depends on your requirement. Honestly, there are so many ways to answer this question.
Q)Or should I place all the JS code into some assets folder and when I start my server, all the JS code will run automatically with them? If so, how should I do it?
If you place everything in your assets folder, then as soon as the home route or any other route is made a request for [from a browser] , the public folder passes on to the browser.
Although I'm not sure if it is the case with server side rendering.
If you're using Angular 1, I do not think it fits server side rendering although you could use some libraries out there.
Q)Another question related is, when is all the JS code sent to users’ browsers? If the app is a client-side rendering app, is the code sent to browser at the first time of server requesting? How does the server know it should package your JS code and ship it?
All the files in PUBLIC folder on the server are accessible by a browser.
All of your questions seem to essentially ask the same question.
There are many approaches to this problem.
If infrastructure management is difficult for you, than maybe it's easier to place them in the same server. You can create another directory and place your html that is served to browser with your JavaScript code.
In case you have a good pipeline (which I think it pays for it self) than having another server that serves your application is better. You can do more things without affecting your service, like caching etc. And your server that runs your service wont be busy serving assets as well.
I have a case where we run a node server, which serves the html and javascript to our users, because that way we can do server side rendering.enter link description here
The flow of code execution will be this : Once the browser of your user hits the server that is serving html and assets, it will download it locally and it will start with JavaScript execution (Parsing, Compiling and Executing). Your JavaScript app might do some API calls upon initialization or it might not, but your service will be executed only if frontend makes a request.
As for CORS it is irrelevant how you serve them, because you can keep them always in the same domain.

How can I use Node.js Offline/locally?

Maybe i'm misunderstanding how Node.js works but, I would like to use it just as a server backend for a web app, without it running as a service/listening a port.
I'm willing to hear ideas to better solve the issue, this app will only be available on our intranet.
Example of what i'm thinking :
backend server.js :
function connectDb(usr, pwrd){
//Some npm package code to connect to a db
return console.log("Sucessfully connected")
}
frontend javascript.js :
require("server.js")
$(".connect.button").on("click", function(e){
connectDb($(".connect.user").text(), $(".connect.pwrd").text())
})
There are two different aspects with your question and code example on which you could work to get a better understanding of the ecosystem.
Client / Server
When a client wants to get some resource from a server, it connects to a specific port on that server, on which the back-end application is "listening". That means, to be able to serve resources coming from a database, you must have a Node process listening to a port, fetching the requested resources from the database, and returning them. The perfect format for that kind of data exchange is JSON.
To get a better understanding of this process, you may want to try and write a simple Node app sending a piece of JSON over the network when it receives a request, and try to load it with an XHR in client code (for example with JQuery's AJAX method). Then, try and serve a dynamic piece of JSON coming from a database, with a query based on the request's content.
Module loading
require("server.js") only works in Node, and can't be used in JavaScript that is running in a client's browser (Well, at least for now. Maybe some kind of module loading could be normalised for browsers, but that's another debate.).
To use a script in a client browser, you have to include it in the loaded page with a <script> tag.
In node, you can load a script file with require. However, said script must declare what functions or variables are exposed to the scripts that require it. To achieve it, you must export these variables or function setting module.exports.
See this article to get some basic understanding, and this part of Node docs to master all the details of module loading. This is quite important, as this will help you structure your app and avoid strange bugs.
For one thing, node itself isn't a web server: it's a JS interpreter, which (among other things) can be used to write a web server. But node itself isn't a web server any more than Java is.
But if you want things to be able to connect to your node program, in order to do things like access a database, or serve a webpage, then, yeah, your program needs to be listening on some port on the machine it's running on.
Simply having your node program listening to a specific port on your machine doesn't mean that anyone else can access it; but that's really a networking question not a programming question.

Node JS REST API, now how do I serve HTML files?

So I did a REST Api in Node JS and now I have a blocker.
app.use('/api', router);
This code makes sure that every url is prefixed with api. Now what If I want to serve an HTML file when the path is just "/"? Should I create another "express" application? I'm just working in localhost right now and I have to do "node server.js" to launch the server. I can't really launch 2 servers at the same time, or can I? One for the api: server.js and one for the rest of the code: client.js (that's a bad name but whatever.). I'm confused on how I have to setup things...
Thanks you for the help.
You can see that you use your api routes to, most likely, serve JSON content. Well, using the same mechanism you can configure your router to serve any other kind of content for a particular route.
So, if you would like to serve some HTML content for the root of your application, let's say a Wiki page or documentation of you API, it is as simple as:
app.get('/', function(req, res){
res.render('index.html');
});
Of course, if you are just rendering a static html page, you might just as well configure a middleware to define where you place all your static content.
app.use(express.static(path.join(__dirname, 'www')));
Where www is the directory where you chose to put your index.html page.
Having said that, if what you built was a REST API, chances are that it is intended to be reused by multiple other applications, and therefore, it is customary to that the client applications are running independently of the REST API. Some client applications may not even be Web applications (i.e. Android, iOS, desktop apps, etc). So you should take that into account before thinking in developing a Web client within the same project.
But nothing prevents your from providing a default implementation of UI that consumes your REST API within the same project/server. And yes, it is possible to run more than one HTTP server serving different applications. There are considerations you might need to take into account if you use separate servers for your API (i.e. CORS).
If you decide to serve everything within the same application, you may want to make sure there is a clear decoupling in the design in a such a way that the client application consumes and uses the rest layer as if it was independent. You should isolate the routes for the REST layer from those used for your client in such a way that if, later on, you want to make the client APP run independently you would not have a problem with that.
How about something like express-namespace to help you organize your routes?

Categories

Resources