passing around a 'db' object in express

2,395 views
Skip to first unread message

eleith

unread,
May 16, 2011, 11:24:32 AM5/16/11
to expre...@googlegroups.com
in my current expressjs project, i'm passing around a 'db' object in order to run queries against my database. this works fine for when the db calls are being made in my routes since they have local access to the db object.

however, i'm starting to build out utilities that live in different parts/files of the project and i have to pass in db as one of the arguments to each function that needs to access the database.

is there a way to share such objects in an expressjs project? i don't want to reconnect to the database each time in these utilities either, but actually use the existing connection that was created when app.js was started.

many of the examples i've found online either pass the 'db' object in function arguments or are simple examples such that all the routes have access to the local 'db' object in app.js.

any pointers would be appreciated.

deitch

unread,
May 16, 2011, 12:01:15 PM5/16/11
to Express
I was doing something like that last night (well, 2am on an airplane
over the Atlantic).

To simplify my example, let's say I have customers and orders. I have
routes that modify a customer and ones that modify an order.
I initialize my db in app.js, and then pass it into the require of a
customer and an order object:

var db, customer, order, server;
db = dbsetupfn();
customer = require('./models/customer')(db);
order = require('./models/order')(db);

server.get("/customer/:id",customer.get,customer.send);
server.get("/order/:id",order.get,order.send);

The actual customer or order lib uses a closure to store the db
object, e.g.

// this is customer.js
module.exports = function(db) {
return {
get: function(req,res,next) {
// get from the db and do other routing stuff
},
set: function(req,res,next) {
// set to the db and do other routing stuff
}
}
}


An alternative approach is to have a global route that stores the db
on the req object:

var db, server;
db = dbsetupfn();
server.use(function(req,res,next) {
req.dbobj = db;
});
server.use(server.router);

// now configure your routes

I like separating out customer, order, etc. as outside objects, as it
makes app.js extremely clean, keeps it model-like in one file, and
allows modifying one file without modifying the others, thus reducing
risk. In truth, you can use both, and it is just a question of if the
db is passed in initialization and thus available due to closure, or
is in the req object.

Avi

Herman A. Junge [neoSource]

unread,
May 16, 2011, 12:19:33 PM5/16/11
to expre...@googlegroups.com
Hi,

What is the best way to deploy my express app into production?


Herman A. Junge
neoSource, SCL


eleith

unread,
May 16, 2011, 12:25:16 PM5/16/11
to expre...@googlegroups.com
thanks avi.

i had forgotten about storing variables on the req obj.

any idea how common this practice is? i think as long as it doesn't happen too often, polluting the req namespace shouldn't be a problem...

but just for the sake of pushing my question even further, how would i go about getting access to the 'req' object itself, without passing that around? 

i'm thinking specifically about how in pylons, you can 'include' the pylons request object in any file/library and you will have access to the current request object of the client. pylons had a global namespace per client, making this possible, but in expressjs this doesn't look possible, and all variables related to the current client needs to be passed around through function calls.


vision media [ Tj Holowaychuk ]

unread,
May 16, 2011, 12:39:34 PM5/16/11
to expre...@googlegroups.com
yeah the request object is typically the way to go, we could have a separate object to tack props onto but I would rather keep the middleware signature small, it's very rarely an issue with the request object and it's always possible to just namespace that obj as well



--
You received this message because you are subscribed to the Google Groups "Express" group.
To post to this group, send email to expre...@googlegroups.com.
To unsubscribe from this group, send email to express-js+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/express-js?hl=en.



--
Tj Holowaychuk
Vision Media
President & Creative Lead

deitch

unread,
May 17, 2011, 1:32:27 PM5/17/11
to Express
Every route function has a signature function(req,res,next). Clean and
easy.

deitch

unread,
May 17, 2011, 1:31:55 PM5/17/11
to Express
Actually, this kind of reminds me of polluted global namespace.

TJ, should we have a standard place within the req object for all
these vars? E.g. req.transient = {} or similar? That way every custom
item knows it stores stuff there, but library middleware does its own
thing? Otherwise you have to worry about who is trouncing what all the
time. Or maybe I am worrying too much?

On May 16, 7:39 pm, "vision media [ Tj Holowaychuk ]" <t...@vision-

vision media [ Tj Holowaychuk ]

unread,
May 17, 2011, 2:21:49 PM5/17/11
to expre...@googlegroups.com
worrying to much IMO, devs can still choose to namespace on req if they want to, the request itself is transient so "meh", if we come across collisions with future versions of node at least it will be per stable release and we can adjust accordingly if needed, though I dont see node having req.session etc any time soon

eleith

unread,
May 17, 2011, 2:51:19 PM5/17/11
to expre...@googlegroups.com
true and that is quite useful. though i was also thinking about libraries i had in other files like 'lib/utilities.js'.

but as you brought up earlier on how controllers can be exported as a function so 'app' can be passed in as a first argument, i've made my libraries structured similarly such that app or db can be passed in as needed.

works good enough for me and looks clean to boot!

Laurie Harper

unread,
May 17, 2011, 3:44:01 PM5/17/11
to expre...@googlegroups.com
Agreed; req isn't the *only* place you can hang you objects; there's nothing wrong with 'module.exports.mything = mysharedthing;' in your modules if it's singleton; req makes sense for things that are per-request, and is the obvious place to hang stuff in that case, but you can still do 'req.mystuff = req.mystuff || {}; req.mystuff.mything = myreqthing;'. If it's a library, provide the API to get 'the thing for this request', as in 'mylib.get(req);' and don't hang it anywhere, then you don't have any conflicts....

There are lots of ways to solve these problems, no point adding noise to the Express APIs IMHO.

L.
-- 
Laurie Harper



vision media [ Tj Holowaychuk ]

unread,
May 17, 2011, 5:17:28 PM5/17/11
to expre...@googlegroups.com
yeah, we could even go as far to have say "this.foo = bar" within a route ref some object like req.expressState or something haha but I dont want to add anything else to the function signature, and I really hate when people use "this" for anything contextual really, almost always end up doing "var self = this" 

deitch

unread,
May 18, 2011, 11:43:04 AM5/18/11
to Express
Yeah, this does get messy. I avoid it whenever I can for things like
this.

On May 18, 12:17 am, "vision media [ Tj Holowaychuk ]" <t...@vision-
Reply all
Reply to author
Forward
0 new messages