Skip to content

feat(metadata): use PHP file as resource format #7017

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 2, 2025

Conversation

loic425
Copy link
Contributor

@loic425 loic425 commented Mar 13, 2025

Q A
Branch? main
Tickets
License MIT
Doc PR api-platform/docs#...

The idea of this PoC is to allow configuring resources and their operations with external PHP files instead of XML/YAML files, which will be useful for projects such as Sylius.

This PR is not ready to merge, there are no PHPUnit tests, I've just used a minimalist Symfony app to test it.
The goal of this PR is to open discussions and make an ADR later.

I already know there are also some discussions about customizing the existing operations but that could be based on this PHP file resource extractor. (I already made a PoC about that too in a CustomResourceMetadataCollectionFactory on the Sylius resource side).

api_platform:
    title: Hello API Platform
    version: 1.0.0
    defaults:
        stateless: true
        cache_headers:
            vary: ['Content-Type', 'Authorization', 'Origin']
    mapping:
        imports:
            - '%kernel.project_dir%/config/api_platform/resources'
        paths:
            - '%kernel.project_dir%/src/Entity'

The main issue is that we cannot load PHP files that are in the autoloader, cause it will throw an error, indicating the class already exist. That's the reason I added an "imports" part to the mapping configuration to solve the issue for the PoC.

<?php
// config/api_platform/resources/speaker.php
declare(strict_types=1);

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Operations;
use ApiPlatform\Metadata\Post;
use App\Entity\Speaker;

return (new ApiResource())
    ->withClass(Speaker::class)
    ->withOperations(new Operations([
        new Post(),
        new Get(),
        new GetCollection(),
    ]))
;

we instanciate the ApiResource, so it's the same DX as we already have when configuring the entity with the attributes.

<?php
// src/Entity/Conference.php
declare(strict_types=1);

namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use App\Repository\ConferenceRepository;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: ConferenceRepository::class)]
#[ApiResource]
class Conference
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;
    
    // ...
}

Here, it's just to show the current implementation with attributes still works.

image
We both have our Conference Entity with the ApiResource attribute and our Speaker entity configured with an external PHP file.

image

I've tried to get the collection and to add a new speaker and it works perfectly.

@loic425 loic425 marked this pull request as draft March 13, 2025 16:39
@loic425 loic425 force-pushed the feat/external-php-file branch from e44b66c to 10224da Compare March 14, 2025 10:11
@soyuka
Copy link
Member

soyuka commented Mar 14, 2025

@dunglas thoughts ? I quite like the idea.

As folluw-up you'd be able to overwrite sylius resources using something like this:

return $syliusProductResource->withShortName('overriden'); 

?

@dunglas
Copy link
Member

dunglas commented Mar 14, 2025

I like the idea too!

@loic425 loic425 force-pushed the feat/external-php-file branch from 10224da to 0d3b24a Compare March 14, 2025 11:19
@loic425
Copy link
Contributor Author

loic425 commented May 19, 2025

@soyuka I know you'll be a speaker during Sylius party in Toulouse. I'll be not there physically but maybe we could work on this together (remotely) during the hackaton if you are interested too. WDYT?

@soyuka
Copy link
Member

soyuka commented May 19, 2025

Not sure there's much more tbd, I'd flag this new functionality as @experimental, rebase, make sure tests are green and I'll do a review then we can merge this no?

@soyuka soyuka force-pushed the feat/external-php-file branch 3 times, most recently from f5f8e08 to 4a76d19 Compare May 28, 2025 20:06
@soyuka soyuka marked this pull request as ready for review May 28, 2025 20:27
@soyuka soyuka changed the title feat(metadata) Load external PHP file resources feat(metadata): use PHP file as resource format May 28, 2025
@soyuka soyuka force-pushed the feat/external-php-file branch from 4a76d19 to 397ffca Compare June 2, 2025 14:07
@soyuka soyuka merged commit 04f252e into api-platform:main Jun 2, 2025
85 of 97 checks passed
@soyuka
Copy link
Member

soyuka commented Jun 2, 2025

thanks @loic425 !

@loic425 loic425 deleted the feat/external-php-file branch June 2, 2025 18:15
@loic425
Copy link
Contributor Author

loic425 commented Jun 2, 2025

That's a very good news, I'll try to work on the customization soon, but that's already a cool feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants