Arangodb/Foxx how to split routes in different files? - arangodb

How could I split the routing into different files?
This what I tried, but did not work:
// file 'index.js' as main in manifest.json
const createRouter = require('#arangodb/foxx/router');
const router = createRouter();
const entries = require('./routes/entries')
entries.init(router);
module.context.use("", router);
and the entries file is working as a function:
// file './routes/entries.js'
const db = require('#arangodb').db;
// [...] more const
module.exports = {
init: function(router) {
router.post('/entries', function(req, res) {
// [...] post handle
}
}
}
1) How could I modify the router in a js file and reuse in?
module.context.use(router)
2) Any idea how to handle all js files in the folder 'routes' to define the router and so minimize the definition for route files?

you can use the funtion router.use([path], middleware, [name]): Endpoint for that.
module.context.use('/entries', require('./routes/entries'), 'entries');
For more information take a look into the docs here or in the newest Foxx tutorial here which also use child routers.

Related

Splitting express app.get in multiple files

Is there any way to split it without needing to state each app.get?
Like this, I have to add a new app.get for each route.
app.get('/', require('./modules/menu'))
The goal is to make it automatic, so it'll get the path, parameters and stuff and send to the correct file.
Thanks!
Put all URL handler functions to separate files, for example, put all those handlers to files in directory ./modules.
Example handler file:
function handle(req,res){
res.send("file1");
}
module.exports = handle;
Use a for loop to create routes for app:
const glob = require("glob");
const glob_promise = require("glob-promise");
var log = console.log;
var files = [];
async function main(){
files = await glob_promise("./modules/**/*.js");
log(files);
for (let i=0; i<files.length; i++){
let file = files[i];
let url_path = file.replace("./modules","").replace(".js","");
log(url_path);
app.get(url_path, require(file))
}
}
main();
This is the way I work with express
app/
routes/
controllers
app.js
you can use app.js to import the files for controllers and routes
const routes1 = require("./routes/route1.json")
const routes2 = require("./routes/route2.json")
inside routes/route1.json you can then import your controllers for those routes:
let express = require('express')
const authTokenController = require("../controllers/auth/token")
let api = express.Router()
api.post('/my-controller', myController.myMethod)
module.exports = api
The good part is that you can use objects as controllers
class myController {
myMethod(request, response) {
}
}
module.exports = new authTokenController
So now you can load your very well organized app into express
app.use('/api', routes1)
app.use('/app', routes2)

Is it possible to have different route files in Express (NodeJS) app?

I'm a NodeJS beginner and I'm using express. My directory is like this :
__app
|_assets
|_controllers
|_somemodel.controller.js
|_models
|_somemodel.model.js
|_user.model.js
|_routes
|_route.js
|_passport.routes.js
|_somemodel.routes.js
|_views
|_note
|_index.ejs
|_passport
|_index.ejs
|_login.ejs
|_profile.ejs
...
__config
|_database.config.js
|_passport.config.js
__node_modules
package.json
server.js
the thing I wanna know is that is it possible to have a general routes file and then include or require other route files in that ? Like my route.js ?
And is this directory correct while using Express and Passport as authentication?
yes, you can require other route files into a common file like bellow.
somemodel.contoller.js
module.exports.someMethod = (req, res) => {
// do something
}
somemodel.routes.js
const controller = require("path-to-somemodel-controller")
module.exports = (app) {
app.route("/somepath")
.get(controller.someMethod)
// other methods
}
route.js
// you need to parse the app into route module
module.exports = (app) => {
require('somemodel.routes')(app);
// others goes here
}
server.js
const app = express();
require('path-to-route.js')(app
)

Express Routes in Parse Cloud Code Module

I am using parse.com cloud code with express to setup my routes. I have done this in the past with node, and I have my routes in separate files. So, in node I do
app.js
express = require("express");
app = exports.app = express();
require("./routes/js/account");
account.js
app = module.parent.exports.app;
app.get("/api/account/twitter", passport.authenticate("twitter"));
All the examples on parses site https://parse.com/docs/cloud_code_guide#webapp show this being done as follows.
app.js
var express = require('express');
var app = express();
app.get('/hello', function(req, res) {
res.render('hello', { message: 'Congrats, you just set up your app!' });
});
So, I would like to change the bottom to include a routes folder with separate routes files, but am not sure how to do this in parse.
I know this post is a little old, but I just wanted to post a solution for anyone still looking to get this to work.
What you need to do, is create your route file, I keep them in 'routes' forlder, for example <my_app_dir>/cloud/routes/user.js
Inside user.js you will have something that looks like this:
module.exports = function(app) {
app.get("/users/login", function(req, res) {
.. do your custom logic here ..
});
app.get("/users/logout", function(req, res) {
.. do your custom logic here ..
});
}
Then, in app.js you just include your file, but remember that you need to append cloud to the path, and pass the reference to your app instance:
require('cloud/routes/user')(app);
Also, remember that express evaluates routes in order, so you should take that into consideration when importing several route files.
I'm using a different method, have the routes in app.js, but you can probably include them in file if you prefer. Take a look at the example app,
anyblog on github
The way it works:
Set up a controller:
// Controller code in separate files.
var postsController = require('cloud/controllers/posts.js');
Add the controller route
// Show all posts on homepage
app.get('/', postsController.index);
// RESTful routes for the blog post object.
app.get('/posts', postsController.index);
app.get('/posts/new', postsController.new);
And then in posts.js, you can use exports, ex.
var Post = Parse.Object.extend('Post');
// Display all posts.
exports.index = function(req, res) {
var query = new Parse.Query(Post);
query.descending('createdAt');
query.find().then(function(results) {
res.render('posts/index', {
posts: results
});
},
function() {
res.send(500, 'Failed loading posts');
});
};
// Display a form for creating a new post.
exports.new = function(req, res) {
res.render('posts/new', {});
};
Pass the app reference to the post controller, and add the routes from there

