GithubHelp home page GithubHelp logo

vyuldashev / laravel-openapi Goto Github PK

View Code? Open in Web Editor NEW
396.0 13.0 91.0 410 KB

Generate OpenAPI specification for Laravel Applications

License: MIT License

PHP 99.66% Shell 0.34%
laravel openapi api documentation docs rest swagger

laravel-openapi's Introduction

laravel-openapi's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-openapi's Issues

ReflectionException with controller from `make:controller --api`

The following error is seen when generating the OpenAPI JSON from the command line (artisan openapi:generate). This is for a bare controller with no editing beyond the Laravel boilerplate for artisan make:controller --api; no #[attribute] annotations were added to the controller, only a Route::resource() entry in routes/api.php.

   ReflectionException

  Method App\Http\Controllers\FooController::create() does not exist

  at vendor/vyuldashev/laravel-openapi/src/RouteInformation.php:75
     71▕                 ]);
     72▕             }
     73▕
     74▕             $reflectionClass = new ReflectionClass($controller);
  ➜  75▕             $reflectionMethod = $reflectionClass->getMethod($action);
     76▕
     77▕             $docComment = $reflectionMethod->getDocComment();
     78▕             $docBlock = $docComment ? DocBlockFactory::createInstance()->create($docComment) : null;
     79▕

      +4 vendor frames
  5   [internal]:0
      Vyuldashev\LaravelOpenApi\Builders\PathsBuilder::Vyuldashev\LaravelOpenApi\Builders\{closure}(Object(Illuminate\Routing\Route))

      +19 vendor frames
  25  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

Steps to Reproduce

  1. Start a new Laravel project using PHP 8.1.6
composer create-project laravel/laravel myproject
cd myproject
  1. Run the following commands to add dependencies and make a controller:
composer require 'php=^8.0'
composer require 'vyuldashev/laravel-openapi'
php artisan make:controller --api FooController
  1. Add the following line to the routes/api.php file:
Route::resource('/foo', App\Http\Controllers\FooController::class);
  1. Run php artisan openapi:generate.

This results in the error I included above.

Extra Info

Click for composer.json contents
{
    "name": "laravel/laravel",
    "type": "project",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "require": {
        "php": "^8.0",
        "guzzlehttp/guzzle": "^7.2",
        "laravel/framework": "^9.11",
        "laravel/sanctum": "^2.14.1",
        "laravel/tinker": "^2.7",
        "vyuldashev/laravel-openapi": "^1.5"
    },
    "require-dev": {
        "fakerphp/faker": "^1.9.1",
        "laravel/sail": "^1.0.1",
        "mockery/mockery": "^1.4.4",
        "nunomaduro/collision": "^6.1",
        "phpunit/phpunit": "^9.5.10",
        "spatie/laravel-ignition": "^1.0"
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Database\\Factories\\": "database/factories/",
            "Database\\Seeders\\": "database/seeders/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi"
        ],
        "post-update-cmd": [
            "@php artisan vendor:publish --tag=laravel-assets --ansi --force"
        ],
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi"
        ]
    },
    "extra": {
        "laravel": {
            "dont-discover": []
        }
    },
    "config": {
        "optimize-autoloader": true,
        "preferred-install": "dist",
        "sort-packages": true
    },
    "minimum-stability": "dev",
    "prefer-stable": true
}

Laravel 10 Support

Incompatible with Laravel 10

 - Root composer.json requires vyuldashev/laravel-openapi ^1.8 -> satisfiable by vyuldashev/laravel-openapi[v1.8.0].
    - vyuldashev/laravel-openapi v1.8.0 requires laravel/framework 5.8.*|^6.0|^7.0|^8.0|^9.0 -> found laravel/framework[v5.8.0, ..., 5.8.x-dev, v6.0.0, ..., 6.x-dev, v7.0.0, ..., 7.x-dev, v8.0.0, ..., 8.x-dev, v9.0.0-beta.1, ..., 9.x-dev] but it conflicts with your root composer.json require (^10.0).

OpenAPI v3.1 Support

Hello @vyuldashev 🤝

Thanks for making this excellent package. I wanted to make a quick issue to track the progress towards supporting OpenAPI v3.1, because it's been out for over a year now and it's excellent. It adds a lot of convenient functionality and lines up perfectly with JSON Schema, which could actually simplify your toolchain rather well as you can just use any of the vast amounts of JSON Schema tooling instead of the subset of tooling which understands what an OpenAPI Schema object.

Here's a guide to the differences written for end-users, but it should help make things fairly clear to tooling vendors like yourself.

https://www.openapis.org/blog/2021/02/16/migrating-from-openapi-3-0-to-3-1-0

If you say you'll be working on it I can update openapi.tools to reflect that.

Let me know if you have any questions or need any help with the upgrade process,

Remove path prefix

