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

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.

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!

Azure Easy API - can't find documentation for getTable('tableName').insert

I'm using Azure Easy API on my app service. I'm experimenting a little bit and I can't find proper documentation for this stuff.
When I made a new Easy API, the comments at the top said
// Use "request.service" to access features of your mobile service, e.g.:
// var tables = request.service.tables;
So I went from there to finding out I can add to any of my tables using request.service.tables.getTable('tableName').insert({columnName: value})
I expected .insert() to return a promise, but it doesn't. In fact, it doesn't seem to return anything at all. But I'd imagine it's asynchronous.
And since it doesn't return a promise, my next bet was that it takes a callback, but when I tried .insert({columnName: value}, function(r){response.send(r.toString()}), the entire api just failed to work at all.
How am I supposed to use this .insert function?
And where can I find the documentation to learn this information on my own? Googling is getting me nowhere.
Here is a code sample you can use in your Easy API for inserting a record into the table.
module.exports = {
"get": function (req, res, next) {
req.azureMobile.tables('tableName')
.insert({columnName: 'value'})
.then(() => res.status(201).send('Success!'))
.catch(next);
}
}
The app.js file would have the following content.
// ----------------------------------------------------------------------------
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
// ----------------------------------------------------------------------------
// This is a base-level Azure Mobile App SDK.
var express = require('express'),
azureMobileApps = require('azure-mobile-apps');
// Set up a standard Express app
var app = express();
// If you are producing a combined Web + Mobile app, then you should handle
// anything like logging, registering middleware, etc. here
// Configuration of the Azure Mobile Apps can be done via an object, the
// environment or an auxiliary file. For more information, see
// http://azure.github.io/azure-mobile-apps-node/global.html#configuration
var mobileApp = azureMobileApps({
// Explicitly enable the Azure Mobile Apps home page
homePage: true,
// Explicitly enable swagger support. UI support is enabled by
// installing the swagger-ui npm module.
swagger: true
});
// Import the files from the tables directory to configure the /tables endpoint
mobileApp.tables.import('./tables');
// Import the files from the api directory to configure the /api endpoint
mobileApp.api.import('./api');
// Initialize the database before listening for incoming requests
// The tables.initialize() method does the initialization asynchronously
// and returns a Promise.
mobileApp.tables.initialize()
.then(function () {
app.use(mobileApp); // Register the Azure Mobile Apps middleware
app.listen(process.env.PORT || 3000); // Listen for requests
});

Generate Swagger Document for existing NodeJS server