Dynamically load routes with express.js

I am using express.js as a webserver and would like an easy way to separate all the "app.get" and "app.post" functions to separate files. For example, if I would like to specify get and post functions for a login page, I would like to have a login.js file in a routes folder that is dynamically loaded (will automatically add all of the files without having to specify each one) when I run node app.js
I have tried this this solution!, but it isn't working for me.
app.js
var express=require("express");
var app=express();
var fs=require("fs");
var routePath="./routers/"; //add one folder then put your route files there my router folder name is routers
fs.readdirSync(routePath).forEach(function(file) {
var route=routePath+file;
require(route)(app);
});
app.listen(9123);
I have put below two routers in that folder
route1.js
module.exports=function(app){
app.get('/',function(req,res){
res.send('/ called successfully...');
});
}
route2.js
module.exports=function(app){
app.get('/upload',function(req,res){
res.send('/upload called successfully...');
});
}
Typescript
routes/testroute.ts
import { Router } from 'express';
const router = Router();
router.get('/test',() => {
// Do your stuffs Here
});
export = router;
index.ts
let app = express()
const routePath = path.join(__dirname, 'routes');
fs.readdirSync(routePath).forEach(async (filename) => {
let route = path.join(routePath, filename);
try {
const item = await import(route);
app.use('/api', item.default);
} catch (error) {
console.log(error.message);
}
});
app.listen()
I ended up using a recursive approach to keep the code readable and asynchronous:
// routes
processRoutePath(__dirname + "/routes");
function processRoutePath(route_path) {
fs.readdirSync(route_path).forEach(function(file) {
var filepath = route_path + '/' + file;
fs.stat(filepath, function(err,stat) {
if (stat.isDirectory()) {
processRoutePath(filepath);
} else {
console.info('Loading route: ' + filepath);
require(filepath)(app, passport);
}
});
});
}
This could be made more robust by checking fro correct file extensions etc, but I keep my routes folder clean and did not want the added complexity
With this approach, there is no need to write routes manually. Just setup a directory structure like the URL paths. Example route is at /routes/user/table/table.get.js and API route will be /user/table.
import app from './app'
import fs from 'fs-readdir-recursive'
import each from 'lodash/each'
import nth from 'lodash/nth'
import join from 'lodash/join'
import initial from 'lodash/initial'
const routes = fs(`${__dirname}/routes`)
each(routes, route => {
let paths = route.split('/')
// An entity has several HTTP verbs
let entity = `/api/${join(initial(paths), '/')}`
// The action contains a HTTP verb
let action = nth(paths, -1)
// Remove the last element to correctly apply action
paths.pop()
action = `./routes/${join(paths, '/')}/${action.slice(0, -3)}`
app.use(entity, require(action))
})
Example route:
import { Router } from 'express'
import Table from '#models/table.model'
const routes = Router()
routes.get('/', (req, res, next) => {
Table
.find({user: userIdentifier})
.select('-user')
.lean()
.then(table => res.json(table))
.catch(error => next(error))
})
module.exports = routes

Pass variable to expressjs 3 routes

I have an ExpressJS 3 app and have my routes in a separate file. I'd like to declare some configs in my app.js that are available in the routes file - outside of the route definitions themselves.
In my app.js I would like to do something such as:
app.set('path_to_models', '/path/models/');
Then in my routes/index.js file I would like to be able to do this:
var Product = require(app.get('path_to_models') + 'product');
exports.list = function(req, res){
return Product.find(function (err, products) {
if (!err) {
res.render('product/manage', { products: products });
} else {
res.render('5xx');
}
});
};
I've seen a few posts related to this but none really addressed what I am looking for. I know that I can wrap the routes in a function but would like an alternative way that will keep my code as is if at all possible.
I just make a separate config module that holds my configuration and in any module that needs info from the config, I just require it as normal. Why drag express into the mix when a more loosely coupled approach works just fine.
config.js
exports.pathToModels = "/path/to/models";
routes.js
var config = require("./config");
console.log(config.pathToModels);
Simply pass app as an argument to `routes/index.js':
var routes = require('./routes/index.js')(app);
UPDATED: This should be
var routes = require('./routes/index.js').init(app);
and in routes/index.js:
var app;
exports=function(whichApp) {
UPDATED: This should be
exports.init=function(whichApp) {
app=whichApp;
// do initialization stuff
return exports;
}
exports.list=...

Resources