Difference between initating an express object in nodejs? - node.js

I can use express in two ways, that is I can initialize it in two ways:
var app = express(); or var app = new express();
From the looks of things, both are calling a constructor, so is there really any difference between the two, I'm mainly asking performance wise, is there really any difference, because I seemed to have experienced none.
If there is no real difference how come every tutorial I've seen does it the first way and not the second way, because the second one seems to be clearer.

In this case calling express() as a function is more correct.
https://github.com/visionmedia/express/blob/8a1e865e37016f279d957f04117007c36ac195e3/lib/express.js#L32
function createApplication() {
var app = connect();
utils.merge(app, proto);
app.request = { __proto__: req, app: app };
app.response = { __proto__: res, app: app };
app.init();
return app;
}
This is basically a factory function, not a constructor. Using the new keyword will create an unnecessary object that will immediately be discarded since the createApplication returns an object, the automatic this that the new keyword creates is discarded (this is just how the JavaScript language works).
So the answer is both versions work fine, but using new is unnecessary here.

Related

Please explain the basic server setup code of Express.js

In this code snippet:
Const express = require('express')
Const app = express();
/*Typeof express = function
Typeof app = function*/
app.get()
My question is: if app is a function then how can we use a dot operator with it to call get function, and if we are creating a object of function express then why didn't we use new keyword to create an object.
Secondly, module.exports exports the literals in object format then why we are getting typeof express here a function.
If I am wrong anywhere, please correct me.
In JavaScript functions are objects, so this is valid:
function x() {
console.log("this is x()");
}
x.y = function() {
console.log("this is x.y()");
}
x();
x.y();
Express and other JavaScript tools use this feature extensively.
If you're used to other languages where functions are just functions and not objects themselves this will seem extraordinarily strange.

Next.js with MySQL/Mongo backend

I have an existing Node.js/Express app which connects to 2 separate databases, it has a MySQL DB for all the relational and a MongoDB store for the non-relational vertical data.
It uses Sequelize and Mongoose and works absolutely swimmingly.
I've been looking at Next.js today and I'm pretty impressed, one of my pet peeves with React is actually how much bootstrapping there is and how much code it takes to achieve something simple. Next.js seems to solve some of those issues for me, so I'm willing to embrace it.
First issue - Is it possible to connect Next.js to existing DB's and read their objects directly in the view?
e.g. ./server.js:
const mongoDb = mongoose.connect(configDB.url); // MongoDB connection
const models = require('./models'); // Sequelize connection
app.prepare().then(() => {
server.use((req, res, next) => {
req.mongodb = mongoDb
req.mysqldb = models
// Logging req.mysqldb/req.mongodb at this point gives the correct result.
next()
});
server.get('*', (req, res) => {
return handle(req, res)
})
})
./pages/index.js:
Index.getInitialProps = async function(req) {
console.log(req.mongodb);
console.log(req.mysqldb)
// Example of what I want: req.mysqldb.users.findAll()....... to populate collection for this view
}
When the console statements are executed in the index.js page, they are logged as undefined.
Ideally I want to use the objects/ORM layer directly in the next.js templates, I do not want to have to call my own API internally, it seems like a huge waste of resources!
Any help, greatly appreciated.
Just for future reference. getInitialProps gets passed in an object with one of the keys being req. So you're meant to do something like the following instead
// add the curly braces around req
Index.getInitialProps = async function({ req }) {
// code
}
This is known as Function Parameter Destructuring and was introduced in ES6. What this accomplishes is similar to the following code
Index.getInitialProps = async function(_ref) {
var req = _ref.req;
}
Meaning, it takes the value of req of the object that gets passed and uses that value.
Well apparently by the time the request gets to the template it has changed a bit! Namely, it is nested within another request object.
req.req.mongodb and req.req.mysqldb both work fine :).

Extend View class in Express on Node.js

I'd like to override the View class in the Express framework, used in Node.js. I want to augment the lookup method, but I can't see a way to do this without altering the Express and App modules. I'd favour deriving from the Express framework, but I can't figure out a neat way to do this.
Any ideas?
Thanks
It seems to me you should be able to:
var View = require('express/lib/view');
// Keep reference to original lookup method
var _lookup = View.prototype.lookup;
// Override lookup method
View.prototype.lookup = function (path) {
// Your implementation here
};
Update:
Run this as a demonstration:
var View = require('express/lib/view');
var _lookup = View.prototype.lookup;
var express = require('express');
View.prototype.lookup = function (path) {
console.log('LOOKUP!!! ' + path);
return _lookup.call(this, path);
};
var app = express();
app.get('/', function (req, res) {
res.render('foo.jade');
});
app.listen(3000);
Run
node app & sleep 1 && curl localhost:3000
I hope this will demonstrate the viability of this way of overriding a method.
It depends on which version of Express you are using.
You can easily augment the view lookup code only if your app is using Express prior to version 3
Since Express 3.0 that's not doable anymore.
You can check one of my old related answers for sample code:
Multiple View paths on Node.js + Express

