Skip to content

Manual Schema

When you need full control over the OData schema -- custom type names, complex types, enum types, or non-standard mappings -- you can build the schema by hand using the EdmBuilder API.

Building an entity type

php
use LaravelUi5\OData\Edm\Contracts\Container\PrimitiveTypeEnum;
use LaravelUi5\OData\Edm\Property\Property;
use LaravelUi5\OData\Edm\Type\EntityType;
use LaravelUi5\OData\Edm\Type\PrimitiveType;

$int32  = new PrimitiveType(PrimitiveTypeEnum::Int32);
$string = new PrimitiveType(PrimitiveTypeEnum::String);

$idProp   = new Property('id', $int32);
$nameProp = new Property('name', $string);
$cityProp = new Property('city', $string);

$partnerType = new EntityType(
    namespace: 'Partners.Data',
    name: 'Partner',
    key: [$idProp],
    declaredProperties: [$idProp, $nameProp, $cityProp],
);

EntityType constructor parameters

ParameterTypeDefaultPurpose
namespacestringrequiredSchema namespace
namestringrequiredType name
baseType?EntityTypeInterfacenullInheritance base type
isAbstractboolfalseAbstract type flag
isOpenboolfalseOpen type (dynamic properties)
hasStreamboolfalseMedia entity flag
keylist<PropertyInterface>[]Key properties
declaredPropertieslist<PropertyInterface>[]Structural properties
declaredNavigationPropertieslist<NavigationPropertyInterface>[]Navigation properties
annotationslist<AnnotationInterface>[]Annotations

Building navigation properties

php
use LaravelUi5\OData\Edm\Property\NavigationProperty;

$passengerType = new EntityType(/* ... */);

$passengersNav = new NavigationProperty(
    name: 'passengers',
    targetType: $passengerType,
    isCollection: true,
);

$flightType = new EntityType(
    namespace: 'Test.Ns',
    name: 'Flight',
    key: [$idProp],
    declaredProperties: [$idProp, $originProp],
    declaredNavigationProperties: [$passengersNav],
);
ParameterTypeDefaultPurpose
namestringrequiredProperty name
targetTypeEntityTypeInterfacerequiredTarget entity type
isCollectionbooltrueCollection vs single-valued
isNullablebooltrueNullable flag
partnerName?stringnullPartner nav property name
isContainmentTargetboolfalseContainment flag
referentialConstraintsarray[]FK mapping
onDeleteAction?stringnullOn-delete behavior
annotationslist<AnnotationInterface>[]Annotations

Building entity sets

php
use LaravelUi5\OData\Edm\Container\EntitySet;
use LaravelUi5\OData\Edm\Container\NavigationPropertyBinding;

$partnerSet = new EntitySet(
    name: 'Partners',
    entityType: $partnerType,
    navigationPropertyBindings: [
        new NavigationPropertyBinding('address', 'Addresses'),
    ],
);

Navigation property bindings tell the OData runtime which entity set holds the target entities for each navigation property.

Building complex types

php
use LaravelUi5\OData\Edm\Type\ComplexType;

$addressType = new ComplexType(
    namespace: 'Partners.Data',
    name: 'Address',
    declaredProperties: [$streetProp, $cityProp, $zipProp],
);

$builder->addComplexType($addressType);

Registering on the builder

php
protected function configure(EdmBuilderInterface $builder): EdmBuilderInterface
{
    // ... build types and sets ...

    return $builder
        ->namespace('Partners.Data')
        ->addEntityType($partnerType)
        ->addEntityType($addressType)
        ->addEntitySet($partnerSet)
        ->addEntitySet($addressSet);
}

EdmBuilder methods

MethodPurpose
namespace(string)Set the schema namespace
alias(string)Set an optional namespace alias
containerName(string)Set the entity container name (default: DefaultContainer)
version(string)Set the OData version
addEntityType(EntityTypeInterface)Register an entity type
addComplexType(ComplexTypeInterface)Register a complex type
addEnumType(EnumTypeInterface)Register an enum type
addTypeDefinition(TypeDefinitionInterface)Register a type definition
addFunction(FunctionInterface)Register a function
addEntitySet(EntitySetInterface)Register an entity set
addSingleton(SingletonInterface)Register a singleton
addFunctionImport(FunctionImportInterface)Register a function import
addReference(ReferenceInterface)Add a vocabulary reference
build()Freeze into immutable EdmxInterface

All methods return $this for fluent chaining. After build() is called, the builder cannot be mutated.

Available primitive types

See the full list in PrimitiveTypeEnum:

Binary, Boolean, Byte, Date, DateTimeOffset, Decimal, Double, Duration, Guid, Int16, Int32, Int64, SByte, Single, Stream, String, TimeOfDay

Plus geography and geometry spatial types.

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