According to Swagger website, there are two approaches: Bottom-up and Top-down.
I have an existing NodeJS server that I'd like to deploy in the Azure enviroment, that require a swagger document (API APP).
Does anyone know a tool for generating the swagger using the code? Even better if you could point a tutorial. I couldn't find it.
Question is a bit old but still. It is possible to generate completely automatically Swagger (OpenAPI) specification just by embedding analysis middleware like this: https://github.com/mpashkovskiy/express-oas-generator
const express = require('express');
const expressOasGenerator = require('express-oas-generator');
let app = express();
expressOasGenerator.init(app, {});
run some client or REST API tests agains your service and open http://host:port/api-docs
It’s not difficult to integrate Swagger in exist express applications following this tutorial.
Generally, we can follow these steps:
Add the dependencies in our package.json, and run npm install to install them. The dependencies should be:
"dependencies": {
"swagger-node-express": "~2.0",
"minimist": "*",
"body-parser": "1.9.x",
...
}
Download the zip project of Swagger-UI, copy the dist folder into the root directory of our project, the directory should almost like:
Introduce the dependencies at the beginnng of app.js:
var argv = require('minimist')(process.argv.slice(2));
var swagger = require("swagger-node-express");
var bodyParser = require( 'body-parser' );
Set up a subpath for swagger doc:
var subpath = express();
app.use(bodyParser());
app.use("/v1", subpath);
swagger.setAppHandler(subpath);
Make sure that /dist is able to serve static files in express:
app.use(express.static('dist'));
Set the info for API:
swagger.setApiInfo({
title: "example API",
description: "API to do something, manage something...",
termsOfServiceUrl: "",
contact: "yourname#something.com",
license: "",
licenseUrl: ""
});
Introduce /dist/index.html for swagger UI:
subpath.get('/', function (req, res) {
res.sendfile(__dirname + '/dist/index.html');
});
Complete the swagger configurations:
swagger.configureSwaggerPaths('', 'api-docs', '');
var domain = 'localhost';
if(argv.domain !== undefined)
domain = argv.domain;
else
console.log('No --domain=xxx specified, taking default hostname "localhost".');
var applicationUrl = 'http://' + domain;
swagger.configure(applicationUrl, '1.0.0');
Configure doc file dependence in /dist/index.html:
if (url && url.length > 1) {
url = decodeURIComponent(url[1]);
} else {
<del>url = "http://petstore.swagger.io/v2/swagger.json";</del>
url = "/api-docs.json";
}
Create api-docs.json file with the info of your APIs, put it in the dist folder.
Run the Express app on local, visit http://localhost:3000/v1, we can check the swagger doc.
Here is my test sample repo for your reference.
To my knowledge, your options are:
Using swagger-node-express which is very cumbersome in my opinion.
Writing up the swagger document manually yourself with the help of swagger editor as suggested in this SO Answer
If you go for option 2, you could use swagger-ui-express to generate the swagger-ui
A lot of developers are still having this problem so I built an open-source tool to help -- the tool is kind of like Git for APIs. It works by running a proxy while you're developing the API, analyzing the traffic, and updating the spec for you as the API's behavior changes. Hopefully, the workflow saves you a lot of time: https://github.com/opticdev/optic
Most alternatives require some sort of API specification through Json, Yaml or even embedded in JSdocs. On the other hand there are some runtime analyzers intercepting HTTP requests and building that specification on-demand.
express-sitemap-html follows a different approach inspecting the express object and its routes at setup time. Thus it always provides an up-to-date swagger UI for installed routes on existing express instance.
const sitemap = require('express-sitemap-html')
...
sitemap.swagger('Title', app) // app is an express instance
Then get swagger UI from your domain /api-docs.

Angular Frontend with JAX-RS backend

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.

Node.js Express: require/use one app within another

I'm facing the following situation. In order to further modulize my software development, I've written a few standard modules stand alone. Think for instance of an login module based upon Express and Passport, allowing users to login with all kinds of social services. The module also contains UI for user management, login, registration, profile, etc.
Now, the thing I'm trying to do is to just drop the Auth app folder (containing the express app, all it's routes, views, models, settings and dependecies) into another Express app (for instance, a CMS) and then load it with something like require('./lib/auth/app.js'). I know this is possible, take a look at Kue.
How would I go about doing this? And how do I manage namespacing problems? I could of cours append /auth/ to each route, but I can imagine the settings (app.use()'s) and public folder would conflict with the 'parent' app.js' settings and public folder.
Thanks in advance,
Fabian
Think I found my answer. So, I found this question, and this one. Guess my terminology was off.
I solved my problem by doing a few things. First of all, I changed all routes and url's to be "namespaced" (not really, but this does the job). All routes now have /auth/ in front of them. I did the same to all links, so that's all working.
Next, I removed the server part from my app.js. So, in stead of doing:
require('http').createServer(app).listen(app.get('port'));
I just do:
module.exports = app;
And I add some custom methods to the app object:
app.isLoggedIn = auth.isLoggedIn;
app.notLoggedIn = auth.notLoggedIn;
Then, in my root app, I just do the following to load the auth app in. Routing, public files, and all other stuff happens magically. pretty cool.
var auth = require('./vendor/auth/app');
var app = express();
app.configure(function() {
app.use(auth); // use our auth app
// do a lot of root-app related stuff...
});
Things still to do:
My auth app uses some session stuff. According to the second link, if I understand correctly, the app.use(session...) stuff in my auth app gets overridden by app.use. Also, I want to define an EJS helper to generate my urls (something like site_url('/facebook/callback') which then points to /auth/facebook/callback). Finally, I need to include settings from my root app. I'm thinking of wrapping my entire app.js (in auth) in a function, to which I pass a config object. Like this:
module.exports = function(config) {
var app = express();
app.set('config', config);
// various app settings, routes, etc
// return app so it's available in my root.
return app;
}
I hope this helps, if you need a bit more information I'll see if I can post some code to a gist. just let me know!

Resources