Updating the prototype of ServerRequest in an express/node configuration

I'd like to augment the prototype of the request object in expressjs, but it isn't clear where this request is defined? I think it is http.ServerRequest, but I can't find that definition either.
What's the right way to do the following...
http.ServerRequest.prototype.redirect = function(path) { }
Express itself adds it's utility methods to http.IncomingMessage.prototype, using this pattern in 2.*:
var http = require('http'),
req = http.IncomingMessage.prototype;
req.foo = function(bar) {
// Do cool stuff
};
And this pattern in 3.*:
var http = require('http');
var req = exports = module.exports = {
__proto__: http.IncomingMessage.prototype
};
It's wise to be careful with monkey patching though, as Vadim Baryshev warns in his answer.
Look at Connect framework and his middleware libs. Every middleware extends request and response objects after their creation. Changing prototype of core objects not the best way because this can lead to unpredictable behavior in other modules.

How to Make a Call to Koa.js App Instance for Unit Tests

I don't know how I'd term this maybe 'static call to a koa router'? Does that seem like the right wordage here for what I'm really trying to accomplish if you were to talk about it technically?
Anyway, I'm using koa-router and I'm coding unit tests (not integration tests). So I do not want to invoke .listen() on my koa app because of that reason...it would create an http server which now makes my test an integration tests.
Instead in my test I simply want to make a straight call to the app object instance and call a route and be able to return no results and check that I returned no results in the response.
How can you do that? I can't find an example and I've tried all sorts of pseudo code attemps agains the koa app object.
If you want to test the function that koa-router routes to then just perform a unit test on that function and leave the routing out of it.
To me it sounds like you've got a file such as app.js and it contains all your code. What you can do is create a router.js file to put you route bindings and a services.js file where you can put your application logic.
So for example app.js might look like:
var koa = require("koa");
var app = module.exports = koa();
var router = require('./router.js');
app.use(router.unsecured.middleware());
app.listen(3000);
And router.js might look like:
var router = require("koa-router");
var service = require("./services.js");
var unsecured = module.exports.unsecured = new router();
unsecured.post('/account/signin', service.signinUser);
unsecured.post('/account/register', service.registerUser);
And services.js might look like:
module.exports.signinUser = function*(signinDetails) {
// contains your application signin logic
};
module.exports.registerUser = function*(registerDetails) {
// contains your application register logic
};
So in this manner you can individually test services.js. I don't see any value in individually testing router.js since it is so trivial. As #Dan Pantry shows you can test routing as part of an integration test using supertest.
Edit:
So this is a little experimental test I was playing around with to test that the routing is correct. I'm using mocha as the test runner and the code example I posted in my original code.
// standard library
var assert = require("assert");
// in app objects
var router = require('./router.js');
var service = require('./service.js');
describe("routing tests", function() {
it("test register routing, POST", function*(done) {
// arrange
var unsecured = router.unsecured;
var path = '/account/register';
var httpMethod = 'POST';
var expected = service.register.toString();
var actual;
// act
for (var i = 0; i < unsecured.stack.length; i++)
{
var pathMatch = unsecured.stack[i].path === path;
var methodMatch = unsecured.stack[i].methods.indexOf(httpMethod) >= 0;
if (pathMatch && methodMatch)
{
actual = unsecured.stack[i].middleware.toString();
break;
}
}
// assert
try {
assert.equal(expected, actual);
done();
} catch(err) {
done(err);
}
});
});
There is probably a neater way of doing this (and a more modular way for testing multiple paths) but as I said this is just a basic example to verify the routing is calling the correct service. What I'm doing is delving into the koa-router object to verify what path is bound to what service code depending on the HTTP method (e.g. POST, GET, etc).
If you have your routing and your services in modules this test completely avoids dealing with the main koa app. Although technically this test spans multiple units (the routing and the service code) so it would technically be an integration test but it does mean you don't go near app.listen() which is what you didn't want to call in your tests.

Resources