dedoc / scramble

Modern Laravel OpenAPI (Swagger) documentation generator. No PHPDoc annotations required.
https://scramble.dedoc.co/
MIT License
1.16k stars 109 forks source link

Unable to retrieve Schemas with Octane #349

Closed kichetof closed 4 months ago

kichetof commented 6 months ago

Hi guy!

I deployed a site with Laravel Octane powered by FrankenPHP and everything works fine and fast!

Today, I looked my API doc, and saw an error with JsonResource Schema.

I was able to reproduce the bug with Laravel 11 and without Docker (my project is on L10 with Docker, I can exclude this), please find my repo https://github.com/kichetof/scramble-frankenphp

Example UserResource toArray:

public function toArray(Request $request): array
{
    return [
        'name' => $this->name,
        'email' => $this->email,
    ];
}

When serving app by: php artisan serve

php-serve

Works fine!

When serving app with Octane/FrankenPHP: php artisan octane:frankenphp

frankenphp

Don't display my resource schema as expected.

I try to debug but they are no error nor no logs!

As my project is on Docker, I tried with FrankenPHP binary and Docker image (binary isn't compiled in the same way) and same behavior.


http://127.0.0.1:8000/docs/api.json : schemas "empty"; no trace of name/email

{"openapi":"3.1.0","info":{"title":"Laravel","version":"0.0.1"},"servers":[{"url":"http:\/\/127.0.0.1:8000\/api"}],"paths":{"\/users":{"get":{"operationId":"users","tags":["Users"],"responses":{"200":{"description":"Array of `UserResource`","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/UserResource"}}},"required":["data"]}}}}}}}},"components":{"schemas":{"UserResource":{"type":"string","title":"UserResource"}}}}

Maybe you've an idea why this happen with FrankenPHP? Thanks a lot for your help! Cheers Christophe

kichetof commented 6 months ago

Some additional informations:

  1. Generate doc from php-cli works as expected: ./frankenphp php-cli artisan scramble:export
  2. Serving app directly from FrankenPHP without Octane works (tested with Docker): docker run -p 80:80 -p 443:443 -p 443:443/udp -v $PWD:/app dunglas/frankenphp

Need more investigations with Octane

kichetof commented 6 months ago

As a workaround, the time to find the cause, this code works fine after having exporting doc from command line.

Route::get('docs/api.json', function (Dedoc\Scramble\Generator $generator) {
    return File::exists($doc = base_path(config('scramble.export_path')))
        ? File::json($doc)
        : $generator();
})->name('scramble.docs.index');
kichetof commented 5 months ago

@romalytvynenko After many hours of digging debug, I finally found that the properties was not resolved from \Dedoc\Scramble\Infer\Scope\Index::class

\Dedoc\Scramble\Support\TypeToSchemaExtensions\JsonResourceTypeToSchema::toSchema \Dedoc\Scramble\Support\Type\ObjectType::getMethodDefinition \Dedoc\Scramble\Infer\Definition\ClassDefinition::getMethodDefinition \Dedoc\Scramble\Infer\Scope\Scope::__construct

As Index::class is resolved only one time, it could be our issue! I resolved it by binding in shared mode and it works!

class ScrambleServiceProvider extends PackageServiceProvider
{
//      $this->app->singleton(Index::class);
        $this->app->bind(Index::class, shared: true);
//...
}

Without shared mode, I encounter same error from #307 as $this->index->classesDefinitions is an empty array.

[2024-04-04 18:51:22] local.ERROR: Error when analyzing route 'GET api/users' (App\Http\Controllers\UsersController@__invoke): Undefined property: Dedoc\Scramble\Support\Type\Generic::$typeToSchemaExtensions – /Users/tof/Herd/scramble-frankenphp/vendor/dedoc/scramble/src/Support/Generator/TypeTransformer.php on line 270  
[2024-04-04 18:51:22] local.ERROR: Undefined property: Dedoc\Scramble\Support\Type\Generic::$typeToSchemaExtensions {"exception":"[object] (ErrorException(code: 0): Undefined property: Dedoc\\Scramble\\Support\\Type\\Generic::$typeToSchemaExtensions at /Users/tof/Herd/scramble-frankenphp/vendor/dedoc/scramble/src/Support/Generator/TypeTransformer.php:270)

I tried both php serve and octane:start and both works :)

Need further investigation to not breaking anything!

romalytvynenko commented 4 months ago

@kichetof should be fixed in v0.10.7