webstack/api-platform-extensions-bundle

Bundle to add uuid filter, or search and global search support for Doctrine ORM to API Platform

v3.1.2 2023-03-07 09:28 UTC

This package is auto-updated.

Last update: 2024-04-03 15:19:49 UTC


README

TODO: what is API Platform and how do we extend it?

Installing

composer require webstack/api-platform-extensions-bundle:[version]

Configuring

After installing the plugin you will need to add some config files to you're project:

  • config/packages/webstack_api_platform_extensions.yaml
webstack_api_platform_extensions:
  identifier_class: App\Entity\%UserEntity%
  • config/routes/api_platform.yaml
app_extra:
  resource: '@WebstackApiPlatformExtensionsBundle/Resources/config/routing/routing.xml'
  prefix: /api

Filters

These filters are added by this bundle:

GlobalSearchFilter (api_platform.doctrine.orm.global_search_filter)

Searches (recursively?) through the specified columns (or all of them, scary stuff) of an entity on whose endpoint it's activated.

Configure the filter as a service (config/services/api_platform/search/[$domain/]$entity.yaml):

services:
  api.resource.region.global.search_filter:
    parent: 'api_platform.doctrine.orm.global_search_filter'
    arguments: [ {
      'name': 'partial',
      'depot.description': 'partial',
    } ]
    tags: [ { name: 'api_platform.filter', id: 'api.region.global_search_filter' } ]
    autowire: false
    autoconfigure: false

And apply it to the appropriate resource:

App\Entity\Transport\Region:
  attributes:
    route_prefix: /transport
    filters:
      - 'api.region.global_search_filter'

Now when a user calls the API with ?_global_search=foo, the query will become something like this:

SELECT 
    r.*
FROM 
    region r
LEFT JOIN
    depot d
ON
    d.id = r.depot_id
WHERE
    r.name LIKE '%foo%' 
    OR d.description LIKE '%foo%'

AliasSearchFilter (api_platform.doctrine.orm.alias_search_filter)

Works as the regular search filter, but lets you rename or alias (nested) properties in the URL. Pass the properties and aliases as separate DI arguments:

services:
  api.some_entity.deeply_nested_prop_filter:
    parent: 'api_platform.doctrine.orm.alias_search_filter'
    arguments:
      $properties:
        deeply.nested.property: 'exact'
      $aliases:
        myProp: 'deeply.nested.property'
    tags: [ { name: 'api_platform.filter' } ]

And apply it to the appropriate resource:

App\Entity\SomeEntity:
  attributes:
    route_prefix: /some
    filters:
      - 'api.some_entity.deeply_nested_prop_filter'

Now to hit this filter, the URL using the default SearchFilter would be:

/some?deeply.nested.property=foo

This alias search filter adds a new query string parameter that it'll map to the configured alias:

/some?myProp=foo

OrSearchFilter (api_platform.doctrine.orm.or_search_filter)

TODO

UuidFilter (api_platform.doctrine.orm.uuid_filter)

For looking up nested entities by their UUID, because API Platform doesn't support that (see api-platform/core#3774, was reverted because it broke date search).

Service configuration:

services:
  api.resource.transport_position.vehicle_filter:
    parent: 'api_platform.doctrine.orm.uuid_filter'
    arguments: [ {
      vehicle.id: 'exact'
    } ]
    tags: [ { name: 'api_platform.filter', id: 'api.transport_position.vehicle_filter' } ]
    autowire: false
    autoconfigure: false
    public: false

API Platform entity configuration:

App\Entity\Transport\Position:
  collectionOperations:
    get:
      filters:
        - 'api.transport_position.vehicle_filter'

Now the API caller can filter using GET .../transport_positions?vehicle.id=$uuid.

Routes

The bundle introduces the following route(s):

/me

Get info about the caller. Includes a SwaggerDecorator to generate OpenAPI documentation about this endpoint.