Is it possible to automate routing in Express? - javascript

Is it possible to automate routing in Express, so I don't have to list out all the routes?
For example: going to URL '/users/first_example' should automatically use the "users.first_example" module.
app.get('/users/:name', function(req,res){
return eval('users.'+req.params.name); //failed attempt
});
There's got to be something I'm missing, and it would make my code look a lot more elegant.
Much appreciated.

var users = require('./users');//a module of route handler functions
app.get('/users/:name', function(req,res){
var handler = users[req.params.name];
if (typeof handler === 'function') {
return handler(req, res);
}
res.status(404).render('not_found');
});

You might want to check this earlier answer on stackoverflow - https://stackoverflow.com/a/6064205/821720
A little more code but abstracts routing to the next level and also gives you a cleaner main file.

I have been working on something like this, focused on REST routes. Take a look at https://github.com/deitch/booster
If your routes are RESTful:
var booster = require('booster'), express = require('express'), app = express(), db = require('./myDbSetup');
booster.init({app:app,db:db});
booster.resource('user');
app.listen(3000);
You just need to wire up the database/persistence connection layer. You can choose to customize the controller routes, or the models, or any part of it, but all optional.

Related

Socket.io: io is not defined

So, I am trying to get data on my node.js file instead of directly getting it on my JS file.
I a using Socket.io 2 here, Below is a snapshot of my code and this is also the first time I am using Websocket with Node.
I am doing something like
var socket = require('socket.io')
//Home Page
app.get("/", function(req, res) {
var cryto = io.connect("https://xyfz.com/);
cryto.on('trades', function (tradeMsg) {
console.log(tradeMsg);
});
res.render("index");
});
I also tried something like
var io = socket("https://abc.io/");
and
var socket = require('socket.io')
var io = socket();
which was throwing errors like server.listeners is not a function and io.connect is not a function.
I am certain that I messing up stuff here so can someone guide me about the correct way of doing it?
Two things which are wrong .
First Consider using Socket.io-client instead of Socket.io.
Second and very much important.
Never ever make API calls inside your routes. This will trigger a API call everytime user opens your website or webpage
You can also expect an error "Unexpected headers" or something like that.
Always, Try do declare it outside any routes in your NodeAPP.
Same goes for socket.io as well

How can I dynamically assign a database path in Express.js based on login?

I have a backend service that I would like to use as a single point of entry for my web application, and dynamically assign a database path based on the user login.
I realize that this is not a scalable solution. I intend to use it during a testing period with several clients (accessing the ALPHA database), and also setting up a demo (accessing the SAND database).
I have the following module that I have written as a simple test to see if the login is for the demo user, all other logins will go to the other resource:
config.js
var express = require('express');
var app = express();
module.exports.dbPath = function (login){
console.log('login - ', login);
if (login === 'demo#mysite.com'){
return process.env.DB_SAND;
} else {
return process.env.DB_ALPHA;
}
};
My question is, how can I manage each unique login and assign a globally accessible reference for that session to direct each user session consistently to the correct database?
Am I overcomplicating this? If there is a different approach that would be a better practice I would welcome a suggestion in another direction.
I would use it as a middleware, and attach it to the req object for each user, something similar this:
module.exports = {
dbPath: function(req, res, next){
var login = req.body.login;
console.log('login - ', login);
if (login === 'demo#mysite.com'){
req.dbPath = 'DB_SAND';
} else {
req.dbPath = 'DB_ALPHA';
}
next();
}
};

User specific global variable in Node.js

my program looks as follows:
var globVar=[];
function1(usr){
//calculations with globVar
}
function2(usr){
//calculations with globVar
}
app.post('/', function(req, res) {
var formString = req.body.filter1;
globVar.push(formString);
usr= req.connection.user;
function1(usr);
function2(usr);
res.redirect('/');
});
req.connection.user comes from nodeSSPI module. I need to make this globVar user specific so it doesn't mixed up when users runs this app concurrently. Now it works well but only for single user :)
Thank you for your consideration on this matter.
I've been looking at what seems like the same problem and my solution was to simply use cookies, and set a variable within the cookies client-side.
In my case the problem was setting language choice permanently for each user and that was simplest.
This guide helps:
https://www.tutorialspoint.com/expressjs/expressjs_cookies.htm

NodeJS Modulization

So, I was told that passing around the request and or response variable in nodeJS is "bad practice". But this means that most of your code has to be in the server.js file, making it cluttered and kind of ugly.
How can you modularize your nodejs server, passing around req/res appropriately and be able to organize your code into separate files?
For example, I would like to split my socket routing, .get and .post into different files, but still be able to use the callback parameters like so:
app.io.route("disconnect", function(req,res) { <--- these params
db.query("UPDATE player_data SET online=0 WHERE id="+mysql.escape(req.session.user));
req.io.broadcast("event", {msg:req.session.username+" has logged out!"});
app.io.broadcast("reloadXY");
});
As of right now they're all in one file and I don't like that.
I think what the person meant by 'passing around' was something like this (in plain express):
app.get('/kittens', function(req, res) {
db.doAthing(req);
updateSomethingElse(res);
upvoteThisAnswer(res);
});
That is, passing around the two variables beyond the first function. This is bad because it becomes increasingly difficult to figure out where the call actually ends. One little res.end(500) in updateSomethingElse can cause the whole house of cards to come tumbling down.
It's perfectly ok (in fact, standard to the point of being the default in express) to declare that callback elsewhere (usually the /routes directory of your project.)
// app.js
var user = require('./routes/user')
, kittens = require('./routes/kittens');
// express stuff...
app.get('/settings', user.getSettings);
app.get('/fur', kittens.shed);
Then, in routes/user.js:
exports.getSettings = function(req, res) {
// Note how we're passing around properties of req/res, not the objects themselves.
db.getUserSettings(req.user.id).then(function(settings) {
res.render('settings', settings);
});
};
This video from TJ Holowaychuk (the guy who wrote Express and a ton of other Node infrastructure that we all use) helped me take Express modularization to the next level. Basically you can make individual apps in their own folders and consume them as middleware very easily. I have managed to extend this technique to socket.io with some tricks.
http://vimeo.com/56166857
You should not pass req and res to another modules but pass callbacks from another modules to route.
It should look like.
var someModule = require("./someModule")
app.get("/someAction", someModule.handleSomeAction) ;
If You want to have post and get in another modules You should pass reference to app (from express()) once to that module and operate on that.
For example :
var express = require("express") ;
var app = express();
var get_handler = require("./get_handler ")
var post_handler = require("./post_handler ")
get_handler.init(app);
post_handler.init(app);
and in post/get_handler :
var app;
exports.init = function( eApp){
app = eApp;
// operate on app
}

What does a Node.js web service look like?

I am taking a look at Node.js and thinking about using it for building an API. From what I can tell, ExpressJS would be the web framework and is not what I'd be looking for to solve this.
So what would a web service look like? Would it simply be creating a server, talking to mongo and returning results? Also, what does routing look like? (I'd obviously want to 'design' the routes).
If Express would be your web framework, look at the express-resource (Github) middleware for routing an API. You define resources and it'll wire up REST-style routing for you with very little boilerplate.
app.resource('horses', require('./routes/horses'), { format: json })
Given the above, express-resource will hook up all the REST-style routes to actions you supply, returning JSON by default. In routes/horses.js, you export actions for that resource, along the lines of:
exports.index = function index (req, res) {
// GET http://yourdomain.com/horses
res.send( MyHorseModel.getAll() )
}
exports.show = function show (req, res) {
// GET http://yourdomain.com/horses/seabiscuit
res.send( MyHorseModel.get(req.params.horse) )
}
exports.create = function create (req, res) {
// PUT http://yourdomain.com/horses
if (app.user.canWrite) {
MyHorseModel.put(req.body, function (ok) { res.send(ok) })
}
}
// ... etc
You can respond with different representations:
exports.show = {
json: function (req, res) {
// GET http://yourdomain/horses/seabiscuit.json
}
, xml: function (req, res) {
// GET http://yourdomain/horses/seabiscuit.xml
}
}
Middlewares like express-resource can make life with Node and Express much easier, take a look through the examples on github to see if it'll do what you need.
Here is a stub that looks up a horse name from a Postgres database and returns the result as JSON. Clients would access would access the API by going to address such as http://yourdomain.com/api/horse/seabiscuit
app.get('/api/horse/:name', function(req, res){
pg.connect(conString, function(err, client) {
var horse = req.params.name;
var sql = "...";
client.query(sql, function(err, result) {
if (err) {
...
}
for (var i=0; i<result.rows.length; i++) {
// Customize data as needed
}
return res.send(JSON.stringify(result.rows));
});
});
});
Node is pretty low level. It's like C in JavaScript's clothing. Since it's comparable to C, there's pretty much a lot you can do with Node. Creating web servers is just one of them. You can create live chat servers using sockets, blogs, streaming etc. The possibilities are infinite. You are limited only by your imagination.
Routing is just a task where you take in commands (commonly via URL or headers) and do tasks based on those commands passed.
But even I have not yet scathed the surface of node. It's API is huge and getting bigger. Better try using some basic library like Express or Connect first since they pretty much abstract the basic requirement of building the server from code.

Categories