Admin backend

What is the Admin backend?

The Admin backend is a REST API generated automatically by the Forest Liana when you launch your application. This API covers all the common requirements of a fully functional Admin Interface (CRUD operations, search & filters, sort, pagination and more). The API is hosted on your side, so you have virtually no limitation to extend it.

However, to ease the customization of your admin panel, we’ve introduced the concept of Smart features which helps you to fully extend the API.

All your Smart features will be implemented by you and hosted on your server. The default folder to organize your customization is /forest, however you can change it using: configDir: 'my/path' in your Forest Admin initialization middleware.

Before you start to deep dive into this documentation, it’s a good idea to see how the Admin API is designed.

Retrieving the admin panel user details

Every time you interact with your application data from the Forest UI, it triggers an API call to your admin panel server. This API call is authenticated using the Data Token. This token is a JWT token signed with your FOREST_AUTH_SECRET (see the Security section for more information) and it is passed to the HTTP request through the Authorization header.

GET /forest/...
Host: ...
Origin: ...
Content-Type: ...
Accept: application/json
Authorization: Bearer <DATA_TOKEN>

The JWT Data Token contains all the details of the admin user. From a route, you can retrieve them with the variable req.user. On our Live Demo example, we’ve developed a Whoami global Smart Action available that returns the full name of the admin user.

SQL
Mongodb
/forest/companies.js
const Liana = require('forest-express-sequelize');
Liana.collection('companies', {
actions: [{
name: 'Whoami',
type: 'global',
endpoint: '/forest/whoami',
httpMethod: 'GET'
}]
});
req.user content
{
id: '2',
type: 'users',
data: {
email: 'sandro@munda.me',
first_name: 'Sandro',
last_name: 'Munda',
teams: ['Operations']
},
relationships: {
renderings: {
data: [{
type: 'renderings',
id: '22631'
}]
}
},
iat: 1521711363,
exp: 1522920963
}
/routes/whoami.js
const express = require('express');
const router = express.Router();
const Liana = require('forest-express-sequelize');
router.get('/actions/whoami', Liana.ensureAuthenticated, (req, res) => {
res.send({ success: `You are ${req.user.data.first_name} ${req.user.data.last_name}.` });
});
module.exports = router;
/forest/companies.js
const Liana = require('forest-express-mongoose');
Liana.collection('companies', {
actions: [{
name: 'Whoami',
type: 'global',
endpoint: '/forest/whoami',
httpMethod: 'GET'
}]
});
req.user content
{
id: '2',
type: 'users',
data: {
email: 'sandro@munda.me',
first_name: 'Sandro',
last_name: 'Munda',
teams: ['Operations']
},
relationships: {
renderings: {
data: [{
type: 'renderings',
id: '22631'
}]
}
},
iat: 1521711363,
exp: 1522920963
}
/routes/whoami.js
const express = require('express');
const router = express.Router();
const Liana = require('forest-express-mongoose');
router.get('/actions/whoami', Liana.ensureAuthenticated, (req, res) => {
res.send({ success: `You are ${req.user.data.first_name} ${req.user.data.last_name}.` });
});
module.exports = router;