Locastic Feb 05

How-to switch off the ApiPlatform specification in the Sylius API

2 min read –
sylius api platform

Recently, we started a new Sylius project (Sylius-standard) and we decided to use their new API for the frontend part of our application. After a few hours of coding, someone asked:

Is it possible to turn off the entire routes specification for the new Sylius API, and then include just shop Product configuration?

The question.

In order to keep our OpenApi(Swagger) documentation clean, we wanted to remove all unused endpoints (~150 routes exist by default). There are various ways of doing it, but hooking into ApiPlatform’s process of generating resources is one of the most powerful, yet simpler way of customizing the API.

The Solution

<?php

declare(strict_types=1);

namespace App\Infrastructure\ApiPlatform;

use ApiPlatform\Core\Metadata\Extractor\ExtractorInterface;
use App\Entity\Product\Product;

class MetadataXmlExtractor implements ExtractorInterface
{
    private ExtractorInterface $decorated;

    public function __construct(ExtractorInterface $decorated)
    {
        $this->decorated = $decorated;
    }

    public function getResources(): array
    {
        $resources = $this->decorated->getResources();

        foreach ($resources as $resourceClass => $definition) {
            if (Product::class !== $resourceClass) {
                unset($resources[$resourceClass]);
            }
        }

        return $resources;
    }
}
# config/services.yaml
...
App\Infrastructure\ApiPlatform\MetadataXmlExtractor:
        decorates: api_platform.metadata.extractor.xml

php bin/console c:c

How does this work?

ApiPlatform has two services for extracting configurations from .xml and .yaml files registered as api_platform.metadata.extractor.xml and api_platform.metadata.extractor.yaml. By decorating them, we can control how will our final configuration look like.

Sylius uses XML for configuration, while we decided to use YAML, so this solution perfectly fits our needs.

After extracting all the configurations, ApiPlatform uses them for registering routes, so with this change, we ensure that the application generates only the routes and the schema that we actually need.

Why would I need that?

We used a really simple example where we haven’t touched the $definition variable. It is an array that contains the entire definition for the given resource, so we can change it however we want (for example, this might be a good place to add “language” as a route parameter in the entire app).

Don’t forget, this way of changing the API can be applied in any ApiPlatform application for various purposes.