Angular Frontend with JAX-RS backend - iis

I have a RESTful Java backend which I made using Jersey, a JAX-RS implementation. This backend is running on a glassfish server on port 8084. I've also made some HTML5/JS/AJAX pages which display the data so I know my REST implementation is working.
I'm trying to develop an HTML5 / JS frontend for this application using the Angular.js framework but I'm experiencing some trouble. I have managed to develop some small webapps in angular which I'm running on Microsoft's IIS on port 80.
Unfortunately, there appears to be a problem with the communication between the two applications. Since I'm new to Angular, I'm unsure if I made a mistake in my frontend code, or if I'm experiencing CORS problems. I already tried running the backend on a Tomcat 7 with the CORS filter but that didn't solve anything.
My angular code looks like this:
services.js
var serviceModule = angular.module('ServiceModule', ['ngResource']);
serviceModule.factory('NodeService', function($resource) {
var NodeService = $resource('http://localhost:port/HtmlJerseyJava/service/node/get/3',{},
{
'get' : { method: 'GET',params:{port:':8084'}}
}
)
return NodeService;
});
controllers.js
function NodeDetailCtrl($scope, NodeService){
var node3 = NodeService.get();
$scope.data = JSON.stringify(node3) ;
}
I hardcoded the ID 3 for now, because I also need to figure out how I can pass the value of an input field from the view to the controller and then to the service. Eventually, the 3 in the service url would be replaced by a variable :nodeId
Any help would be greatly appreciated.

Try the following simplified code:
app.js (for test purposes I suggest you to put functions in one js file)
var serviceModule = angular.module('ServiceModule', ['ngResource']);
serviceModule.factory('Node', function($resource) {
return $resource('http://localhost:port/HtmlJerseyJava/service/node/get/3',{port:':8084'},
{
get {method:'GET'}
});
});
serviceModule.controller('NodeDetailCtrl', function($scope, Node){
$scope.data = Node.get();
}
It would be interesting to now what JSON data your client gets from the REST call.
Greets Marc

I found the solution. There were several steps to fix this problem:
Add a CORS filter to the Jersey servlet on Glassfish.
Upgrade the Angular version to 1.1.x (currently still unstable)
Set a custom header in your resource.
Enjoy a working application.
Big thanks Marcbaur for helping me out here.

Related

node Vue.js different code scenario if run in dev mode

I have Vue.JS front app with nodeJS backend based on expressJS. ExpressJS also used as web server for statically built Vue.JS app
Front app communicates with express backend via rest and websocket. It uses url host from window.location instance and easily communicates with backend
In production mode, when built application in static expressJS server area, everything work perfect
In dev mode, Vue use it's own web server, and backend urls based on window.location are incorrect because no expresJS on same host and port.
So my question is it possible change some code blocks if running in dev mode ?
Like something this :
if( devmode)
{
const url = "http://somebackendhost/rest"
}
else {
const url = location.host ....
}
}
I will assume you are developing your Vue app using Vue CLI
Changing app behavior depending on environment
In Vue CLI you can use Environment Variables
if(process.env.NODE_ENV === "development")
{
}
This works thanks to Webpack's Define plugin and big advantage is that process.env.NODE_ENV is replaced at build time by the real value. So in production build Webpack will see just if("production" === "development") {} and happily removes the code in optimization phase because it knows this can never be true
Better solution
But I would not use this approach for your problem. Using different API server (not same as the server used for serving Vue SPA) can easily lead to CORS problems
Exactly for this use case, Vue CLI (and Webpack Dev server used under the hood) supports proxying
vue.config.js
module.exports = {
devServer: {
proxy: {
'^/api': {
target: 'http://localhost:58300/',
ws: true, // websockets
changeOrigin: true,
}
}
},
},
This config makes Vue Dev server to proxy any request to /api to other server running at http://localhost:58300/ (your node/express app) and change the origin (so browser thinks response came from the dev server)
All of this can be done without Vue CLI but you will need to set it up by yourself in Webpack config...
The problem
You can't access this information from your browser.
But there are three solutions:
Solution #1
On compilation time create a variable in code which defines devmode (const devmode = true;)
Solution #2
Because your bundler can minify your variable names or changing the scope for security reasons, may be the situation where you can't access it.
So second solution is to define devmode in your localStorage.
Solution #3
Third solution is almost the best.
If you are developing, you are probably accessing your web app via localhost.
location.hostname will return the name of host, so you can make something like:
const devmode = location.hotname == 'localhost';
Best solution
Do not do this. Develop a fully working web app using local REST API and define the URL of REST API in some variable, so when you are preparing your production app, you or compiler just changes the URL adress variable in code of your REST API.
Why is this the best solution?
Because it do not impacts your end-user's performance and they will be loading less code, which is the best practise.
Post Scriptum
Don't forget to remove all devmode codepaths when compiling production version!

How do I access a Azure application setting from inside an Aurelia application?

