ObjectHydrator - Object Hydration library to create Command and Query objects.

Related tags

API ObjectHydrator
Overview

Object Hydrator

This is a utility that converts structured request data (for example: decoded JSON) into a complex object structure. The intended use of this utility is to receive request data and convert this into Command or Query object. The library is designed to follow a convention and does not validate input.

Quick links:

Design goals

This package was created with a couple design goals in mind. They are the following:

  • Object creation should not be too magical (use no reflection for instantiation)
  • There should not be a hard runtime requirement on reflection
  • Constructed objects should be valid from construction
  • Construction through (static) named constructors should be supported

Installation

composer require eventsauce/object-hydrator

Usage

By default, input is mapped by property name, and types need to match.

use EventSauce\ObjectHydrator\ObjectHydrator;

$hydrator = new ObjectHydrator();

class ExampleCommand
{
    public function __construct(
        public readonly string $name,
        public readonly int $birthYear,
    ) {}
}

$command = $hydrator->hydrateObject(
    ExampleCommand::class,
    [
        'name' => 'de Jonge',
        'birthYear' => 1987
    ],
);

$command->name === 'de Jonge';
$command->birthYear === 1987;

Complex objects are automagically resolved.

class ChildObject
{
    public function __construct(
        public readonly string $value,
    ) {}
}

class ParentObject
{
    public function __construct(
        public readonly string $value,
        public readonly ChildObject $child,
    ) {}
}

$command = $hydrator->hydrateObject(
    ParentObject::class,
    [
        'value' => 'parent value',
        'child' => [
            'value' => 'child value',
        ]
    ],
);

Custom Mapping Key

use EventSauce\ObjectHydrator\MapFrom;

class ExampleCommand
{
    public function __construct(
        public readonly string $name,
        #[MapFrom('birth_year')]
        public readonly int $birthYear,
    ) {}
}

Mapping from multiple keys

You can pass an array to capture input from multiple input keys. This is useful when multiple values represent a singular code concept. The array allows you to rename keys as well, further decoupling the input from the constructed object graph.

use EventSauce\ObjectHydrator\MapFrom;

class BirthDay
{
    public function __construct(
        public int $year,
        public int $month,
        public int $day
    ){}
}

class ExampleCommand
{
    public function __construct(
        public readonly string $name,
        #[MapFrom(['year_of_birth' => 'year', 'month', 'day'])]
        public readonly int $birthYear,
    ) {}
}

$hydrator->hydrateObject(ExampleCommand::class, [
    'name' => 'Frank',
    'year_of_birth' => 1987,
    'month' => 11,
    'day' => 24,
]);

Property casting

When the input type and property types are not compatible, values can be cast to specific scalar types.

Casting to scalar values

use EventSauce\ObjectHydrator\PropertyCasters\CastToType;

class ExampleCommand
{
    public function __construct(
        #[CastToType('integer')]
        public readonly int $number,
    ) {}
}

$command = $hydrator->hydrateObject(
    ExampleCommand::class,
    [
        'number' => '1234',
    ],
);

Casting to a list of scalar values

use EventSauce\ObjectHydrator\PropertyCasters\CastListToType;

class ExampleCommand
{
    public function __construct(
        #[CastListToType('integer')]
        public readonly array $numbers,
    ) {}
}

$command = $hydrator->hydrateObject(
    ExampleCommand::class,
    [
        'numbers' => ['1234', '2345'],
    ],
);

Casting to a list of objects

use EventSauce\ObjectHydrator\PropertyCasters\CastListToType;

class Member
{
    public function __construct(
        public readonly string $name,
    ) {}
}

class ExampleCommand
{
    public function __construct(
        #[CastListToType(Member::class)]
        public readonly array $members,
    ) {}
}

$command = $hydrator->hydrateObject(
    ExampleCommand::class,
    [
        'members' => [
            ['name' => 'Frank'],
            ['name' => 'Renske'],
        ],
    ],
);

Casting to DateTimeImmutable objects

use EventSauce\ObjectHydrator\PropertyCasters\CastToDateTimeImmutable;

class ExampleCommand
{
    public function __construct(
        #[CastToDateTimeImmutable('!Y-m-d')]
        public readonly DateTimeImmutable $birthDate,
    ) {}
}

$command = $hydrator->hydrateObject(
    ExampleCommand::class,
    [
        'birthDate' => '1987-11-24',
    ],
);

Casting to Uuid objects (ramsey/uuid)

use EventSauce\ObjectHydrator\PropertyCasters\CastToUuid;
use Ramsey\Uuid\UuidInterface;

class ExampleCommand
{
    public function __construct(
        #[CastToUuid]
        public readonly UuidInterface $id,
    ) {}
}

$command = $hydrator->hydrateObject(
    ExampleCommand::class,
    [
        'id' => '9f960d77-7c9b-4bfd-9fc4-62d141efc7e5',
    ],
);

Using multiple casters per property

Create rich compositions of casting by using multiple casters.

use EventSauce\ObjectHydrator\PropertyCasters\CastToArrayWithKey;
use EventSauce\ObjectHydrator\PropertyCasters\CastToType;
use EventSauce\ObjectHydrator\MapFrom;
use Ramsey\Uuid\UuidInterface;

class ExampleCommand
{
    public function __construct(
        #[CastToType('string')]
        #[CastToArrayWithKey('nested')]
        #[Map('number')]
        public readonly array $stringNumbers,
    ) {}
}

$command = $hydrator->hydrateObject(
    ExampleCommand::class,
    [
        'number' => [1234],
    ],
);

$command->stringNumbers === ['nested' => [1234]];

Creating your own property casters

You can create your own property caster to handle complex cases that cannot follow the default conventions. Common cases for casters are union types or intersection types.

Property casters give you full control over how a property is constructed. Property casters are attached to properties using attributes, in fact, they are attributes.

Let's look at an example of a property caster:

use Attribute;
use EventSauce\ObjectHydrator\ObjectHydrator;
use EventSauce\ObjectHydrator\PropertyCaster;

#[Attribute(Attribute::TARGET_PARAMETER)]
class CastToMoney implements PropertyCaster
{
    public function __construct(
        private string $currency
    ) {}

    public function cast(mixed $value, ObjectHydrator $hydrator) : mixed
    {
        return new Money($value, Currency::fromString($this->currency));
    }
}

// ----------------------------------------------------------------------

#[Attribute(Attribute::TARGET_PARAMETER)]
class CastUnionToType implements PropertyCaster
{
    public function __construct(
        private array $typeToClassMap
    ) {}

    public function cast(mixed $value, ObjectHydrator $hydrator) : mixed
    {
        assert(is_array($value));

        $type = $value['type'] ?? 'unknown';
        unset($value['type']);
        $className = $this->typeToClassMap[$type] ?? null;

        if ($className === null) {
            throw new LogicException("Unable to map type '$type' to class.");
        }

        return $hydrator->hydrateObject($className, $value);
    }
}

You can now use these as attributes on the object you wish to hydrate:

class ExampleCommand
{
    public function __construct(
        #[CastToMoney('EUR')]
        public readonly Money $money,
        #[CastUnionToType(['some' => SomeObject::class, 'other' => OtherObject::class])]
        public readonly SomeObject|OtherObject $money,
    ) {}
}

Static constructors

Objects that require construction through static construction are supported. Mark the static method using the Constructor attribute. In these cases, the attributes should be placed on the parameters of the static constructor, not on __construct.

use EventSauce\ObjectHydrator\Constructor;
use EventSauce\ObjectHydrator\MapFrom;

class ExampleCommand
{
    private function __construct(
        public readonly string $value,
    ) {}

    #[Constructor]
    public static function create(
        #[MapFrom('some_value')]
        string $value
    ): static {
        return new static($value);
    }
}

Maximizing performance

Reflection and dynamic code paths can be a performance "issue" in the hot-path. To remove the expense, optimized version can be dumped. These dumps are generated PHP files that perform the same construction of classes as the dynamic would, in an optimized way.

Dumping an optimized hydrator

You can dump a fully optimized hydrator for a known set of classes. This dumper will dump the code required for constructing the entire object tree, it automatically resolves the nested classes it can hydrate.

use EventSauce\ObjectHydrator\ObjectHydrator;
use EventSauce\ObjectHydrator\ObjectHydratorDumper;

$dumpedClassNamed = "AcmeCorp\\YourOptimizedHydrator";
$dumper = new ObjectHydratorDumper();
$classesToDump = [SomeCommand::class, AnotherCommand::class];

$code = $dumper->dump($classesToDump, $dumpedClassNamed);
file_put_contents('src/AcmeCorp/YourOptimizedHydrator.php');

