Skip to main content
Translation datasources require advanced knowledge of Forest’s query interface.
The translation strategy is an advanced approach for creating your own datasources that involves translating Forest’s query interface into the target API’s query language.

Overview

A full-featured query translation module typically exceeds 1000 lines of code. This approach suits full-featured databases and requires deep understanding of Forest’s internals.
Translation datasource capabilities diagram

Key steps

Implementing this strategy requires completing three main phases:
  1. Structure declaration - Define the data structure
  2. Capabilities declaration - Specify API capabilities
  3. Translation layer implementation - Code the actual query translation

Minimal example

Structure declaration

Columns

Define fields with types, validation, and default values:

Typing

The typing system for columns is the same as the one used when declaring fields in the back-end customization step.

Validation

Forest permits declaring validation rules on primitive-type fields. These rules validate records during creation/updating in the back-office interface. The validation API mirrors the condition tree structure but excludes a “field” entry. Example validation clause:

Relationships

Important: Only intra-datasource relationships belong at the collection level. For inter-datasource relationships, use jointures during customization. Data sources using the query translation strategy require careful implementation for relationships.

Capabilities declaration

Data source implementers don’t need to translate every possible query type. Forest ensures only supported query features are available by having collections declare capabilities on construction.

Required features

All datasources must support:
  • Listing records
  • And nodes in condition trees
  • Or nodes in condition trees
  • Equal operator on primary keys
  • Paging (skip, limit)
Note: Translating the Or node is a strong constraint, as many backends will not allow it: providing a working implementation may require making multiple queries and recombining the results.

Optional features (opt-in)

UI filter requirements by field type

To unlock GUI filtering:
  • Boolean: Equal, NotEqual, Present, Blank
  • Date: All date operators
  • Enum: Equal, NotEqual, Present, Blank, In
  • Number: Equal, NotEqual, Present, Blank, In, GreaterThan, LessThan
  • String: Equal, NotEqual, Present, Blank, In, StartsWith, EndsWith, Contains, NotContains
  • UUID: Equal, NotEqual, Present, Blank

Collection-level capabilities

Count

Enables pagination widget to display total page count. Requires implementing the aggregate method:
Allows custom search implementation instead of default condition tree approach. Useful for full-text search (ElasticSearch, etc.):

Segments

Define segments at datasource level when condition trees are insufficient or segments are shared across projects:

Field-level capabilities

Write support

Mark fields as read-only:

Filtering operators

Declare supported operators per field:

Sort support

Flag sortable fields:

Read implementation

Emulation strategy

Emulation enables rapid development by allowing features to be tested in Node.js before optimization. This approach trades performance for faster iteration.

Basic list implementation

Aggregate method

The aggregate method handles both record counting and chart data generation:

Optimization: count queries

Handle count operations separately if your API supports efficient counting:

Write implementation

Making your records editable is achieved by implementing the create, update and delete methods. Important: The three write methods accept filter parameters, but unlike the list method, pagination support is unnecessary.

Method details

  • create(): Must return the newly created records with all fields populated
  • update(): Receives filter and patch object; updates matching records
  • delete(): Receives filter; deletes all matching records

Intra-datasource relationships

When building your own datasources using the translation strategy, collections must handle intra-datasource relationships that are declared in their structure.

Relationship types and requirements

Automatic handling:
  • one-to-many relationships
  • many-to-many relationships
For these types, Forest will automatically call the destination collection with a valid filter, requiring no additional implementation work. Manual implementation required:
  • many-to-one relationships
  • one-to-one relationships
These require developers to make all fields from the target collection available on the source collection (under a prefix).

Handling prefixed fields

When a many-to-one relationship exists, the collection must accept references using dot notation throughout its operations.

Structure declaration example

Query example

The system can execute calls using both source and target collection fields:

Expected response structure

Implementation scope

Developers implementing your own datasources must handle prefixed field references in:
  • Filters (condition trees)
  • Projections (field selections)
  • Aggregations (calculation operations)
Want to share your datasource with the community? Check out the Forest experimental repository to contribute.