I have a Aurelia app that I host in an Azure app service. I would like to configure the api endpoint that Aurelia connects to by defining it in a Application Setting. How can I read that setting inside Aurelia?
As the other answers and comments also mentioned, Aurelia runs as a clientside application and has no knowledge of backend-driven applications. So the concept of something like the web.config or appsettings.json is not available here without some serious hacks. You don't want to go there.
That being said, of course you can! :) You can pretty much define any settings file you like, similar to the concept of appsettings.json of ASP.NET (Core) apps but then in Aurelia.
A great example for this is the Aurelia open source plugin Aurelia-Configuration.
Simple instructions are that your first start by adding any .json file you like (like config.json) to your project. Next, register it in your Aurelia startup:
export function configure(aurelia) {
aurelia.use
.standardConfiguration()
.developmentLogging()
.plugin('aurelia-configuration'); // <-- there you go
aurelia.start().then(a => a.setRoot());
}
Finally, just read out the values using AureliaConfiguration. The sample below illustrates it with dependency injection:
import {inject} from 'aurelia-framework';
import {AureliaConfiguration} from 'aurelia-configuration';
#inject(AureliaConfiguration)
export class MyComponent {
constructor(config) {
this.config = config;
this.config.get('endpoint');
}
}
The README explains it all.
Note: I'm not affiliated with the aurelia-configuration plugin, but just a fan of it.
Isn't Aurelia a JavaScript client framework, e.g. all-in-browser no backend? Application Settings is a server side thing (key-value store) in App Service. No backend, no app settings.
Consider this restify minimal backend that returns Application Settings by calling /settings/{app-setting-name}:
var restify = require('restify');
function respond(req, res, next) {
// Returns app setting value.
// Provides zero input validation,
// DO NOT COPY PASTE INTO PROD,
// ALL YOUR BASE WILL BELONG TO US.
res.send(process.env[req.params.setting]);
next();
}
var server = restify.createServer();
server.get('/settings/:setting', respond);
server.head('/settings/:setting', respond);
server.listen(process.env.PORT || 3000, function() {
console.log('restify listening...');
});
Hope this all makes more sense now.

Explain the service.js in AngularJS

I'm quite new to AngularJS and NodeJS. I'm trying to develop an app using MEAN stack. I just looked through the sample code in the mean.io boilerplate. I created my own app referring the sample app. I'm trying to submit the AngularJS front end and expecting it to call NodeJs server side but it isn't working. I think service.js is messing up something. Here is the service code of sample app. Can any one explain what this code does with respect to Angular client side and NodeJS Server side.
'use strict';
//Articles service used for articles REST endpoint
angular.module('mean.articles').factory('Articles', ['$resource', function($resource) {
return $resource('articles/:articleId', {
articleId: '#_id'
}, {
update: {
method: 'PUT'
}
});
}]);
It creates a new factory in angular called Articles. The Articles factory has the $resource service injected. The $resource object is used to setup an object for communicating with a RESTful service, in this case "articles/:articleId" the articleId will be pulled from the _id of the resource objects that are returned from queries using this $resource. When you call to update on one of the resources it will use the PUT HTTP Verb.
By itself this just defines the factory but doesn't actually make any calls you would need to inject this and use it somewhere like Articles.query();
From the docs
If the parameter value is prefixed with # then the value of that
parameter is extracted from the data object (useful for non-GET
operations).

build multiple layer restful API in node.js express

I am using node.js express to build simple rest API, I had built a API like
app.get('/sites/:site/:building/:floor',function(req,res){
var building = req.params.building, floor = req.params.floor, site = req.params.site;
console.log('query site ',site,building, floor);
.....
}
when client did the AJAX request in angular.js
$http.get('/sites/london')
.success(function(data) {
}).error(function(data, status, headers, config) {
});
the server doesn't respond to this kind of URL, unless I changed the express API to
app.get('sites/:site',function(){})
app.get('sites/:site/:building',function(){})
app.get('sites/:site/:building/:floor',function(){})
But the way above is too tedious so I wonder if it is possible to build API in one sentence app.get('sites/:site/:building/:floor',function(){})
The following stackoverflow answer should help you out. But to answer your question, the below should work
app.get('sites/:site?/:building?/:floor?',function(){})

CORS between AngularJS and Java Jersey Rest

I have a Java Webapplication using jersey rest which gets deployed on a local tomcat server.
This application is developed and tested within eclipse IDE.
Now in aptana IDE I have a AngularJS webapp which should connecct (using REST) to the jersey webapplication.
What steps do I have to make to establish the connection? Out of the box its not running because of the different contexts.
My current angularJS call:
WinesApp.factory('Wine', function ($resource) {
return $resource('/WinesApp/rest/wines/:wineId', {}, {
update: {method:'PUT'},
query: {method:'GET', isArray:false}
});
});
Which should become somethign like:
WinesApp.factory('Wine', function ($resource) {
return $resource('http://localhost:port/WinesApp/rest/wines/:wineId', {port:':8080'}, {
update: {method:'PUT'},
query: {method:'GET', isArray:false}
});
});
Greets
Marc
For CORS to work you need to send the appropriate headers from the server: for Jersey, see for exmaple Java/Jersey: A CORS-Compliant REST API. Then you simply call it from JavaScript like you wrote (while not strictly RESTful, it's easier to restrict your API to use GET and POST requests only, no PUT and DELETE). Finally, the curl command line utility comes in handy to test the server.

Resources