Skip to content

[api-platform/core: v2.4.3] [BUG] Binary UUID in search filter returns an empty array #2838

Closed
@farazive

Description

@farazive

This issue was raised as a comment in this issue here, but since that issue is labeled won't fix I am not sure if my comment will be ignored, so creating a new issue here.

The Entity

/**
 * @ORM\Entity
 */
class User
{
    /**
     * @var \Ramsey\Uuid\UuidInterface
     *
     * @ORM\Id
     * @ORM\Column(name="uuid", type="uuid_binary_ordered_time", unique=true)
     * @ORM\GeneratedValue(strategy="CUSTOM")
     * @ORM\CustomIdGenerator(class="Ramsey\Uuid\Doctrine\UuidOrderedTimeGenerator")
     */
    public $id;

    /**
     * First name of user
     *
     * @ORM\Column(name="first_name",type="string", length=255)
     */
    protected $firstName;

doctrine.yaml

doctrine:
    dbal:
        types:
            uuid_binary_ordered_time: Ramsey\Uuid\Doctrine\UuidBinaryOrderedTimeType
...
        connections:
            default:
                mapping_types:
                    uuid_binary_ordered_time: binary
...

Search filter

    app.api_resource.filter.search_filter.user:
        parent: 'api_platform.doctrine.orm.search_filter'
        arguments:
          -
            id: exact
            firstName: partial
        tags:  [ { name: 'api_platform.filter', id: 'app.api_resource.filter.search_filter.user' } ]

Because the id is exact, we can filter on multiple ids in a single query.

The API Resource file

resources:
    'App\Entity\User':

        shortName: 'User'
        class: 'App\Entity\User'

        description: 'The User resource'

        collectionOperations:
            api_users_get_collection:
                filters: [ 'app.api_resource.filter.search_filter.user' ]
                method: 'GET'
                normalization_context:
                    groups: [ 'userRead' ]
            get:
                openapi_context:
                    summary: Get's all the users specified in the system
                    description: >
                        Get all the users from the system
                    parameters:
                    -
                        name: id
                        in: query
                        required: false
                        schema:
                            type: array
                            items:
                                type: string
                        description: Exact match of Ids. Its possible to send multiple Ids
                        style: deepObject
                        explode: true

The bug

When visiting the route /users/{id}, where id is a UUID v1, everything works.

When visiting the route /users?id[0]={id} the system returns an empty array since its not converting the string UUIDs to Ramsey UUID objects.

It was cited in a comment here that the actual bug is this one. So I added the following in class Ramsey\Uuid\Doctrine\UuidBinaryOrderedTimeType

...
    /**
     * @inheritdoc
     *
     * @return int
     */
    public function getBindingType()
    {
        return ParameterType::BINARY;
    }

But the UUID is still not converted.

For item operations, it works fine since in the identifiers are converted here. But for collection operations, the id filter is not converted.

Regarding the solution provided here I have reservations mentioned in this comment here.

Please let me know if you need any more details. Thanks.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions