How to access routes folder in sailsjs - node.js

My route.js file is becoming larger. Is there any way to split the file based on controller?
I want to create separate route file for each folder and merge it.

Basically you can do whatever you want in your project. One solution is to use the route.js file as a compilation file of your route configurations. You can write a function and execute it in place like that:
var routes = {};
var assemble = function() {
//do assembling stuff here and add your routes to the routs object
}
assemble();
module.exports.routes = routes;
This should be enough. In your assemble function you can use some smart way to find configurations so that your code is universal and from now on whatever config you write it would get merged automatically.

Related

How can I stay organized when changing asset locations used by express.js server?

I have been learning express and everything seems to be clicking into place so I am trying now to concentrate on organization and keeping things clean and intuitive. I am wondering if there is a convention for storing where certain files are stored to be accessed by my server? The idea is for example I have a directory something like this:
root/
|--html
|--html1.html
but I want to change the structure mid project to:
root/
|--assets
|--html
|--html1.html
Or for example as a site scales I decide to move my public directory to S3 or some other cloud storage instead.
Now I have to go back everywhere that sends that file and change the path or the entire middleware to send an s3 file. My solution is this, and it works, but I am not sure if it is optimal or if there is a convention that might be better.
I can store everything in an asset module like this which has methods to return a file:
function getFile(path){
return fs.readFileSync(path)
}
module.exports = {
html1: getFile(`${__dirname}/html/html1.html`),
html2: getFile(`${__dirname}/html/html2.html`,
image1: getFile(`${__dirname}/image/image1.html`
}
and import it into my server as "assets" and use it like this:
app.get('/*', (req, res, next) => {
res.set('Content-Type', 'text/html');
res.send(assets.html1);
});
Now if I want to change the path or even use an asset from s3 I can simply change the logic/function/path etc all in one place rather than going through all my routers manually etc.
Any feedback or guidance on where to look for more info is greatly appreciated!

NodeJS, express - routing

I´ve setup a little NodeJS API with 'expressjs'. In my code I have some similar code blocks looking like this:
app.get('/api/my/path', (req, res) => {
doSomethingUseful();
});
All thoses requests do something different, so the function being called is always different too.
I´m asking myself if this is good practice for writing code in NodeJS or not.
If there is a better / cleaner way of writing all those paths I would appreciate if you could tell me how or at least giving me a place to look for it.
EDIT 1: To be clear: I ask if it´s a good idea to write a lot of 'app.get(...)' into one source code file or if there is a better way?
Yes there is a better way than writing all routes in one file. For example, let us say you have routes for users and questions.
For users, you want get/set/put/delete for profile, and similarly for questions.So you create the following folder structure: /api/users and /api/questions
In /api/users,
const express=require('express')
const router=express.Router()
//this handles route: /users
router.get('/',(req,res)=>{})
//this handles route: /users/profile
router.get('/profile',(req,res){})
//this is to retrieve profile of specific user by user id :/users/profile/:userID
router.get('/profile/:userId',(req,res))
router.post('/profile',(req,res))
.
.
Then, in your index.js or entry point of your project,
const users=require('./api/users')
const questions=require('./api/questions')
app=require('express')
app.use('/users',users)
app.use('/questions',questions)
So in effect, you say for any /users route, refer to the users.js file, for any /questions routes, refer questions.js file and so on
Use a simple module, don't be invoking routes until you form a heap.
Try Route Magic
You want to do just 2 lines of code and have the module read your directory and file structure to handle all the app.use routing invocations, like this:
const magic = require('express-routemagic')
magic.use(app, __dirname, '[your route directory]')
For those you want to handle manually, just don't use pass the directory to Magic.

how do I pass a variable in app.js down to a route file?

so my folder structure looks like this:
app.js
----routes
|----user.js
----models
|----index.js
|----(all my model files)
I want to require all my model files in the app.js file and then pass that variable to the routes as I require them. My thinking was that if any of my route files ever change location I would only need to update app.js instead of also having to update the route file require call.
I know that you can say:
var User = require("./routes/user")(db);
app.use('/user', User);
my user files however looks like this:
const express = require('express');
const router = express.Router();
...some code
modules.export = router;
I realize that usually you'd write:
modules.export = (db)=>{
some code here...
}
this may be a stupid question but how do you modify that to work with the router?
My thinking was that if any of my route files ever change location I would only need to update app.js instead of also having to update the route file require call.
If that is your concern, may I interest you in module aliasing? You can set the path to your module in your package.json and then reference them in your route files using the alias you create for them. If the path changes, you would just have to change the path in your package.json and not in each file. Module aliasing is also great from getting around referencing files like this ---> ./../../../module.js
You can put a tiny bit of middleware code near the top of your http.js module, definitely before mounting your router handlers, like this.
app.use( function ( req, res, next ) {
req.models = {};
req.models.model1 = whatever;
req.models.model2 = whatelse;
req.models.other = thing; /* etc */
next();
} );
Then, when your requests arrive at your routes, they'll have that custom models object attached to them for use by route code.

What is the purpose of the `(app)` in `require(controller)(app)`?

I'm new to node, blah blah
I'm looking through some code I found, and encountered the lines
var app = express();
var glob = require('glob');
var controllers = glob.sync(config.root + '/app/controllers/*.js');
controllers.forEach(function (controller) {
require(controller)(app);
});
I understand that this goes and gets all the filenames of every file in /app/controllers/ that ends with .js, and sticks them in an array, then iterates over each one and calls a require on it. Makes sense, and looks like a nice way of not requiring each one individually. My question is what's that last (app) for? I tried looking at node documentation, but there is no require()() function. editing out the (app) leaves the code working fine with no errors, but doesn't load the controllers. If I had to take a guess, is it 'multiplying' the app by the found controller? Why would app.require(controller) not be a suitable option?
Thanks in advance
require is a part of node and is how modules are loaded. When you edit out the (app), it is probably still loading the controllers but because you haven't passed the app object over to each controller, they fail silently or return a controller object that doesn't work.
So something in the controller (probably a route being created or other similar stuff) needs to know about the app object and it has to be passed into the controller because app isn't in the global scope. You may want to review the node docs for module and globals as those will probably clear up WAY more than just this one question.
In my estimation we will have:
/* some-controller-file.js */
module.exports = function (app) {
/* do things with `app` */
}
So this allows you to use the created app inside of the controllers probably so you can attach routes.

Consolidating Routes in Express.js

I'm a novice programmer working on a web app. As I have things right now there is a route for every single query to my database. I know there must be a way to use route parameters to direct the route to executing the right function but I am having problems in implementation.
Here is what my routes look like right now:
var database = require('./routes/database');
app.get('/query/type', database.type);
app.get('/query/test', database.test);
app.get('/query/another', database.another);
app.get('/query/onemore', database.onemore);
Each route is mapped to a function in the database.js file. I would like to try to implement something in the following format which would handle the queries with a single line:
app.get('/query/:query', database.query)
Where it executes whichever function is named in the parameter :query.
Is there an easy way of implementing this?
you can create a function that will parse the parameter and use associative array to build the function you want to execute then invoke it. see code below.
function parseParam(req, res) {
var func = database[req.param('query')];
func(req, res);
}
app.get('/query/:query', parseParam);

Resources