I am trying to implement openAPI documentation in a Laravel project. I am using darkaonline/l5-swagger package, which is built on top of swagger-php to generate the documentation. I am facing a problem with references. I want to export the response of an API call to an external file outside the controller, that I am documenting, and for this purpose I'm using references. However, in this particular project I get this annoying error when generating the documentation:
Upon running:
php artisan l5-swagger:generate
I get the following output
$ref "#/components/responses/" not found for @OA\Response(response=201) in \App\Http\Controllers\Organization\OrganizationController->get() in /data/www/nnaydenov/laravel-sandbox/app/Http/Controllers/Organization/OrganizationController.php on line 58
at vendor/zircote/swagger-php/src/Loggers/DefaultLogger.php:31
27▕ } else {
28▕ $error_level = E_USER_WARNING;
29▕ }
30▕
➜ 31▕ trigger_error($message, $error_level);
32▕ }
33▕ }
34▕
+33 vendor frames
34 artisan:37
Illuminate\Foundation\Console\Kernel::handle()
Here is my controller:
class OrganizationController extends Controller
{
/**
* @OA\Get(
* path="second-example",
* operationId="secondExample",
* @OA\Response(
* response=200,
* description="Hello from my awesome description",
* @OA\JsonContent(
* @OA\Property(
* property="foo",
* type="string",
* example="bar",
* )
* )
* ),
* @OA\Response(
* ref="#/components/responses/foo",
* response=201
* )
* )
*/
public function get($id = null)
{
// ...
}
}
Here is the file that contains the response, I want to reference. It is located in app/Something/SomethingElse:
<?php
/**
* @OA\Response(
* response="foo",
* description="Sample description",
* @OA\JsonContent(
* @OA\Property(
* property="foo",
* type="string",
* example="bar",
* )
* )
* )
*/
The top level annotations, located at app\Http\Controllers\Controller:
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
/**
* @OA\Info(
* version="1.0.0",
* title="Api documentation",
* description="Api documentation",
* @OA\Contact(
* email="admin@admin.com"
* ),
* @OA\License(
* name="Apache 2.0",
* url="http://www.apache.org/licenses/LICENSE-2.0.html"
* )
* )
*
* @OA\Server(
* url=L5_SWAGGER_CONST_HOST,
* description="Demo API Server"
* )
*
* @OA\Tag(
* name="Projects",
* description="API Endpoints of Projects"
* )
*/
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
// ...
}
I guess there is something wrong with the project, I am trying to implement this at, because the same code works in a plain Laravel 8 project. However, I don't know how to debug this issue. I tried to manually create an openapi.json file using
./vendor/bin/openapi . -o openapi.json
But this results into numerous errors, which I haven't managed to fix. Any suggestions as to what the cause of this error might be or how to even debug this?
If this is a new project chances are that you are now using swagger-php V4. In version 4 the analyser code uses reflection. This was done to make it possible to use either annotations or PHP 8 attributes.
One downside is that stand-alone docblocks are no longer detected as there is no reflection to access those.
The simplest way to fix this is to add a class FooResponse{}
line after the annotations and swagger-php should find it again.
The same applies to other top level annotations like @OA\Info
or others.
See: https://zircote.github.io/swagger-php/guide/faq.html#warning-required-oa-info-not-found
In practice that would mean to add class FooResponse {}
to the annotation:
<?php
/**
* @OA\Response(
* response="foo",
* description="Sample description",
* @OA\JsonContent(
* @OA\Property(
* property="foo",
* type="string",
* example="bar",
* )
* )
* )
*/
class FooResponse {}