Mount Koajs app on top of Express - node.js

From koajs.com:
app.callback()
Return a callback function suitable for the http.createServer() method to handle a request. You may also use this callback function to mount your koa app in a Connect/Express app.
Now I have an Express app that already starts its own http server. How can I mount a koa app on top of this existing server, so that it shares the same port?
Would I include the koa app as an Express middlware? Do I still use app.callback() for that?

expressapp.use(koaapp.callback()) is fine. but remember, koaapp.callback() does not have a next, so there's no passing errors to the express app or skipping the koaapp once you use it.
it's better to keep them completely separate since their APIs are incompatible
var koaapp = koa()
var expressapp = express()
http.createServer(req, res) {
if (true) koaapp(req, res);
else expressapp(req, res);
})

Since you need a server instance in order to mount a middleware on a specific /prefix, it would be something like
var http = require('http');
var expressApp = require('express');
var koaApp = require('koa');
// ...
expressApp.use('/prefix', http.createServer(koaApp.callback()));

Related

express.Router() vs express() in express

As mentioned in express routing guide and this answer, we can create "mini-app" and use it from the main app. However I saw a code where it uses app instead of router in the module
app.js
var express = require('express');
var userRoutes = require('./routes/user');
var app = express();
app.use('/user', userRoutes);
module.exports = app;
routes/user.js
var express = require('express');
var app = express(); // not express.Router() !!
app.get('/:name', function(req, res) {
var userName = req.params.name;
res.render('user.jade', {
userName: userName
});
});
module.exports = app;
I assumed the correct usage in routes/user.js should be
router = express.Router()
instead of
app = express()
but app = express() also works! what are the differences and why router = express.Router() is better?
When you are working with a server where there are many routes, it can be confusing to leave them in a Main file together. The let router = express.Router() option works differently than let app = express().
While the app returns an app object, router will return a small app fragment, similar to the app, where you will use logic to call them later on the Main.
The most important, about your question, is that a router, which is isolated, will not interfere with others in the application, being a single environment.
https://expressjs.com/en/api.html#router
A router object is an isolated instance of middleware and routes. You can think of it as a “mini-application,” capable only of performing middleware and routing functions. Every Express application has a built-in app router.
A router behaves like middleware itself, so you can use it as an argument to app.use() or as the argument to another router’s use() method.

Node.js / express / passport / saml - How to inspect the content of outgoing HTTP request to SAML Identity Provider?

I am a newbie in node.js, but I have a sample application written for node.js that shows the way of integration with specific Identity Provider (SAML). Using this sample app I am trying to inspect what is sent in the HTTP requests made from the node.js backend to the remote IdP. Logging the request headers and body by writing to the console.log would be enough for me. Monitoring the network traffic with some tool like Fiddler is not an option for me, because I cannot run it locally, I need to have the app exposed and I have it deployed to Heroku.
I've tried morgan, but it only intercepts the INCOMING requests. I've also tried global-request-logger, but for some reason it does not inject itself into the express framework and passport. Seems like passport is not using the standard modules for HTTP requests?
The question is: what I need to use to be able to log the content of the HTTP requests made by passport during the .authenticate() call? Is there any flag that I am able to set in passport to enable HTTP logging? Or should I rather do it in express? Or maybe some other package would provide the functionality I need?
EDIT:
My original question was marked as possible duplicate of how to log OUTGOING https requests from node within webstorm
But actually I have already seen that topic and I've tried to setup a hook to http module, it was done this way:
'use strict';
// Setup express.js application:
var express = require('express');
var app = express();
// Patch "http" module with outgoing request logging:
var http = require('http');
const originalRequest = http.request;
http.request = function wrapMethodRequest(req) {
console.log('EXTERNAL OUTGOING REQUEST LOGGING:');
console.log(req.host, req.body);
return originalRequest.apply(this, arguments);
}
This approach was not working. As already said in the original question, it seems that passport does not use standard http module? Or did I something wrong with the code above?
As already mentioned in the original question, I was also trying to handle it via global-request-logger package (which as explained in the possible duplicated post, uses the same technique). The code for that was:
'use strict';
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var passport = require('passport');
var SamlStrategy = require('passport-saml').Strategy;
app.use(bodyParser.urlencoded({ extended: false }));
var globalLog = require('global-request-logger');
globalLog.initialize();
globalLog.on('success', (req, res) => {
console.log('HTTP(S) CALLOUT SUCCESS');
console.log('REQUEST: ', req);
console.log('RESPONSE: ', res);
});
globalLog.on('error', (req, res) => {
console.log('HTTP(S) CALLOUT ERROR');
console.log('REQUEST: ', req);
console.log('RESPONSE: ', res);
});
...

Express middleware on folder mounted app

I have an Express.js application running on https://mydomain.tld/folder. It sets up the route middlewares with
app.use('/path', middleware)
but only the one for the '/' path is working properly. I'm guessing this is because Express is looking for requests on https://mydomain.tld/path instead of on https://mydomain.tld/folder/path.
How can I get Express to process the requests for https://mydomain.tld/folder/path (preferably without having to hard code the path)?
Using a router:
// myRouter.js
var express = require('express')
var router = express.Router()
router.get('/path', middleware)
// other routes...
module.exports = router
Now you can use your router with the relative path you want:
var myRouter = require('./myRouter')
app.use('/folder', myRouter)

NodeJs + Unable to access localStorage inside routes.js

In my NODEjs ( using Express ) application, I want to use Country Code inside routes.js but I am unable to access localstorage inside the routes.js
Please provide some solution.
LocalStorage is only available in browsers on the Window object.
The Window object is not available server side.
MDN
Following your comment, you could implement a route in your express application which takes the IP as part of the body.
For this to work you will need body-parser middleware. Example application:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var server;
app.use(bodyParser.json());
app.get('/api/ip', function (req, res) {
res.send(req.body.ip);
});
server = app.listen(3000);
This would return the posted IP.

Manually injecting express app via `http.createServer` proxy

I am currently authoring a component for a users sites which adds a number of resources to their server. For my part, I am wanting to use express, but the user could be using express themselves or some other web framework.
Because I want this to just work out of the box, I was attempting to setup my express pipeline via proxying http.createServer. Injecting the pipeline this way seems to work reasonably well in cases where I handle the request, but it fails in cases where I let it fall through and execute the users callback (specifically, it says that the response headers have been sent already).
Here is the sample I am working on. Any ideas?
var http = require('http');
var express = require('express');
var setupProxy = function setupProxy() {
var app = buildApp();
var oldCreateServer = http.createServer;
http.createServer = function(callback) {
return oldCreateServer(function(req, res) {n
app.apply(this, arguments);
if (!res.finished) {
callback.apply(this, arguments);
}
});
};
};
var buildApp = function buildApp() {
var app = express();
app.use('/test', function(req, res) {
res.send('Hello World');
});
return app;
};
I suspect your express handling creates a default 404 response when it doesn't match any of your routes. So, that would be the cause of the headers already sent issue when you are not handling it, but trying to pass it on.
So, I think you need your own 404 handler that writes nothing to the request (e.g. does nothing), but keeps Express from handling it.
Or, another possibility would be to call the user's server callback from your express 404 handler and not elsewhere.

Resources