/** @var ObjectHydrator $hydrator */
$hydrator = new AcmeCorp\YourOptimizedHydrator();
$someObject = $hydrator->hydrateObject(SomeObject::class, $payload);

Dumping an optimized definition provider

When only need a cached version of the class and property definitions, you can dump those too.

use EventSauce\ObjectHydrator\DefinitionProvider;
use EventSauce\ObjectHydrator\DefinitionDumper;

$dumpedClassNamed = "AcmeCorp\\YourOptimizedDefinitionProvider";
$dumper = new DefinitionDumper();
$classesToDump = [SomeCommand::class, AnotherCommand::class];

$code = $dumper->dump($classesToDump, $dumpedClassNamed);
file_put_contents('src/AcmeCorp/YourOptimizedDefinitionProvider.php');

/** @var DefinitionProvider $hydrator */
$hydrator = new AcmeCorp\YourOptimizedDefinitionProvider();
$definitionForSomeObject = $hydrator->provideDefinition(SomeObject::class);

Alternatives

This package is not unique, there are a couple implementations our there that do the same, similar, or more than this package does.

Comments
  • Fix cache keys colliding when using multiple casters without options

    Fix cache keys colliding when using multiple casters without options

    Using multiple casters that have no option within the same class causes the first one to be used for all of them.

    Currently, the example below will throw a UnableToHydrateObject exception stating "Invalid UUID string: ...". This is because the cache key is ClassThatUsesMutipleCastersWithoutOptions[] for both casters, meaning it will use CastToUuid instead of CastToLowerCase.

    class ClassThatUsesMutipleCastersWithoutOptions
    {
        public function __construct(
            #[CastToUuid]
            public UuidInterface $id,
    
            #[CastToLowerCase]
            public string $name,
        ) {
        }
    }
    
    opened by dhrrgn 4
  • Make serializing public methods optional

    Make serializing public methods optional

    There is currently no way to prevent the DefinitionProvider() from always returning all public methods. I have a lot of objects that calculate values out of other properties and I don't want these to be exported, because they are just for making handling easier (like asking an object for its height and width, but creating it by giving a set of dots in a coordination system). Is there any way to achieve this? I can't seem to solve this elegantly by providing my own DefinitionProvider, because it's a final class and not an interface I can code against. The only halfway elegant solution seems creating a derived class of ObjectMapperUsingReflection and overriding serializeObject(). That seems way over the top.

    I'd love to be able to turn off this behavior, preferably by an attribute like (#[SerializeMethods(true/false)]) or something similar on the object being serialized. Just a suggestion. I might be missing something important, but right now, I feel a bit clueless.

    opened by Nadyita 3
  • [FEATURE] Added ability to define nested input

    [FEATURE] Added ability to define nested input

    This PR introduces the ability to specify mapping from a nested key using a separator based notation. The separator is optional and configurable, providing full control for mapping.

    class ClassWithPropertiesMappedFromNestedKeys
    {
        public function __construct(
            #[MapFrom('nested.name', separator: '.')]
            public string $name,
            #[MapFrom('nested.age')]
            public int $age
        )
        {
        }
    }
    
    $object = $hydrator->hydrateObject(
        ClassWithPropertiesMappedFromNestedKeys::class,
        [
            'nested' => ['name' => 'Frank'],
            'nested.age' => 34
        ]
    );
    

    $object->name; // Frank $object->age; // 34

    opened by frankdejonge 3
  • Add additional CastToDateTimeImmutable attribute argument timezone (optional)

    Add additional CastToDateTimeImmutable attribute argument timezone (optional)

    Moin Moin from Hamburg.

    I found your package some weeks ago and bookmarked it. Now is the time I'm using it and I have an optimization suggest for you. The cast CastToDateTimeImmutable doesn't care about the date time zone. This can have different side effefcts. In this pull request I added the possibility to use a time zone for the cast.

    - Cheers Jan

    opened by jmatthiesen81 2
  • Multiple CastListToType on same constructor

    Multiple CastListToType on same constructor

    Hi,

    If I use multiple CastListToType attributes on the same constructor, as follow:

     public function __construct(
            #[CastListToType(Contact::class)]
            public readonly array $contacts = [],
    
            #[CastListToType(Message::class)]
            public readonly array $messages  = [],
    )
    

    Then the instance key for the property caster is the same for both the properties in: https://github.com/EventSaucePHP/ObjectHydrator/blob/b24acb880bfcf5551839c54f95a035eabe560e5c/src/ObjectHydrator.php#L71-L79

    Looking something like:

    Micc83\MyObject-0-EventSauce\ObjectHydrator\PropertyCasters\CastListToType
    

    As the same hydrator is used for both, then $messages is casted as Contact instead of Message.

    Should $options be considered as key for retrieving the instance?

    opened by micc83 2
  • Feature: MapFrom support nested data arrays

    Feature: MapFrom support nested data arrays

    Hi, it would be lovely, if it was supported hydrating data from nested objects:

    $data = [
        'name' => 'name'
        'data' => [
            'birthYear' => 1900,
        ],
    ];
    
    class ExampleCommand
    {
        public function __construct(
            public readonly string $name,
            #[MapFrom('data.birthYear')]
            public readonly int $birthYear,
        ) {}
    }
    
    $command = $hydrator->hydrateObject(ExampleCommand::class, $data);
    

    If you are opened to this, i am able to send PR. Thank you.

    opened by JanMikes 2
  • Feature: hydrate multiple objects into

    Feature: hydrate multiple objects into "typed array"

    So far I have been using https://packagist.org/packages/symplify/easy-hydrator which has unfortunately been deprecated. API and functionality seems to be very close to each other.

    Though i miss one important feature and that is hydrating multiple objects at once:

    /** @var array<MyClass> $data */
    $hydrator->hydrateObjects(MyClass::class, $data);
    

    Right now i am using:

    $objects = [];
    foreach ($data as $objectData) {
        $objects[] = $hydrator->hydrateObject(MyClass::class, $objectData);
    }
    

    Are you opened to support such functionality? I am able to send PR if you confirm. Thank you

    opened by JanMikes 2
  • Support nullable enum properties

    Support nullable enum properties

    I have a use case for hydrating objects with nullable enum properties, which is currently not supported. This could also be considered a bug fix since the object mapper otherwise passes null to BackedEnum::from() (which only accepts int|string).

    Thanks for your work on this package!

    opened by devfrey 1
  • Fix typo in PHPDoc parser regex pattern

    Fix typo in PHPDoc parser regex pattern

    There's a tiny mistake in the regex pattern used to parse PHPDoc types for arrays. This meant that camelCase properties couldn't be parsed, resulting in "Unable to resolve item type for type" errors.

    opened by devfrey 1
  • Cannot map object that has

    Cannot map object that has "use function" declarations.

    Type: EventSauce\ObjectHydrator\UnableToHydrateObject
    Code: 0
    Message: Unable to hydrate object: Acme\Reservation (property: customer) Caused by: Unable to hydrate object: Acme\Customer Caused by: assert(in_array($token[0], [T_NAME_FULLY_QUALIFIED, T_NAME_QUALIFIED, T_STRING]))
    File: /var/www/html/vendor/eventsauce/object-hydrator/src/UnableToHydrateObject.php
    Line: 44
    

    My Customer class looks like:

    <?php
    
    declare(strict_types=1);
    
    namespace Acme\Data;
    
    use EventSauce\ObjectHydrator\MapFrom;
    
    use function explode;
    use function vsprintf;
    
    final class Customer
    {
        public function __construct(
            #[MapFrom('customer_id')]
            public string $id,
            public string $firstName,
            public string $lastName,
            #[MapFrom('email_address')]
            public ?string $email = null,
            #[MapFrom('phone_number')]
            public ?string $phone = null,
            public ?string $organization = null,
            public array $address = [],
        ) {
        }
    
        public function shortId(): string
        {
            return explode(separator: '-', string: $this->id, limit: 2)[0];
        }
    
        public function name(): string
        {
            return vsprintf(format: '%s %s', values: [$this->firstName, $this->lastName]);
        }
    }
    
    opened by shadowhand 1
  • Type Error when try to hydrate a nullable DateTime(Immutable) Object

    Type Error when try to hydrate a nullable DateTime(Immutable) Object

    How-To-Reproduce

    checkout commit d1d2c9975ba4a7d40e659377ed622b50e0b06ee6 and execute tests. This will cause a Type Error TypeError: DateTimeImmutable::__construct(): Argument #1 ($datetime) must be of type string, null given

    opened by sleipi 1
  • Support PHPDocs with non-array `@param` types

    Support PHPDocs with non-array `@param` types

    This PR contains only failing tests and a partial fix, because I'm unsure how to implement the correct fix. I figured a PR with failing tests would be more helpful than just an issue.

    When ObjectHydrator tries to resolve array types from PHPDocs when hydrating objects, it breaks when the PHPDoc contains additional @param tags for non-array types, specifically when there's a single space after the non-array type. This PHPDoc currently breaks:

    /**
     * @param int $number
     * @param CamelClass[] $list
     */
    public function __construct(
        public int $number,
        public array $list,
    ) {}
    
    // LogicException : Unable to resolve item type for type: int
    

    The issue is partly related to this regex: https://github.com/EventSaucePHP/ObjectHydrator/blob/main/src/NaivePropertyTypeResolver.php#LL136. It doesn't match PHPDocs with more than one space after the @param type, which may be why this issue hasn't come up before.

    I'm not sure what the right fix would be. Ideally we should avoid passing the matched type to extractItemType(), but that would complicate the regex. Alternatively, we could do an early return from extractItemType() without throwing an exception, and return false from resolveFromConstructorDocComment().

    I'd like to hear your thoughts. I'm open to implementing a fix if you could provide some guidance.

    Thanks for your time and effort!

    opened by devfrey 3
  • Feature: polymorphic object mapping

    Feature: polymorphic object mapping

    EDIT: This PR now contains class-level MapFrom and MapToType

    This PR makes it possible to hydrate and serialise polymorphic structures using an #[attribute].

    Given the following classes:

    use EventSauce\ObjectHydrator\MapToType;
    
    class ClassThatMapsTypes
    {
        public function __construct(
            #[MapToType('animal', [
                'frog' => Frog::class,
                'dog' => Dog::class,
            ])]
            public Animal $child
        ) {
        }
    }
    
    class Dog implements Animal
    {
        public function __construct(public string $name)
        {
        }
    
        public function speak(): string
        {
            return 'woof';
        }
    }
    
    class Frog implements Animal
    {
        public function __construct(public string $color)
        {
        }
    
        public function speak(): string
        {
            return 'ribbit';
        }
    }
    

    When deserialising a payload:

    
    $object = $objectMapper->hydrateObject(ClassThatMapsTypes::class, [
       'child' => ['animal' => 'dog', 'name' => 'Rover'],
    ];
    
    assert($object->child instanceof Dog);
    assert($object->child->name === 'Rover');
    opened by frankdejonge 0
Releases(1.0.0)
  • 0.5.0(Aug 8, 2022)

  • 0.4.3(Aug 8, 2022)

    What's Changed

    • Type Error when try to hydrate a nullable DateTime(Immutable) Object by @sleipi in https://github.com/EventSaucePHP/ObjectHydrator/pull/23

    New Contributors

    • @sleipi made their first contribution in https://github.com/EventSaucePHP/ObjectHydrator/pull/23

    Full Changelog: https://github.com/EventSaucePHP/ObjectHydrator/compare/0.4.2...0.4.3

    Source code(tar.gz)
    Source code(zip)
  • 0.4.2(Aug 8, 2022)

  • 0.4.1(Jun 8, 2022)

    What's Changed

    • Add additional CastToDateTimeImmutable attribute argument timezone (optional) by @jmatthiesen81 in https://github.com/EventSaucePHP/ObjectHydrator/pull/21

    New Contributors

    • @jmatthiesen81 made their first contribution in https://github.com/EventSaucePHP/ObjectHydrator/pull/21

    Full Changelog: https://github.com/EventSaucePHP/ObjectHydrator/compare/0.4.0...0.4.1

    Source code(tar.gz)
    Source code(zip)
  • 0.4.0(Jun 5, 2022)

    What's Changed

    Added

    • The ObjectMapper interface was introduced, which represents both generated and reflection based mappers.
    • [Major Feature] Serialization was added to the main ObjectHydrator interface.
    • Array hydration now also has rudimentary support for docblock type hints (@param Type[] $name, @param array<Type> $name, @param array<string, Type> $name).

    Deprecations

    • The ObjectHydrator class was deprecated, use ObjectMapperUsingReflection and hint against the new ObjectMapper interface.
    • The ListOfObjects class was deprecated, use the IterableList object instead.
    • The KeyFormattingWithoutConversion class was deprecated, use the KeyFormatterWithoutConversion class instead.

    Breaking Changes

    • The ObjectHydrator class was converted into an interface named ObjectMapper, the main implementation is ObjectMapperUsingReflection.
    • The PropertyDefintion class was renamed to PropertyHydrationDefinition to be symmetrical with the new PropertySerializationDefinition.
    • The DefinitionProvider::provideDefinition method was deprecated in favour of the new provideHydrationDefinition for symmetry with provideSerializationDefinition.
    • The KeyFormatter interface was changed by adding a keyToPropertyName method, needed for serialization.
    • The ObjectHydrator::hydrateObjects return type class was renamed from ListOfObjects to IterableList.

    Full Changelog: https://github.com/EventSaucePHP/ObjectHydrator/compare/0.3.1...0.4.0

    Source code(tar.gz)
    Source code(zip)
  • 0.3.1(May 28, 2022)

    What's Changed

    • Add @template info to functions using class-string. by @zobo in https://github.com/EventSaucePHP/ObjectHydrator/pull/13
    • Added the ability to specify default key conversion strategy by @frankdejonge in https://github.com/EventSaucePHP/ObjectHydrator/pull/14
    • Fix example code in the readme by @jdreesen in https://github.com/EventSaucePHP/ObjectHydrator/pull/16

    New Contributors

    • @zobo made their first contribution in https://github.com/EventSaucePHP/ObjectHydrator/pull/13
    • @jdreesen made their first contribution in https://github.com/EventSaucePHP/ObjectHydrator/pull/16

    Full Changelog: https://github.com/EventSaucePHP/ObjectHydrator/compare/0.3.0...0.3.1

    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(May 28, 2022)

    What's Changed

    • [FEATURE] Added ability to define nested input by @frankdejonge in https://github.com/EventSaucePHP/ObjectHydrator/pull/12

    Full Changelog: https://github.com/EventSaucePHP/ObjectHydrator/compare/0.2.0...0.3.0

    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Apr 1, 2022)

    What's Changed

    • [FEATURE] Added ability to register default casters. by @frankdejonge in https://github.com/EventSaucePHP/ObjectHydrator/pull/4
    • Add the Jane's AutoMapper to alternatives by @Korbeil in https://github.com/EventSaucePHP/ObjectHydrator/pull/6
    • Typo fix by @mxr576 in https://github.com/EventSaucePHP/ObjectHydrator/pull/8
    • Fix very nitpicky typo by @bradjones1 in https://github.com/EventSaucePHP/ObjectHydrator/pull/7
    • Fixed #9: Added ability to map a list of payloads to objects. by @frankdejonge in https://github.com/EventSaucePHP/ObjectHydrator/pull/11

    New Contributors

    • @Korbeil made their first contribution in https://github.com/EventSaucePHP/ObjectHydrator/pull/6
    • @mxr576 made their first contribution in https://github.com/EventSaucePHP/ObjectHydrator/pull/8
    • @bradjones1 made their first contribution in https://github.com/EventSaucePHP/ObjectHydrator/pull/7

    Full Changelog: https://github.com/EventSaucePHP/ObjectHydrator/compare/0.1.0...0.2.0

    Source code(tar.gz)
    Source code(zip)
  • 0.1.0(Jan 3, 2022)

    What's Changed

    • Added ability to use multiple casters for one property. by @frankdejonge in https://github.com/EventSaucePHP/ObjectHydrator/pull/2
    • Feature: capture from multiple keys by @frankdejonge in https://github.com/EventSaucePHP/ObjectHydrator/pull/3
    • Add benchmarks to CI. by @frankdejonge in https://github.com/EventSaucePHP/ObjectHydrator/pull/5
    • Initial implementation

    New Contributors

    • @frankdejonge made their first contribution in https://github.com/EventSaucePHP/ObjectHydrator/pull/2

    Full Changelog: https://github.com/EventSaucePHP/ObjectHydrator/commits/0.1.0

    Source code(tar.gz)
    Source code(zip)
Owner
EventSauce
An event sourcing library for PHP.
EventSauce
Mediator - CQRS Symfony bundle. Auto Command/Query routing to corresponding handlers.

Installation $ composer require whsv26/mediator Bundle configuration // config/packages/mediator.php return static function (MediatorConfig $config)

Alexander Sv. 6 Aug 31, 2022
Read and write OpenAPI 3.0.x YAML and JSON files and make the content accessible in PHP objects.

php-openapi Read and write OpenAPI 3.0.x YAML and JSON files and make the content accessible in PHP objects. It also provides a CLI tool for validatin

Carsten Brandt 399 Dec 23, 2022
A simple object-relational mapping library built using PHP.

A simple object-relational mapping library built using PHP.

Maleesha Gimshan 2 Jun 29, 2021
Collection of value objects that represent the PHP code units

sebastian/code-unit Collection of value objects that represent the PHP code units. Installation You can add this library as a local, per-project depen

Sebastian Bergmann 740 Dec 29, 2022
Add Price Including tax for Magento's "cart" GraphQl query

Comwrap_GraphQlCartPrices Add Price Including tax for Magento's "cart" GraphQl query Query will looks like following: items { id __typenam

Comwrap 1 Dec 2, 2021
Syntax to query GraphQL through URL params, which grants a GraphQL API the capability to be cached on the server.

