core icon indicating copy to clipboard operation
core copied to clipboard

Service Injection in Processor Causes /api Route to Fail

Open PicassoHouessou opened this issue 6 months ago • 6 comments

API Platform version(s) affected: 4.1.8 on Laravel

Description
After creating a processor in Laravel, if you inject a service into the processor’s constructor, accessing the /api route results in a 500 error, as shown in the image.

Image

How to reproduce

<?php
//app/State/UserProcessor.php
declare(strict_types=1);

namespace App\State;

use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProcessorInterface;

final class UserProcessor implements ProcessorInterface
{
     public function __construct(
        private ProcessorInterface $persistProcessor,
        private ProcessorInterface $removeProcessor,
    )
    {
    }
    public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): void
    {
        // Handle the state
    }
}

<?php
//app/Models/User.php
namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use ApiPlatform\Metadata\ApiResource;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
#[ApiResource(processor: 'App\State\UserProcessor')]
class User extends Authenticatable
{
    /** @use HasFactory<\Database\Factories\UserFactory> */
    use HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var list<string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var list<string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }
}

PicassoHouessou avatar May 13 '25 18:05 PicassoHouessou

Create a service provider I'm not sure how we're supposed to know what services to inject in the UserProcessor.

soyuka avatar May 14 '25 04:05 soyuka

@soyuka

I used the following command to create the processor:

php artisan make:state-processor

This added the following line to the AppServiceProvider:

$this->app->tag(UserProcessor::class, ProcessorInterface::class);

Here is the content of the provider

<?php

namespace App\Providers;

use App\State\UserProcessor;
use ApiPlatform\State\ProcessorInterface;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        //
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        //

		$this->app->tag(UserProcessor::class, ProcessorInterface::class);
    }
}

However, it seems that this part of the documentation isn't working as expected: https://api-platform.com/docs/core/state-processors/#laravel-state-processor-mechanism

PicassoHouessou avatar May 14 '25 09:05 PicassoHouessou

If you want both arguments to be properly injected you're missing something like:

$this->app->singleton(UserProcessor::class, function (Application $app) {
    return new UserProcessor(
        $app->make(\ApiPlatform\Laravel\Eloquent\State\ItemProvider::class),
        $app->make(\ApiPlatform\Laravel\Eloquent\State\RemoveProcessor::class),
    );
});

soyuka avatar May 17 '25 08:05 soyuka

Thank you. This code works:

 $this->app->singleton(UserProcessor::class, function (Application $app) {
            return new UserProcessor(
                $app->make(\ApiPlatform\Laravel\Eloquent\State\PersistProcessor::class),
                $app->make(\ApiPlatform\Laravel\Eloquent\State\RemoveProcessor::class),
            );
        });

So I believe the documentation should be updated for both the state provider and the state processor sections.

PicassoHouessou avatar May 17 '25 11:05 PicassoHouessou

don't hesitate to update the documentation thanks!

soyuka avatar May 19 '25 08:05 soyuka

Okay. I will

PicassoHouessou avatar May 19 '25 08:05 PicassoHouessou

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Jul 18 '25 08:07 stale[bot]