Routes

What is route?

A route is simply the mapping between an API endpoint and the business logic behind this endpoint. In other words, the Admin API automatically generated by the Forest Liana consists of a series of routes.

What is a Smart Route?

Very often, you’ll need to be able to call business logic from your customer-facing application to avoid code duplication between your admin and your app. Another typical use case is simply to trigger a verification business logic before executing the logic.

So in summary, the Smart Route feature allows you to extend the default behavior of a Route.

Lumber
Rails
Express/Sequelize
Express/Mongoose

On our Live Demo, we’ve overridden the DELETE /forest/companies/:companyId API call to only allow admin users that are part of the Management team. If you’re in the right team, we call simply next() to trigger the default DELETE implementation.

app.js
'use strict';
var express = require('express');
var app = express();
var fs = require('fs');
// ...
// You MUST require these files before the default routes.
fs.readdirSync('./decorators/routes').forEach((file) => {
if (file[0] !== '.') {
app.use('/forest', require(`./decorators/routes/${file}`));
}
});
fs.readdirSync('./routes').forEach((file) => {
if (file[0] !== '.') {
app.use('/forest', require('./routes/' + file));
}
});
app.use(require('forest-express-sequelize').init({
modelsDir: __dirname + '/models',
envSecret: process.env.FOREST_ENV_SECRET,
authSecret: process.env.FOREST_AUTH_SECRET,
sequelize: require('./models').sequelize
}));
module.exports = app;
/decorators/routes/companies.js
const express = require('express');
const router = express.Router();
const Liana = require('forest-express-sequelize');
router.delete('/companies/:companyId', Liana.ensureAuthenticated, (req, res, next) => {
if (req.user.data.teams.indexOf('Management') > -1) {
next();
} else {
res.status(403).send('Sorry, you\'re now allowed to delete a company. Ask someone in the Management team.');
}
});
module.exports = router;

On our Live Demo, we’ve overridden the DELETE /forest/Company/:companyId API call to only allow admin users that are part of the Management team. If you’re in the right team, we call simply default_destroy method to trigger the default destroy implementation.

/lib/forest_liana/controllers/companies_controller.rb
if ForestLiana::UserSpace.const_defined?('CompanyController')
ForestLiana::UserSpace::CompanyController.class_eval do
# We register the default behavior method to default_destroy before the override.
alias_method :default_destroy, :destroy
def destroy
teams = forest_user.dig('data', 'data', 'teams')
if teams.include?('Management')
default_destroy
else
render status: 403, plain: 'Sorry, you\'re now allowed to delete a company. Ask someone in the Management team.'
end
end
end
end

On our Live Demo, we’ve overridden the DELETE /forest/companies/:companyId API call to only allow admin users that are part of the Management team. If you’re in the right team, we call simply next() to trigger the default DELETE implementation.

app.js
'use strict';
var express = require('express');
var app = express();
var fs = require('fs');
// ...
// You MUST require these files before the default routes.
fs.readdirSync('./decorators/routes').forEach((file) => {
if (file[0] !== '.') {
app.use('/forest', require(`./decorators/routes/${file}`));
}
});
fs.readdirSync('./routes').forEach((file) => {
if (file[0] !== '.') {
app.use('/forest', require('./routes/' + file));
}
});
app.use(require('forest-express-sequelize').init({
modelsDir: __dirname + '/models',
envSecret: process.env.FOREST_ENV_SECRET,
authSecret: process.env.FOREST_AUTH_SECRET,
sequelize: require('./models').sequelize
}));
module.exports = app;
/decorators/routes/companies.js
const express = require('express');
const router = express.Router();
const Liana = require('forest-express-sequelize');
router.delete('/companies/:companyId', Liana.ensureAuthenticated, (req, res, next) => {
if (req.user.data.teams.indexOf('Management') > -1) {
next();
} else {
res.status(403).send('Sorry, you\'re now allowed to delete a company. Ask someone in the Management team.');
}
});
module.exports = router;

On our Live Demo, we’ve overridden the DELETE /forest/Company/:companyId API call to only allow admin users that are part of the Management team. If you’re in the right team, we call simply next() to trigger the default DELETE implementation.

app.js
'use strict';
var express = require('express');
var app = express();
var fs = require('fs');
// ...
// You MUST require these files before the default routes.
fs.readdirSync('./decorators/routes').forEach((file) => {
if (file[0] !== '.') {
app.use('/forest', require(`./decorators/routes/${file}`));
}
});
fs.readdirSync('./routes').forEach((file) => {
if (file[0] !== '.') {
app.use('/forest', require('./routes/' + file));
}
});
app.use(require('forest-express-mongoose').init({
modelsDir: __dirname + '/models',
envSecret: process.env.FOREST_ENV_SECRET,
authSecret: process.env.FOREST_AUTH_SECRET,
mongoose: require('mongoose')
}));
module.exports = app;
/decorators/routes/companies.js
const express = require('express');
const router = express.Router();
const Liana = require('forest-express-mongoose');
router.delete('/Company/:companyId', Liana.ensureAuthenticated, (req, res, next) => {
if (req.user.data.teams.indexOf('Management') > -1) {
next();
} else {
res.status(403).send('Sorry, you\'re now allowed to delete a company. Ask someone in the Management team.');
}
});
module.exports = router;