Chevere 3.0

Chévere! chévere! chévere!

rodber
rodber   GitHub

This content as 2024-01-13 is outdated due Chevere 4.0.

Chevere keeps getting better with a broader type support (generics) allowing to achieve the unicorn concept of typed array for PHP.

It has been three months since Chevere 2.0 and this new major version happened that fast because of a new major client using Chevere. From December 2022 I'm involved in the creation of a new state of the art system for the agricultural industry and I'm glad that I got the chance to implement Chevere there.

I hope this trend continues, that Chevere gets used in more different contexts and use cases.

# Generics

Chevere is getting support for generic parameters which provides great utility for I/O layer validation. With support for generics we can now handle complex real-life data structures.

If you want to assert on a fixed array argument is trivial as define its key-parameter pair:

$parameter = arrayp(
    abc: integerp(minimum: 100)
);
$argument = ['abc' => 100];
assertArgument($parameter, $argument);

For the example above Chevere will check for abc value to be at least 100.

Chevere gets more interesting when wanting to assert a collection of n-items. In Chevere this is easy as define both generic key K and value V:

$parameter = genericp(
    K: stringp('/^[a-z]+$/'),
    V: integerp(minimum: 100)
);
$argument = [
    ['a' => 100],
    ['b' => 101],
    ['c' => 102],
    // ...
];

For the previous code Chevere will check on both key and value pairs on the entire array, for each pair. Key will be match against a string with defined regular expression.

Cherry on top? 🤯 Chevere supports nested generic definitions. You can validate a generic inside a generic.

# Union parameter

The newly added Union Parameter enables to define a parameter of type union. With this you can assert a parameter against multiple types which makes Chevere's type system more robust.

With Chevere 3 you can assert any argument against an union parameter:

$parameter = unionp(
    stringp('/^[a-z]+$/'),
    integerp(minimum: 1),
    nullp(),
    // ...
);
assertArgument($parameter, 'abc');
assertArgument($parameter, 1);
assertArgument($parameter, null);

Chevere's union parameter system is powerful and more flexible than PHP's built-in union type. It supports multiple parameters with their own specific rules. With Chevere you can build union parameter rules that you can't have in plain PHP.

# Null parameter

The newly added Null Parameter enables to define a parameter of type null. This was added to be used with union parameter as on its own to define a null parameter doesn't make much sense.

# Action improves

With the addition of generics the Action component got modified for consistency. I dropped the concept of "Parameters" (plural) in favor of a newly introduced type: ArrayTypeParameterInterface, which is implemented by ArrayParameter and GenericParameter.

To summarize, I went from this:

public function getResponseParameters(): ParametersInterface
{
    return parameters(
        id:     integerParameter(),
        name:   stringParameter(),
    );
}

public function run(): array
{
    return [
        'id'   => 1,
        'name' => 'rodolfo'
    ];
}

To this (fixed array):

public function acceptResponse(): ArrayTypeParameterInterface
{
    return arrayp(
        id:     integerp(),
        name:   stringp(),
    );
}

And to this (generic array):

public function acceptResponse(): ArrayTypeParameterInterface
{
    return genericp(
        arrayp(
            id:     integerp(),
            name:   stringp(),
        ),
}

public function run(): array
{
    return [
        [
            'id'   => 1,
            'name' => 'Argentina'
        ],
        [
            'id'   => 2,
            'name' => 'France'
        ],
        // ...
    ];
}

# HTTP controller improves

The HttpController component gets improved with own namespace and interface improvements for consistency. For example, I changed withGet to withQuery and withPost for withBody.

You can review issue #120 for an overview of these changes.

Rodolfo blogging since 2012.