Skip to content

Recipe: SAP UI5 SmartTable

This recipe shows how to expose an Eloquent model as an OData entity set that a UI5 SmartTable can consume with automatic filtering, sorting, and paging.

1. Create the model

php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    protected $casts = [
        'price' => 'decimal:2',
        'active' => 'boolean',
    ];

    public function category()
    {
        return $this->belongsTo(Category::class);
    }
}

2. Create the service with discovery

php
<?php

namespace App\OData;

use App\Models\Product;
use App\Models\Category;
use LaravelUi5\OData\ODataService;
use LaravelUi5\OData\Service\Contracts\EdmBuilderInterface;

class ShopService extends ODataService
{
    public function serviceUri(): string
    {
        return '';
    }

    public function namespace(): string
    {
        return 'Shop.Data';
    }

    protected function configure(EdmBuilderInterface $builder): EdmBuilderInterface
    {
        $this->discoverModel(Product::class);
        $this->discoverModel(Category::class);

        return $builder->namespace($this->namespace());
    }
}

Discovery automatically:

  • Creates entity types Product and Category with all DB columns
  • Creates entity sets Products and Categories
  • Maps the category BelongsTo relationship to a navigation property
  • Maps price cast to Edm.Decimal, active cast to Edm.Boolean
  • Auto-binds EloquentEntitySetResolver for both models

3. What the SmartTable sends

A typical UI5 SmartTable sends requests like:

GET /odata/Products?$top=20&$skip=0&$count=true&$orderby=name asc
GET /odata/Products?$filter=active eq true and price gt 10&$top=20&$count=true
GET /odata/Products?$filter=contains(name,'Widget')&$select=id,name,price&$top=20
GET /odata/Products?$expand=category&$top=20

All of these are handled automatically by the library.

4. Adding UI annotations (optional)

To give the SmartTable column configuration hints, add vocabulary annotations:

php
use LaravelUi5\OData\Edm\Annotation\Annotation;
use LaravelUi5\OData\Edm\Annotation\ConstantAnnotationValue;
use LaravelUi5\OData\Edm\Annotation\CollectionAnnotationValue;
use LaravelUi5\OData\Edm\Annotation\RecordAnnotationValue;

// On the entity type -- define LineItem (table columns):
$productType = new EntityType(
    namespace: $this->namespace(),
    name: 'Product',
    key: [$idProp],
    declaredProperties: [...],
    annotations: [
        new Annotation(
            term: 'com.sap.vocabularies.UI.v1.LineItem',
            value: new CollectionAnnotationValue([
                new RecordAnnotationValue(properties: [
                    'Value' => new ConstantAnnotationValue('name'),
                    'Label' => new ConstantAnnotationValue('Product Name'),
                ]),
                new RecordAnnotationValue(properties: [
                    'Value' => new ConstantAnnotationValue('price'),
                    'Label' => new ConstantAnnotationValue('Price'),
                ]),
                new RecordAnnotationValue(properties: [
                    'Value' => new ConstantAnnotationValue('active'),
                    'Label' => new ConstantAnnotationValue('Active'),
                ]),
            ]),
        ),
    ],
);

The SmartTable reads these annotations from $metadata and auto-generates columns.

5. Verify the metadata

GET /odata/$metadata

Check that the XML contains your entity types, properties with correct OData types, navigation properties, and any annotations you added.

OData: MIT | Core: BSL 1.1 | SDK: Commercial License