Our server is configured as follows: `https://domain.com/api/v1'
However, this package seems to simply take the uri's from the route and use them as paths.

That means that the openapi document now contains operations for api/v1/blog/{blog} whereas it should have been blog/{blog}.

It feels to me the package should instead generate full url's for routes, and remove the server url prefix from them.

No option to resolve custom collection.

Right now the package has the functionality to create multiple collections, but there is no option to serve them on multiple routes.
Example:

/api/public/docs
/api/private/docs

Because OpenApiController does not receive a collection flag and uses a "default" one.

class OpenApiController
{
    public function show(Generator $generator): OpenApi
    {
        return $generator->generate();
    }
}

There should be a way to pass collection:

    public function show(Generator $generator): OpenApi
    {
        return $generator->generate($collectionName);
    }

Or it should take from config.
I can help, but which way would be preferable? Or add a custom controller setting to the config?

OpenAPI 3.1 support

Hello,
do you have plans to add support for OpenAPI 3.1? It introduced new webhook fields to specification which is a useful feature

parameter & factory : add argument

Hello,
I'm wondering if it is possible to add some argument to \Vyuldashev\LaravelOpenApi\Attributes\Parameters to allow some argument. The idea would be to pass the validation request, by example, and allow to build part of the parameter information

So something like this

	#[OpenApi\Parameters(MyParameters::class), MyRequest::class]
	#[OpenApi\Response(ErrorValidationResponse::class, 422)]
	#[OpenApi\Operation]
	public function index(MyRequest $request)

thanks

Factory class must be instance of ResponseFactory when running openapi:generate

While using php artisan openapi:generate we can run into this exception:

image

This happens when your response class doesn't extend from Vyuldashev\LaravelOpenApi\Factories\ResponseFactory or straight up doesn't exist in the path you specified in the annotation of your controller method.
My suggestion would be to specify the Factory that generated this error in the exception message so it can help future devs debug their code.

Generation hangs when schemas referencing each other

When I'm defining my schemas and they're referencing each other the generation hangs.
Consider the following example.

// UserSchema.php
return Schema::object('User')
            ->properties(
                Schema::array('vehicles')->items(VehicleSchema::ref())->description('The related vehicles')->default(null),
             )
// VehicleSchema.php
return Schema::object('Vehicle')
            ->properties(
                Schema::object('user')->additionalProperties(UserSchema::ref())->description('The user relation')->default(null),
             )

Both of these are implementing the Reusable interface.

No support for Laravel database prefix

Within Laravel's config/database.php file, there is an option to add a prefix to database table names.

My MySQL config for example (defualt prefix is '') :

        'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => env('DB_PREFIX', ''),
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],

However, when generating a new schema with php artisan openapi:make-schema User -m User, it looks like the prefix field isn't being honoured as it should be, as I get this error message:

 Doctrine\DBAL\Schema\SchemaException

  There is no column with name 'id' on table 'users'.

  at vendor/doctrine/dbal/src/Schema/SchemaException.php:87
     83▕      * @return SchemaException
     84▕      */
     85▕     public static function columnDoesNotExist($columnName, $table)
     86▕     {
  ➜  87▕         return new self(
     88▕             sprintf("There is no column with name '%s' on table '%s'.", $columnName, $table),
     89▕             self::COLUMN_DOESNT_EXIST
     90▕         );
     91▕     }

      +3 vendor frames
  4   [internal]:0
      Vyuldashev\LaravelOpenApi\Console\SchemaFactoryMakeCommand::Vyuldashev\LaravelOpenApi\Console\{closure}("id")

      +17 vendor frames
  22  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

My users table is actually prefixed with "auth_" so if it looked for "auth_users" it would find the correct structure.

I've looked at the code to see if I can submit a PR for this, but I can't seem to find on a quick glance, where that table name is set within the code.

Schema didn't auto generated

i need to know why my reusable schema here App\OpenApi\Schemas\UserSchema didn't generated as a component schemas in json file (depending on ref)
here is my response builder
Screenshot from 2022-09-22 18-02-49

and here is my schema class
Screenshot from 2022-09-22 18-03-07

thanks for your consideration

Multiple parameter route

Hi,
I have such issues with multiple parameter as follow:

I code route with 3 parameter, but cannot generate the doc.

Route::prefix('activity')->group(function () {
    Route::GET('/{activity}/{personalflag}/{houseid}',
    [
      'as' => 'activity.show',
      'uses' => 'ActivityController@show',
    ]);
  });

Below is the error that I got while using 3 parameter at route.

Symfony\Component\Debug\Exception\FatalThrowableError  : Argument 1 passed to Vyuldashev\LaravelOpenApi\SchemaHelpers::guessFromReflectionType() must be an instance of ReflectionType, null given, called in D:\xampp7.3.0\htdocs\laravel\layanesia\vendor\vyuldashev\laravel-openapi\src\Builders\Paths\Operation\ParametersBuilder.php on line 39

  at D:\xampp7.3.0\htdocs\laravel\layanesia\vendor\vyuldashev\laravel-openapi\src\SchemaHelpers.php:10
     6| use ReflectionType;
     7|
     8| class SchemaHelpers
     9| {
  > 10|     public static function guessFromReflectionType(ReflectionType $reflectionType): Schema
    11|     {
    12|         switch ($reflectionType->getName()) {
    13|             case 'int':
    14|                 return Schema::integer();

  Exception trace:

  1   Vyuldashev\LaravelOpenApi\SchemaHelpers::guessFromReflectionType()
      D:\xampp7.3.0\htdocs\laravel\layanesia\vendor\vyuldashev\laravel-openapi\src\Builders\Paths\Operation\ParametersBuilder.php:39

  2   Vyuldashev\LaravelOpenApi\Builders\Paths\Operation\ParametersBuilder::Vyuldashev\LaravelOpenApi\Builders\Paths\Operation\{closure}(["houseid"])
      [internal]:0

  Please use the argument -v to see more details.

PHP 8 not yet supported

Hi there,

it would be great if PHP 8 could be supported here please.

Is anyone working on it?

thanks

php artisan openapi:make-schema User -m User generates Error in Laravel > 8

I'm using Laravel 8 and
php artisan openapi:make-schema User -m User command is not working correctly.
because of new namespace for Models App\Models\User

i fixed this in my project by adding 1 line in SchemaFactoryMakeCommad class.

    protected function buildModel($output, $model)
    {
        $model = Str::start($model, $this->laravel->getNamespace());

        if (! is_a($model, Model::class, true)) {
            throw new InvalidArgumentException('Invalid model');
        }
    protected function buildModel($output, $model)
    {
        $namespace = app()::VERSION[0] >= 8 ? $this->laravel->getNamespace(). 'Models\\' : $this->laravel->getNamespace();
        $model = Str::start($model, $namespace);
        
        if (! is_a($model, Model::class, true)) {
            throw new InvalidArgumentException('Invalid model');
        }

Installation issue on laravel 8

I'm attempting an install on a new laravel 8 project

    "require": {
        "php": "^7.3|^8.0",
        "fideloper/proxy": "^4.4",
        "fruitcake/laravel-cors": "^2.0",
        "guzzlehttp/guzzle": "^7.0.1",
        "laravel/framework": "^8.12",
        "laravel/tinker": "^2.5"
    },

and get the following error:

In Reader.php line 130:
                                                                                                                                                                                            
  cebe\openapi\Reader::readFromYamlFile(): Argument #1 ($fileName) must be of type string, null given, called in /var/www/html/vendor/mdwheele/laravel-openapi/src/OpenApiServiceProvider.  
  php on line 25      

Argument 1 passed to Vyuldashev\LaravelOpenApi\Generator::__construct() must be of the type array, null given

Hi there,

I've just installed this package and published It's configuration.

For some reason, when I try to generate the documentation I get the following error:

php artisan openapi:generate

   TypeError

  Argument 1 passed to Vyuldashev\LaravelOpenApi\Generator::__construct() must be of the type array, null given, called in C:\wamp64\www\Ocasiao-CMS\vendor\vyuldashev\laravel-openapi\src\OpenApiServiceProvider.php on line 47

  at C:\wamp64\www\Ocasiao-CMS\vendor\vyuldashev\laravel-openapi\src\Generator.php:26
     22▕     protected $tagsBuilder;
     23▕     protected $pathsBuilder;
     24▕     protected $componentsBuilder;
     25▕
  ➜  26▕     public function __construct(
     27▕         array $config,
     28▕         InfoBuilder $infoBuilder,
     29▕         ServersBuilder $serversBuilder,
     30▕         TagsBuilder $tagsBuilder,

  1   C:\wamp64\www\Ocasiao-CMS\vendor\vyuldashev\laravel-openapi\src\OpenApiServiceProvider.php:47
      Vyuldashev\LaravelOpenApi\Generator::__construct(Object(Vyuldashev\LaravelOpenApi\Builders\InfoBuilder), Object(Vyuldashev\LaravelOpenApi\Builders\ServersBuilder), Object(Vyuldashev\LaravelOpenApi\Builders\TagsBuilder), Object(Vyuldashev\LaravelOpenApi\Builders\PathsBuilder), Object(Vyuldashev\LaravelOpenApi\Builders\ComponentsBuilder))

  2   C:\wamp64\www\Ocasiao-CMS\vendor\laravel\framework\src\Illuminate\Container\Container.php:805
      Vyuldashev\LaravelOpenApi\OpenApiServiceProvider::Vyuldashev\LaravelOpenApi\{closure}(Object(Illuminate\Foundation\Application), [])

Can anyone help?

Documentation for request bodies and schemas

Do you have any examples of how to use request bodies and schemas?

I’d particularly like to use Schema::ref() to refer to reusable schemas, but haven’t been able to get it to work.

Thanks!

Suggestion for Responses generated off Laravel Resources

I'm trying to define Responses for my Open API Schema.

In my API, all of my controllers use Laravel Resources to define how models are transformed into responses, and which fields are included. So I have, say, 39 Controllers and 18 Resources.

Currently, I now need to define 18 Responses in Laravel OpenAPI.

However, it seems that if I could alter my UserResource class, and simply add a trait, use OpenApiResponse, then I could keep information about my response in the same place.

This would seem to simplify my project, in the same way that every endpoint is defined by a #[OpenApi\Operation(tags: ['User'])] annotation on the controller, I could simply add some annotations and a trait on my resources.

P.S.: Love this tool, it's helping us out a lot.

Support for requiring multiple API Key security requirements

It appears there's no way currently (or at least documented way I can find) to require more than one API Key header for the Security Requirements.

It looks like the OpenAPI documentation specify this is possible: https://swagger.io/docs/specification/authentication/api-keys/

  components:
    securitySchemes:
      apiKey:
        type: apiKey
        in: header
        name: X-API-KEY
      appId:
        type: apiKey
        in: header
        name: X-APP-ID
  security:
    - apiKey: []
      appId:  []   # <-- no leading dash (-)

It would be good if this was supported to allow for requiring more than one security header.

Response attribute must not be repeated error

Hi, I have just upgraded to v1.0.2 from v0 and I'm unable to generate the API doc when there is multiple responses in a single controller method. My code looks like this:

#[OpenApi\Operation(id: 'invitationAccept', tags: ['Invitation'])]
#[OpenApi\Parameters(factory: DefaultHeaderParameters::class)]
#[OpenApi\Response(factory: SuccessResponse::class, statusCode: 200)]
#[OpenApi\Response(factory: BadRequestResponse::class, statusCode: 400)]
public function accept(Invitation $invitation)
{
   ...
}

And I get this error when running the openapi:generate command:

  Attribute "Vyuldashev\LaravelOpenApi\Attributes\Response" must not be repeated

  at vendor/vyuldashev/laravel-openapi/src/RouteInformation.php:84
     80▕             $controllerAttributes = collect($reflectionClass->getAttributes())
     81▕                 ->map(fn(ReflectionAttribute $attribute) => $attribute->newInstance());
     82▕ 
     83▕             $actionAttributes = collect($reflectionMethod->getAttributes())
  ➜  84▕                 ->map(fn(ReflectionAttribute $attribute) => $attribute->newInstance());
     85▕ 
     86▕             $instance->domain = $route->domain();
     87▕             $instance->method = $method;
     88▕             $instance->uri = Str::start($route->uri(), '/');

      +4 vendor frames 
  5   [internal]:0
      Vyuldashev\LaravelOpenApi\Builders\PathsBuilder::Vyuldashev\LaravelOpenApi\Builders\{closure}()

      +18 vendor frames 
  24  artisan:37
      Illuminate\Foundation\Console\Kernel::handle()

My current project is on PHP 8.0, Laravel 8, laravel-openapi 1.0.2. I haven't tested this issue on a fresh laravel installation yet.

[Request] Add attribute Summary

At the moment, most generated requests for OpenApi are done via attributes.
However, the summary is still done via docblock reflection.

I propose to add a summary Attribute to replace docblock reflection.

#[OpenApi\Summary(string: "The summary of the request.")]

This will be used to populate the summary paramter of the request definition.

From my breif look through the code, this would allow the project to drop phpdocumentor/reflection-docblock dependancy

Issue with referenced package version roave/better-reflection ^4.0 - should be ^3.5

Used packages:

  • vyuldashev/laravel-openapi: ^0.18.1

Dev:

  • phpunit/phpunit: ^8.0

The package roave/better-reflection has no version/tag 4.* so it uses dev-master for installation and this is the result:

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Conclusion: remove vyuldashev/laravel-openapi v0.18.1
    - vyuldashev/laravel-openapi v0.18.1 requires roave/better-reflection ^4.0 -> satisfiable by roave/better-reflection[4.0.x-dev].
    - Conclusion: remove roave/better-reflection 4.0.x-dev|keep phpdocumentor/reflection-docblock 4.3.4
    - Conclusion: remove phpdocumentor/reflection-docblock 4.3.4
    - Conclusion: remove phpdocumentor/type-resolver 1.0.1
    - Conclusion: don't install phpdocumentor/type-resolver 1.0.1
    - Conclusion: don't install phpdocumentor/reflection-docblock 4.3.4|don't install roave/better-reflection 4.0.x-dev|install phpdocumentor/reflection-docblock 5.0.0
    - Conclusion: don't install phpdocumentor/reflection-docblock 5.0.0
    - Conclusion: don't install phpdocumentor/reflection-docblock 4.3.3
    - Installation request for vyuldashev/laravel-openapi ^0.18.1 -> satisfiable by vyuldashev/laravel-openapi[v0.18.1].
    - roave/better-reflection 4.0.x-dev requires phpdocumentor/reflection-docblock ^5.0.0 -> satisfiable by phpdocumentor/reflection-docblock[5.0.0, 5.0.0-alpha1, 5.0.0-alpha2, 5.0.0-alpha3, 5.0.0-alpha4, 5.0.0-alpha5, 5.0.0-alpha6, 5.0.0-alpha7, 5.0.0-alpha8, 5.0.0-alpha9, 5.0.0-beta, 5.x-dev].
    - Can only install one of: phpdocumentor/reflection-docblock[5.0.0-alpha6, 4.3.2].
    - Can only install one of: phpdocumentor/reflection-docblock[5.0.0-alpha7, 4.3.2].
    - Can only install one of: phpdocumentor/reflection-docblock[5.0.0-alpha8, 4.3.2].
    - Can only install one of: phpdocumentor/reflection-docblock[5.0.0-alpha9, 4.3.2].
    - Can only install one of: phpdocumentor/reflection-docblock[5.0.0-beta, 4.3.2].
    - Can only install one of: phpdocumentor/reflection-docblock[5.x-dev, 4.3.2].
    - vyuldashev/laravel-openapi v0.18.1 requires phpdocumentor/reflection-docblock ^4.3 -> satisfiable by phpdocumentor/reflection-docblock[4.3.4, 4.3.0, 4.3.1, 4.3.2, 4.3.3].
    - phpdocumentor/reflection-docblock 4.3.0 requires phpdocumentor/type-resolver ^0.4.0 -> satisfiable by phpdocumentor/type-resolver[0.4.0].
    - phpdocumentor/reflection-docblock 4.3.1 requires phpdocumentor/type-resolver ^0.4.0 -> satisfiable by phpdocumentor/type-resolver[0.4.0].
    - phpdocumentor/reflection-docblock 5.0.0-alpha1 requires phpdocumentor/type-resolver ^0 -> satisfiable by phpdocumentor/type-resolver[0.1, 0.1.1, 0.1.2, 0.1.3, 0.1.4, 0.1.5, 0.1.6, 0.1.7, 0.1.8, 0.2, 0.2.1, 0.3.0, 0.4.0, 0.5.0, 0.5.1, 0.6.0, 0.6.1, 0.6.2, 0.6.3, 0.7.0, 0.7.1, 0.7.2, 0.7.x-dev].
    - phpdocumentor/reflection-docblock 5.0.0-alpha2 requires phpdocumentor/type-resolver ^0 -> satisfiable by phpdocumentor/type-resolver[0.1, 0.1.1, 0.1.2, 0.1.3, 0.1.4, 0.1.5, 0.1.6, 0.1.7, 0.1.8, 0.2, 0.2.1, 0.3.0, 0.4.0, 0.5.0, 0.5.1, 0.6.0, 0.6.1, 0.6.2, 0.6.3, 0.7.0, 0.7.1, 0.7.2, 0.7.x-dev].
    - phpdocumentor/reflection-docblock 5.0.0-alpha3 requires phpdocumentor/type-resolver ^0 -> satisfiable by phpdocumentor/type-resolver[0.1, 0.1.1, 0.1.2, 0.1.3, 0.1.4, 0.1.5, 0.1.6, 0.1.7, 0.1.8, 0.2, 0.2.1, 0.3.0, 0.4.0, 0.5.0, 0.5.1, 0.6.0, 0.6.1, 0.6.2, 0.6.3, 0.7.0, 0.7.1, 0.7.2, 0.7.x-dev].
    - phpdocumentor/reflection-docblock 5.0.0-alpha4 requires phpdocumentor/type-resolver ^0 -> satisfiable by phpdocumentor/type-resolver[0.1, 0.1.1, 0.1.2, 0.1.3, 0.1.4, 0.1.5, 0.1.6, 0.1.7, 0.1.8, 0.2, 0.2.1, 0.3.0, 0.4.0, 0.5.0, 0.5.1, 0.6.0, 0.6.1, 0.6.2, 0.6.3, 0.7.0, 0.7.1, 0.7.2, 0.7.x-dev].
    - phpdocumentor/reflection-docblock 5.0.0-alpha5 requires phpdocumentor/type-resolver ^0 -> satisfiable by phpdocumentor/type-resolver[0.1, 0.1.1, 0.1.2, 0.1.3, 0.1.4, 0.1.5, 0.1.6, 0.1.7, 0.1.8, 0.2, 0.2.1, 0.3.0, 0.4.0, 0.5.0, 0.5.1, 0.6.0, 0.6.1, 0.6.2, 0.6.3, 0.7.0, 0.7.1, 0.7.2, 0.7.x-dev].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.4.0].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.5.0].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.5.1].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.6.0].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.6.1].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.6.2].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.6.3].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.7.0].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.7.1].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.7.2].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.7.x-dev].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.1].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.1.1].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.1.2].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.1.3].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.1.4].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.1.5].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.1.6].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.1.7].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.1.8].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.2].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.2.1].
    - Can only install one of: phpdocumentor/type-resolver[1.x-dev, 0.3.0].
    - roave/better-reflection 4.0.x-dev requires phpdocumentor/type-resolver ^1.0.0 -> satisfiable by phpdocumentor/type-resolver[1.0.1, 1.0.0, 1.x-dev].
    - Conclusion: don't install phpdocumentor/type-resolver 1.0.0

My packages at all:

    "require": {
        "php": ">=7.3",
        "ext-json": "*",
        "bensampo/laravel-enum": "^1.26",
        "bschmitt/laravel-amqp": "^2.0",
        "fideloper/proxy": "^4.0",
        "laravel/framework": "^6.0",
        "laravel/tinker": "^1.0",
        "league/flysystem-aws-s3-v3": "^1.0",
        "pion/laravel-chunk-upload": "^1.3",
        "predis/predis": "^1.1",
        "renepardon/amqp-pubsub": "^1.0",
        "vladimir-yuldashev/laravel-queue-rabbitmq": "^10.1",
        "vyuldashev/laravel-openapi": "^0.18.1"
    },
    "require-dev": {
        "barryvdh/laravel-ide-helper": "^2.6",
        "brainmaestro/composer-git-hooks": "^2.8",
        "facade/ignition": "^1.4",
        "fzaninotto/faker": "^1.4",
        "haydenpierce/class-finder": "^0.4.0",
        "mockery/mockery": "^1.0",
        "nunomaduro/collision": "^3.0",
        "nunomaduro/larastan": "^0.4.3",
        "pdepend/pdepend": "^2.5",
        "phing/phing": "^2.16",
        "phploc/phploc": "^5.0",
        "phpmd/phpmd": "^2.7",
        "phpunit/php-code-coverage": "^7.0",
        "phpunit/phpunit": "^8.0",
        "renepardon/laravel-code-generator": "^1.0",
        "renepardon/laravel-code-generator-swagger": "^1.0",
        "sebastian/phpcpd": "^4.1",
        "squizlabs/php_codesniffer": "^3.5"
    },

Collection resource

hi
i got this error while generating:
TypeError Cannot assign Illuminate\Support\Collection to property Vyuldashev\LaravelOpenApi\RouteInformation::$parameters of type array

`null` as an example of nullable field

If I try to set null as an example of some field, it will be ignored.

Example:

Schema::string('foo')
    ->nullable()
    ->example(null),

It will look like this:

"foo": {
    "type": "string",
    "nullable": true
},

But expected:

"foo": {
    "type": "string",
    "nullable": true,
    "example": null
},

It will be correctly rendered using SwaggerUI or Redoc.

image

Scheme not generated

I run php artisan openapi:generate but my schemas in app\OpenApi\Schemas not generated

Resource Controllers and PUT vs. PATCH

When using a resource controller, I see that the documentation shows only PUT requests and no documentation for PATCH requests.

Because of the subtle differences in PUT (full resource data expected) vs. PATCH (partial/changed resource data expected), I’d love to see the ability to specify which one—or both—should be available via the generated documentation.

One potential workaround is to register the API endpoints individually rather than using a resource controller.

Dependency issue with phpDocumentor

Hello,

I've ran into a problem today. While trying to generate the openapi file I had the following error:

trace

TypeResolver is a dependency of ReflectionDocBlock, which is required by this package, I'm not sure if this is an issue related to this package or more on the side of ReflectionDocBlock but I decided to leave it here, maybe this saves other people some time aswell.

This exception only occurs on version 1.7 of TypeResolver, it works just fine on version 1.6.2. Since the update happened just 3 days ago I assume it has to be from the changes related to that.
These changes include a complete refactor of the TypeResolver.php which seems to cause this exception for me.

A quick fix is to add "phpdocumentor/type-resolver": "1.6.2" to your own composer.json.

Unable to install config('openapi.collections') Invalid argument supplied for foreach()

When trying to install using composer require, I receive this error below:

ErrorException 

  Invalid argument supplied for foreach()

  at vendor/vyuldashev/laravel-openapi/routes/api.php:8
      4▕ use Illuminate\Support\Facades\Route;
      5▕ use Vyuldashev\LaravelOpenApi\Http\OpenApiController;
      6▕ 
      7▕ Route::group(['as' => 'openapi.'], function () {
  ➜   8▕     foreach (config('openapi.collections') as $name => $config) {
      9▕         $uri = Arr::get($config, 'route.uri');
     10▕ 
     11▕         if (! $uri) {
     12▕             continue;

      +14 vendor frames 
  15  [internal]:0
      Illuminate\Foundation\Application::Illuminate\Foundation\{closure}()

      +5 vendor frames 
  21  artisan:37
      Illuminate\Foundation\Console\Kernel::handle()

I also tried copying the openapi config file first, but still no luck.

PHP Version: 7.4
Laravel Version: 8.0

Trying to get property 'objectId' of non-object when referencing Parameters

Compiling header parameters into a DeviceController parameter file as it seems only a single parameter annotation is allowed on the route:

class DeviceParameters extends ParametersFactory
{
    /**
     * @return Parameter[]
     */
    public function build(): array
    {
        return [
            AcceptParameters::ref(),
            ApiVersionParameters::ref(),
        ];
    }
}

And here's the example ApiVersionParameters:

class ApiVersionParameters extends ParametersFactory implements Reusable
{
    /**
     * @return Parameter[]
     */
    public function build(): array
    {
        return [

            Parameter::header('ApiVersion')
                ->name('Api-Version')
                ->description('Api Version')
                ->required(true)
                ->schema(Schema::string()->example('1.0')),

        ];
    }
}

Then receive this error on compile:

 Trying to get property 'objectId' of non-object

  at vendor/vyuldashev/laravel-openapi/src/Concerns/Referencable.php:41
     37▕         } elseif ($instance instanceof SecuritySchemeFactory) {
     38▕             $baseRef = '#/components/securitySchemes/';
     39▕         }
     40▕
  ➜  41▕         return Schema::ref($baseRef.$instance->build()->objectId, $objectId);
     42▕     }
     43▕ }
     44▕

      +1 vendor frames
  2   app/OpenApi/Parameters/DeviceParameters.php:21
      Vyuldashev\LaravelOpenApi\Factories\ParametersFactory::ref()

      +4 vendor frames
  7   [internal]:0
      Vyuldashev\LaravelOpenApi\Builders\PathsBuilder::Vyuldashev\LaravelOpenApi\Builders\{closure}(Object(Illuminate\Support\Col
lection), "/device/upgrade-token")

Which makes sense, the Parameters stub returns an array of parameters, but the static ref() is expecting an object.

Perhaps I'm approaching this wrong, open to alternatives! Thanks

CORS issue with docker-image swaggerapi/swagger-ui

TL;DR: Just read the answer if you want to know how to solve a CORS issue with swagger-ui when you're running laravel with open-api in a docker container.


Thanks for making this package, which I got installed without a problem.
I really like the PHP8 Attribute convention-over-configuration approach and want to stick to your package.

Problem:
I want to let a docker-container of the image swaggerapi/swagger-ui run besides the Laravel-container.
The URL of the swagger-ui-container is: http://127.0.0.1:8082.
The URL of your openapi-package within Laravel is: http://127.0.0.1:8080/openapi.

When trying to explore http://127.0.0.1:8080/openapi from the swagger-ui the following error-message is rendered in the browser:
"Possible cross-origin (CORS) issue? The URL origin (http://127.0.0.1:8080) does not match the page (http://127.0.0.1:8082). Check the server returns the correct 'Access-Control-Allow-*' headers".

In the network-log of general Laravel-API-Methods, the response-headers always include a Access-Control-Allow-Origin: *-header.
I'm using "fruitcake/laravel-cors" for that.
In the network-log of your provided URL http://127.0.0.1:8080/openapi the Access-Control-Allow-Origin: * header is missing.

How can I enable that header for your URL?

In config\openapi.php I tried:

'route' => [
    'uri' => '/openapi',
    'middleware' => [
        \Fruitcake\Cors\HandleCors::class,
    ],
],

Conflict error in composer

Hi,

When I try to make a composer require vyuldashev/laravel-openapi I have the following conflict error :

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Can only install one of: phpdocumentor/type-resolver[1.0.1, 0.4.0].
    - Can only install one of: phpdocumentor/type-resolver[0.4.0, 1.0.1].
    - Can only install one of: phpdocumentor/type-resolver[0.4.0, 1.0.1].
    - roave/better-reflection 3.5.0 requires phpdocumentor/type-resolver ^0.4.0 -> satisfiable by phpdocumentor/type-resolver[0.4.0].
    - vyuldashev/laravel-openapi v0.7.0 requires roave/better-reflection ^3.5 -> satisfiable by roave/better-reflection[3.5.0].
    - Installation request for vyuldashev/laravel-openapi ^0.7.0 -> satisfiable by vyuldashev/laravel-openapi[v0.7.0].
    - Installation request for phpdocumentor/type-resolver (locked at 1.0.1) -> satisfiable by phpdocumentor/type-resolver[1.0.1].


Installation failed, reverting ./composer.json to its original content.

Can you check and tell me what's going on ?
Maybe it's since the last update for Laravel 6 ?

Thanks for you answer !

Use Primary Key type as path parameter

Current Behavior

If a Controller function accesses the path variable by model binding (as described here https://laravel.com/docs/9.x/routing#implicit-binding) and doesn't manually specify a path type, it is typed as string.

Requested Behavior

I would suggest to automatically try to type the path variable like the primary key type of the model

Possible Solution

Change the guessFromReflectionType of the SchemaHelpers class to something like this:

public static function guessFromReflectionType(ReflectionType $reflectionType): Schema
    {
        $typeString = $reflectionType->getName();
        if (is_subclass_of($reflectionType->getName(), 'Illuminate\Database\Eloquent\Model')) {
            $modelInstance = new ($reflectionType->getName())();
            $typeString = $modelInstance->getKeyType();
        }
        switch ($typeString) {
            case 'int':
                return Schema::integer();
            case 'bool':
                return Schema::boolean();
        }

        return Schema::string();
    }

Installation fails: Invalid argument supplied for foreach()

When running composer require, it hits this error on api.php line 8. Can't install. Don't have this issue with composer require on any other packages I just tested.

In api.php line 8:
                                           
  Invalid argument supplied for foreach()  
                                           

Script @php artisan package:discover handling the post-autoload-dump event returned with error code 1

Installation failed, reverting ./composer.json and ./composer.lock to their original content.

Non serializable configuration when using global security

When configuring global security it is not posible to use config:cache command as it breaks with the "Your configuration files are not serializable." exception.
At config/openapi.php:
'security' => [ GoldSpecDigital\ObjectOrientedOAS\Objects\SecurityRequirement::create()->securityScheme('oauth2'), ],
Exception:
image

I solved the issue using an array for the security specification, but had to override the GoldSpecDigital\ObjectOrientedOAS\OpenApi class.

PHP7 -> PHP8 (0.x -> 1.0) migration

For anyone wondering how to migrate the docblocks into PHP8 Attributes quickly, this one worked for me:

regex replace: \* @OA\\Operation\(tags=(.*?)\)\n.*?\*/ to */\n#[OA\\Operation(tags: [$1])]

\* @OA\\PathItem\(\)\n .*?\/ to */\n#[OA\\PathItem()]

Maybe it would be a good idea to include this (or maybe even better some modified version that would work in all cases) in a readme/doc somewhere?

Documentation

Please I'd like to know what you used to achieve the documentation for this project. I'm looking for something similar?

Thank you

generate a parameterFactory from a validation request - suggestion of feature

Hello,
To ease my process I have created the start of a command to generate Parameters from a validation request. I think it could be interesting to perhaps add this feature? But, if someone need it or my example could bootstrap something, here is my code (with the possibility of overwrite in mind)

<?php

namespace App\Console\Commands;

use Illuminate\Console\GeneratorCommand;
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Routing\Route;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Illuminate\Validation\ValidationRuleParser;
use Illuminate\Validation\Validator;
use Symfony\Component\Console\Input\InputOption;

class ParametersFactoryMakeCommand extends GeneratorCommand
{
	protected $name = 'mm:make-parameters';
	protected $description = 'Create a new Parameters factory class based on an existing request class';
	protected $type = 'Parameters';

	// @see https://laravel.com/docs/9.x/validation#available-validation-rules
	protected array $mapRules = [
		// @see https://swagger.io/docs/specification/data-models/data-types/
		'Numeric' => ['schema.type' => 'number'],
		'Integer' => ['schema.type' => 'integer'],
		'String' => ['schema.type' => 'string'],
		'Boolean' => ['schema.type' => 'boolean'],
		'Array' => 'mapRuleArray',

		// @see https://swagger.io/docs/specification/describing-parameters/
		'Required' => ['required' => true, 'allowEmptyValue' => false],
		'Present' => ['allowEmptyValue' => true],
		'Prohibited' => ['allowEmptyValue' => true],
		'Filled' => ['allowEmptyValue' => false],
		'Nullable' => ['nullable' => true],
		'In' => 'mapRuleIn',
	];

	protected function getOptions(): array
	{
		return [
			['request', 'r', InputOption::VALUE_OPTIONAL, 'The request class parameters being generated for'],
			['force', null, InputOption::VALUE_NONE, 'Create the class even if the factory already exists'],
			['route', 'R', InputOption::VALUE_OPTIONAL, 'The route name associated to'],
			['action', 'a', InputOption::VALUE_OPTIONAL, 'The route action associated to'],
		];
	}

	protected function getStub(): string
	{
		return resource_path('/stubs/openAPI/parameters.stub');
	}

	protected function buildClass($name)
	{
		$output = parent::buildClass($name);

		$fields = $this->extractFieldFromRequest($this->option('request'));
		$fields += $this->extractFieldFromRouteName($this->option('route'));
		$fields += $this->extractFieldFromRouteAction($this->option('action'));

		$output = $this->buildClassFromFieldsInfos($output, $fields);

		return $output;
	}

	protected function buildClassFromFieldsInfos(string $output, array $fields): string
	{
		$definition = [''];
		$spacer = '			';
		foreach ($fields as $field)
		{
			$definition []= $spacer . $this->assembleField($this->renderField($field, $spacer));
		}

		return str_replace('DummyDefinition', implode(PHP_EOL, $definition), $output);
	}

	protected function getDefaultNamespace($rootNamespace): string
	{
		return $rootNamespace . '\OpenApi\Parameters';
	}

	protected function qualifyClass($name): string
	{
		$name = parent::qualifyClass($name);

		if (Str::endsWith($name, 'Parameters'))
		{
			return $name;
		}

		return $name . 'Parameters';
	}

	protected function buildValidatorFromRequest(string $request): Validator
	{
		try
		{
			/** @var FormRequest $request */
			$request = app($request);
		}
		catch (ValidationException $e)
		{
			return $e->validator;
		}

		// if build of validation doesn't generate any error, we try to build the validator
		// see \Illuminate\Foundation\Http\FormRequest::getValidatorInstance
		/** @var ValidationFactory $factory */
		$factory = app(ValidationFactory::class);
		if (method_exists($request, 'validator'))
		{
			$validator = app()->call([$request, 'validator'], compact('factory'));
		}
		else
		{
			$validator = $factory->make(
				[],
				app()->call([$request, 'rules']),
				$request->messages(),
				$request->attributes(),
			);
		}

		return $validator;
	}

	private function extractRulesFromRequest(string $request): array
	{
		$validator = $this->buildValidatorFromRequest($request);
		$rules = [];
		if (method_exists($validator, 'getRules'))
		{
			$rules = call_user_func([$validator, 'getRules']);
		}
		return $rules;
	}

	protected function mapRule(string $field, string $attribute, string $rule, array $parameters, array $attributeRules): array
	{
		if (array_key_exists($rule, $this->mapRules))
		{
			if (is_array($this->mapRules[ $rule ]))
			{
				return $this->mapRules[$rule];
			}

			return $this->{$this->mapRules[ $rule ]}($field, $attribute, $rule, $parameters, $attributeRules);
		}

		return [];
	}

	protected function mapRuleIn(string $field, string $attribute, string $rule, array $parameters, array $attributeRules): array
	{
		return ['schema.enum' => $parameters];
	}

	protected function mapRuleArray(string $field, string $attribute, string $rule, array $parameters, array $attributeRules): array
	{
		// TODO type array or object => see $attributeRules
		return ['schema.type' => 'array'];
	}

	protected function mapRulesToField(array $fields, string $field, string $attribute, array $attributeRules): array
	{
		foreach ($attributeRules as $rule)
		{
			[$rule, $parameters] = ValidationRuleParser::parse($rule);
			if ($rule === '')
			{
				continue;
			}

			$ruleMapped = $this->mapRule($field, $attribute, $rule, $parameters, $attributeRules);
			$fields[ $field ] = $ruleMapped + $fields[ $field ];
		}

		return $fields;
	}

	protected function renderField(array $field, string $spacer): array
	{
		$field = Arr::undot($field);

		$output = [
			$spacer . 'Parameter::query()',
			$spacer . '	->name(\'' . $field['name'] . '\')',
		];

		if (array_key_exists('required', $field))
		{
			$output []= $spacer . '	->required(' . ($field['required'] ? 'true' : 'false') . ')';
		}

		if (array_key_exists('allowEmptyValue', $field))
		{
			$output []= $spacer . '	->allowEmptyValue(' . ($field['allowEmptyValue'] ? 'true' : 'false') . ')';
		}

		if (array_key_exists('schema', $field))
		{
			$schema = $field['schema'];
			$output []= $spacer . '	->schema(';
			$output = array_merge($output, $this->renderFieldSchema($schema, $spacer . '		'));
			$output []= $spacer . '	)';
		}

		return $output;
	}

	private function assembleField(array $renderField): string
	{
		return '$parameters [] = ' . implode(PHP_EOL, $renderField) . ';';
	}

	protected function renderFieldSchema(array $schema, string $spacer): array
	{
		$output = [];
		$output []= $spacer . 'Schema::' . $schema['type'] . '()';
		if (array_key_exists('enum', $schema))
		{
			$output []= $spacer . '	->enum(' . var_export($schema['enum'], true) . ')';
		}

		return $output;
	}

	protected function extractFieldFromRequest(?string $request): array
	{
		if (!$request)
		{
			return [];
		}

		if (!is_a($request, FormRequest::class, true))
		{
			throw new \InvalidArgumentException('Invalid request, it must be a FormRequest');
		}

		// extract rules from request validator
		$rules = $this->extractRulesFromRequest($request);

		// @see \Illuminate\Validation\Validator::passes
		$fields = [];
		foreach ($rules as $attribute => $attributeRules)
		{
			$field = explode('.', $attribute)[0];
			$fields[ $field ] = $fields[ $field ] ?? ['name' => $field];

			$fields = $this->mapRulesToField($fields, $field, $attribute, $attributeRules);
		}

		return $fields;
	}

	protected function extractFieldFromRouteName(?string $routeName): array
	{
		if (!$routeName)
		{
			return [];
		}

		$route = app('router')->getByName($routeName);
		return $route ? $this->routeToFields($route) : [];
	}

	protected function extractFieldFromRouteAction(?string $action): array
	{
		if (!$action)
		{
			return [];
		}

		$router = app('router')->getRoutes();
		$route = $router->getByAction($action) ?? $router->getByAction('App\\Http\\Controllers\\' . $action);
		return $route ? $this->routeToFields($route) : [];
	}

	protected function routeToFields(Route $route): array
	{
		// $parameters = $route->parameterNames(); // don't give optional parameters
		preg_match_all('/{(.*?)}/', $route->uri, $parameters);
		$parameters = collect($parameters[1]);
		if (count($parameters) > 0)
		{
			$parameters = $parameters->mapWithKeys(static fn ($parameter) => [Str::replaceLast('?', '', $parameter) => [
				'name' => Str::replaceLast('?', '', $parameter),
				'required' => ! Str::endsWith($parameter, '?'),
			]]);
		}

		/** @var \ReflectionParameter $signatureParameter */
		foreach ($route->signatureParameters() as $signatureParameter)
		{
			$parameter = $parameters[ $signatureParameter->getName() ] ?? [
				'name' => $signatureParameter->getName(),
				'required' => $signatureParameter->isOptional(),
			];

			if ($signatureParameter->hasType())
			{
				$type = ucFirst($signatureParameter->getType()->getName());
				if (is_a($type, FormRequest::class, true))
				{
					$parameters = $parameters->union($this->extractFieldFromRequest($type));
					$parameters->offsetUnset($signatureParameter->getName());
					continue;
				}

				if (array_key_exists($type, $this->mapRules) && is_array($this->mapRules[$type]))
				{
					$parameter['type'] = $this->mapRules[$type];
				}
			}

			if (!$parameter['required'])
			{
				$parameter['allowEmptyValue'] = $signatureParameter->isOptional() || $signatureParameter->allowsNull() || $signatureParameter->isDefaultValueAvailable();
			}

			$parameters->put($signatureParameter->getName(), $parameter);
		}

		return $parameters->toArray();
	}
}

Status code from controller it's just ignored

In documentation:
"Even if the schema defines a status code, you must supply the status code in the controller method attributes, or only one response will be included in the result."

Even if I define a custom status code in controller level it's just ignored

No way to add Laravel prebuild controllers

When the Laravel\Sanctum\Http\Controllers\CsrfCookieController is used, there is no way to add it path into schema.

Route list ignore this Controller, because it not contains #[OpenApi\PathItem] and #[OpenApi\Operation] attributes, but I can't add them there, because it is a part of third-party package.

I have to make my own extension of that controller, also part of code, that automagicaly register them to route and so one...

It will be useful to have a possibility to setup this attributes also externally in the openapi.php config file.

Documentation: How to extend a schema?

Looking for documentation on how to extend an existing reusable schema.

Would the ideal solution be to to use openapi $ref and then additional properties?

Missing documentation

Great package!

Missing documentation for Collections and Middlewares.

Can we have a rudimentary description for these and how they're used?
The only information we have is a comment in the config for the middlewares but it isn't much help.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.