Translation strategy

This is the official documentation of the forestadmin/laravel-forestadmin v2+ and forestadmin/symfony-forestadmin PHP agents.

Steps

Creating a custom data source will require you to work on the 3 following steps:

  1. Declare the structure of the data

  2. Declare the API capabilities

  3. Code a translation layer

Minimal example

<?php

use ForestAdmin\AgentPHP\DatasourceToolkit\Collection;
use ForestAdmin\AgentPHP\DatasourceToolkit\Components\Caller;
use ForestAdmin\AgentPHP\DatasourceToolkit\Components\Contracts\DatasourceContract;
use ForestAdmin\AgentPHP\DatasourceToolkit\Components\Query\Aggregation;
use ForestAdmin\AgentPHP\DatasourceToolkit\Components\Query\Filters\Filter;
use ForestAdmin\AgentPHP\DatasourceToolkit\Components\Query\Projection\Projection;
use ForestAdmin\AgentPHP\DatasourceToolkit\Schema\ColumnSchema;
use GuzzleHttp\Client;
// The real work is in writing this module
// Expect a full featured query translation module to be over 1000 LOCs
use QueryGenerator;

class MyCollection extends Collection
{
    public function __construct(DatasourceContract $datasource)
    {
        parent::__construct(
            $datasource,
            'MyCollection'
        );

        $this->addField('id', new ColumnSchema(
            columnType: 'Number',
            // As we are using the query translation strategy => define capabilities
            filterOperators: [], // field is not filterable
            isPrimaryKey: true,
            isReadOnly: true,  // field is readonly
            isSortable: false // field is not sortable
        ));

        $this->addField('title', new ColumnSchema(
            columnType: 'String',
            filterOperators: [],
            isPrimaryKey: false,
            isReadOnly: true,
            isSortable: false
        ));

        $this->client = new Client([
            'base_uri' => 'https://my-api/',
            'timeout'  => 5.0,
        ]);
    }

    public function list(Caller $caller, Filter $filter, Projection $projection): array
    {
        $params = QueryGenerator::generateListQueryString($filter, $projection);

        try {
            $response = $this->client->get('my-collection', [
                'query' => $params,
            ]);

            $body = json_decode($response->getBody()->getContents(), true);

            return $body['items'] ?? [];
        } catch (\Exception $e) {
            throw new \RuntimeException('Failed to fetch items: ' . $e->getMessage());
        }
    }

    public function aggregate(Caller $caller, Filter $filter, Aggregation $aggregation, ?int $limit = null)
    {
        $params = QueryGenerator::generateAggregateQueryString($filter, $aggregation, $limit);

        try {
            $response = $this->client->get('my-collection', [
                'query' => $params,
            ]);

            $body = json_decode($response->getBody()->getContents(), true);

            return $body['items'] ?? [];
        } catch (\Exception $e) {
            throw new \RuntimeException('Failed to fetch items: ' . $e->getMessage());
        }
    }
}
<?php

use Collections\MyCollection;
use ForestAdmin\AgentPHP\DatasourceToolkit\DataSource;

class MyDataSource extends DataSource
{
    public function __construct()
    {
        parent::__construct();
        $this->addCollection(new MyCollection($this)); // List of your collections
    }
<?php

use ForestAdmin\AgentPHP\Agent\Builder\AgentFactory;

return static function () {
    $dataSource = new MyDataSource();
    $agent = new AgentFactory([]);
    $agent->addDatasource($dataSource);

    return $dataSource;
};

Read more

Implementing a data source using the "query translation" strategy is an advanced concept: you will need to have a deep understanding of Forest Admin internals.

This strategy is a good match when writing data sources for full-featured databases.

Before starting, it is highly advised to read and understand the following sections:

Last updated