API-платформа: фильтрация настраиваемого поставщика данных

В настоящее время у меня возникают проблемы при попытке отфильтровать мои результаты при использовании внешнего источника API (Stripe) в API-Platform.

Что мне нужно сделать, так это вернуть список подписок для указанного клиента. Таким образом, переход к http: // локальный хост / api / подписки? customer = 123foo вернет все записи, соответствующие этому клиенту.

Теперь приведенный ниже код выдает ошибку из-за ORM \ Filter и будет работать без него, поскольку фактическая фильтрация выполняется в Stripes API, а не мной, НО, я действительно хочу, чтобы графический интерфейс Swagger-API имел фильтр коробка.

Короче говоря, как мне заставить аннотации в моей сущности отображать доступные для поиска поля в пользовательском интерфейсе Swagger при использовании внешнего источника данных.

У меня есть сущность, как показано ниже (упрощено, например, для целей):

<?php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Annotation\ApiProperty;
use Symfony\Component\Serializer\Annotation\Groups;

use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Core\Annotation\ApiFilter;

/**
 * Subscriptions allow you to charge a customer on a recurring basis. A subscription ties a customer to a particular plan you've created.
 * @ApiResource()
 * @ApiFilter(SearchFilter::class, properties = {"customer": "exact"})
 * @package App\Entity
 */
class Subscription
{
     /**
     * Unique identifier for the object.
     * @ApiProperty(identifier=true)
     * @var string | null
     */
    protected $id; 

    /**
     * ID of the customer who owns the subscription.
     * @var string | null
     */
    protected $customer;

    // Plus a bunch more properties and their Getters & Setters
}

И SubscriptionCollectionDataProvider:

<?php

namespace App\DataProvider;

use App\Entity\Subscription;
use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use App\Controller\BaseController;
use Symfony\Component\HttpFoundation\RequestStack;

/**
 * Class SubscriptionCollectionDataProvider
 * @package App\DataProvider
 * @author dhayward
 */
final class SubscriptionCollectionDataProvider extends BaseController implements CollectionDataProviderInterface, RestrictedDataProviderInterface
{

    protected $requestStack;

    /**
     * SubscriptionCollectionDataProvider constructor.
     * @param RequestStack $requestStack
     */
    public function __construct(RequestStack $requestStack)
    {
        $this->request = $requestStack->getCurrentRequest();
    }

    /**
     * @param string $resourceClass
     * @param string|null $operationName
     * @param array $context
     * @return bool
     */
    public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
    {
        return Subscription::class === $resourceClass;
    }

    /**
     * @param string $resourceClass
     * @param string|null $operationName
     * @return \Generator
     * @throws \Stripe\Error\Api
     */
    public function getCollection(string $resourceClass, string $operationName = null): \Generator
    {
        $customer = $this->request->get("customer");

        $data = \Stripe\Subscription::all(["customer" => $customer]);

        foreach($data['data'] as $subscriptionObject){
            $this->serializer()->deserialize(json_encode($subscriptionObject), Subscription::class, 'json', array('object_to_populate' => $subscription = new Subscription()));
            yield $subscription;
        }
    }

}

Результат ошибки, предположительно из-за того, что я использую ORM / Filter без какой-либо настройки ORM:

Call to a member function getClassMetadata() on null

Приветствуются любые указатели.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
7
0
5 331
1

Ответы 1

Так что мне, наконец, удалось с этим разобраться. Это было так же просто, как создание моей собственной версии SearchFilter, реализующей ApiPlatform\Core\Api\FilterInterface.

<?php

namespace App\Filter;

use ApiPlatform\Core\Api\FilterInterface;

/**
 * Class SearchFilter
 * @package App\Filter
 */
class SearchFilter implements FilterInterface
{
    /**
     * @var string Exact matching
     */
    const STRATEGY_EXACT = 'exact';

    /**
     * @var string The value must be contained in the field
     */
    const STRATEGY_PARTIAL = 'partial';

    /**
     * @var string Finds fields that are starting with the value
     */
    const STRATEGY_START = 'start';

    /**
     * @var string Finds fields that are ending with the value
     */
    const STRATEGY_END = 'end';

    /**
     * @var string Finds fields that are starting with the word
     */
    const STRATEGY_WORD_START = 'word_start';

    protected $properties;

    /**
     * SearchFilter constructor.
     * @param array|null $properties
     */
    public function __construct(array $properties = null)
    {
        $this->properties = $properties;
    }

    /**
     * {@inheritdoc}
     */
    public function getDescription(string $resourceClass): array
    {
        $description = [];

        $properties = $this->properties;

        foreach ($properties as $property => $strategy) {

                $filterParameterNames = [
                    $property,
                    $property.'[]',
                ];

                foreach ($filterParameterNames as $filterParameterName) {
                    $description[$filterParameterName] = [
                        'property' => $property,
                        'type' => 'string',
                        'required' => false,
                        'strategy' => self::STRATEGY_EXACT,
                        'is_collection' => '[]' === substr($filterParameterName, -2),
                    ];
                }
            }

        return $description;
    }

}

Также возможно добавить фильтры через openapi_context

famas23 03.09.2021 11:37

Другие вопросы по теме