Field Query Syntax to query GraphQL through URL params, which grants a GraphQL API the capability to be cached on the server. Install Via Composer com

PoP 4 Jan 7, 2022
An object oriented PHP wrapper for the Livepeer API

Livepeer PHP An object oriented PHP wrapper for the Livepeer API Requirements PHP >= 7.4 A PSR-17 implementation A PSR-18 implementation Install Via C

Owen Voke 2 Nov 23, 2021
Create REST and GraphQL APIs, scaffold Jamstack webapps, stream changes in real-time.

API Platform is a next-generation web framework designed to easily create API-first projects without compromising extensibility and flexibility: Desig

API Platform 7.7k Jan 7, 2023
Supermeteor is PHP SDK use to create cloud message: whatsapp, sms and email etc

Supermeteor Supermeteor is PHP SDK use to create cloud message: whatsapp, sms and email etc How to use install using composer composer require superme

null 0 Jul 15, 2022
Create simple Restfull Api With Codeigniter 4 Framework

CodeIgniter 4 Restfull API Application Starter Codeigniter 4 Restfull is the creation of Restfull API with the codeigniter 4 framework. Use is very si

gunanto 14 Aug 27, 2022
A simple example of how to create a RESTful API in Laravel Framework 8.36.1.

FirstLaravel A simple example of how to create a RESTful API in Laravel Framework 8.36.1. I used Database sqlite because I wanted to deploy this proje

Max Base 4 Apr 16, 2021
This project was built to connect WHMCS with GridPane.com's API service so we can create sites within WHMCS.

GridPane Server Module for WHMCS This project was built to connect WHMCS with GridPane.com's API service so we can create sites within WHMCS. Discliam

null 10 Sep 2, 2021
Simple utility and class library for generating php classes from a wsdl file.

wsdl2phpgenerator Simple WSDL to PHP classes converter. Takes a WSDL file and outputs class files ready to use. Uses the MIT license. Announcement: We

null 802 Dec 10, 2022
The efficient and elegant JSON:API 1.1 server library for PHP

Woohoo Labs. Yin Woohoo Labs. Yin is a PHP framework which helps you to build beautifully crafted JSON:APIs. Table of Contents Introduction Features W

Woohoo Labs. 237 Nov 28, 2022
The efficient and elegant, PSR-7 compliant JSON:API 1.1 client library for PHP

Woohoo Labs. Yang Woohoo Labs. Yang is a PHP framework which helps you to communicate with JSON:API servers more easily. Table of Contents Introductio

Woohoo Labs. 160 Oct 16, 2022
A PHP library to support implementing representations for HATEOAS REST web services.

Hateoas A PHP library to support implementing representations for HATEOAS REST web services. Installation Working With Symfony Usage Introduction Conf

William Durand 998 Dec 5, 2022
This PHP library will help you to work with your Pinterest account without using any API account credentials.

Pinterest Bot for PHP A PHP library to help you work with your Pinterest account without API credentials. The Pinterest API is painful: receiving an a

Sergey Zhuk 414 Nov 21, 2022
YouTrack RestAPI library for PHP. An implementation for communicating with your YouTrack instance.

YouTrack API PHP This is an implementation for communicating with the JetBrains YouTrack RestAPI. This library covers basic resource calls available i

Samih Soylu 4 May 3, 2022
微信支付 API v3 的 PHP Library,同时也支持 API v2

微信支付 WeChatPay OpenAPI SDK [A]Sync Chainable WeChatPay v2&v3's OpenAPI SDK for PHP 概览 微信支付 APIv2&APIv3 的Guzzle HttpClient封装组合, APIv2已内置请求数据签名及XML转换器,应

null 275 Jan 5, 2023