BFF Specification
Intro
As mentioned above, the BFF (Backend for Frontend) is designed to be a specification rather than an exact implementation. Therefore, this article aims to provide the specifications for a basic BFF server that is compatible with the Invent Platform.
While it is possible to expand the range of endpoints exposed on your BFF, this article will ensure that all essential endpoints are presented.
By default for security we are using authorization header. So any protected endpoint will expect an authorization: Bearer header with JWT in it.
Public endpoints could be fetched without going through the auth process. All the public routes are required for platform bootstrapping.
/theme
More about the theme contracts can be found in the theme article
GET: /theme
This endpoint should return the theme selected by the user. If no theme is selected - the default theme should be returned.
Method: GET
URI: /theme
Auth: Bearer header
content-type: application/json; charset=utf-8
response-status: 200/400/403/404
response-body: ThemeObject
GET: /theme/list
This endpoint should return a list of theme names.
Method: GET
URI: /theme/list
Auth: Bearer header
content-type: application/json; charset=utf-8
response-status: 200/400/403/404
response-body: ThemeObject[]
GET: /theme/:name
This endpoint provides access to the theme by name. Note that you HAVE to provide a fallback theme. The fallback theme should be prefixed with your company's slug. For example, the slug for Microsoft™ might be MS. So for a company called Owsome Company, it might be OC. And then the default theme name will look like OC-default. And the access endpoint for that theme will be https://my-bff-url.com/themes/OC-default.
Method: GET
URI: /theme/*SLUG*-default
Auth: not needed
response-status: 200/404
content-type: application/json; charset=utf-8
response-body: ThemeObject
POST: /theme/:name
This endpoint is used to upsert the specific theme. This endpoint is protected by default. So it is a good idea to keep it that way. If the theme with this name exists, it should be updated, if not - created. It is also better to create a whitelist of users who can use this endpoint. UserId is expected in the JWT token.
Method: POST
URI: /theme/*theme-name*
Auth: Bearer header.
request-body: ThemeObject
response-status: 200/400/403/404
response-body: -
/extensions
GET: /extensions/list
More about extensions you can find in Extension article
This endpoint returns a list of installed extensions.
Method: GET
URI: /extensions/list
Auth: Bearer
response-status: 200/403/404
content-type: application/json; charset=utf-8
response-body: ExtContractBff[]
Extension entity contract will look like:
type ExtContractBff = {
id: number;
name: string;
extHost: string;
version: string;
module: string;
scope: string;
useSharedExts: boolean;
dependencies: string[];
companion: string;
pathList: string[];
author: string;
};
Examples could be found here
/token
POST: /token/validate
This endpoint should return the status of the sent token.
type TokenValidateRT = {
status: "ok" | "unauthorized";
};
Method: POST
URI: /token/validate
Auth: Bearer
response-status: 200/401/404
content-type: application/json; charset=utf-8
response-body: TokenValidateRT
/tenent
GET: /tenent
This endpoint should return ENV param of tenentId. This one is used in widget-store
type TenentRT = {
tenentId: string;
};
Method: GET
URI: /tenent
Auth: Bearer
response-status: 200/401/404
content-type: application/json; charset=utf-8
response-body: TenentRT
/dashboards
Contracts
type DashboardMeta = {
name: string;
group: string;
version?: number;
role?: string;
id: string;
isVisible: boolean;
isShared: boolean;
sharedFor: string[];
creatorId: string;
couldBeEditedByRoles?: string[];
couldBeEditedByUsers?: string[];
};
type Dashboard = {
meta: DashboardMeta;
widgets: WidgetType[];
};
GET: /dashboards
This endpoint should return a list of dashboards to the user. If you want to apply some sort of access policy for getting a list of dashboards, this is the place to do it. You can also use this approach to implement dashboard sharing. It is also a good idea to return an empty list in case nothing is found by the user's query.
Method: GET
URI: /dashboards
Auth: Bearer
response-status: 200/401/404
content-type: application/json; charset=utf-8
response-body: Dashboard[]
POST: /dashboards
This endpoint upsert the dashboard. If the ID is empty or does not exist in the BFF datastore, a new dashboard is created.
Method: POST
URI: /dashboards
Auth: Bearer header.
request-body: Dashboard
response-status: 200/400/403/404
GET: /dashboards/metaList
This endpoint returns a list of dashboards meta-data. Can be used for an overview or quick access. Note that the list of DashboardMeta for users should be the same as for Dashboard.
Method: GET
URI: /dashboards/metaList
Auth: Bearer
response-status: 200/401/404
content-type: application/json; charset=utf-8
response-body: DashboardMeta[]
GET /dashboards/:dashboardId
This endpoint returns specific dashboard object.
Method: GET
URI: /dashboards/:dashboardId
Auth: Bearer
response-status: 200/401/404
content-type: application/json; charset=utf-8
response-body: Dashboard
DELETE /dashboards/:dashboardId
This endpoint deletes specific dashboard object.
Method: DELETE
URI: /dashboards/:dashboardId
Auth: Bearer
response-status: 200/401/404
content-type: application/json; charset=utf-8
POST: /dashboards/:dashboardId/thumbnail
This endpoint gives you the ability to upload images for a preview of specific dashboards.
Method: POST
URI: /dashboards/:dashboardId/thumbnail
Auth: Bearer header.
request-body: binary-image
response-status: 200/400/403/404
response-body: -