GithubHelp home page GithubHelp logo

dedoc / scramble Goto Github PK

View Code? Open in Web Editor NEW
960.0 960.0 87.0 1.4 MB

Modern Laravel OpenAPI (Swagger) documentation generator. No PHPDoc annotations required.

Home Page: https://scramble.dedoc.co/

License: MIT License

PHP 99.59% Blade 0.41%
api generator laravel openapi swagger

scramble's Introduction

Scramble – Laravel API documentation generator

Scramble

Scramble generates API documentation for Laravel project. Without requiring you to manually write PHPDoc annotations. Docs are generated in OpenAPI 3.1.0 format.

Warning Package is in early stage. It means there may be bugs and API is very likely to change. Create an issue if you spot a bug. Ideas are welcome.

Documentation

You can find full documentation at scramble.dedoc.co.

Introduction

The main motto of the project is generating your API documentation without requiring you to annotate your code.

This allows you to focus on code and avoid annotating every possible param/field as it may result in outdated documentation. By generating docs automatically from the code your API will always have up-to-date docs which you can trust.

Installation

You can install the package via composer:

composer require dedoc/scramble

Usage

After install you will have 2 routes added to your application:

  • /docs/api - UI viewer for your documentation
  • /docs/api.json - Open API document in JSON format describing your API.

By default, these routes are available only in local environment. You can change this behavior by defining viewApiDocs gate.


Donate

scramble's People

Contributors

alexsabur avatar andreas02-dev avatar hn-seoai avatar jeffreyvanhees avatar joligoms avatar kburton-dev avatar kennyhorna avatar kichetof avatar layerok avatar manuel-watchenterprise avatar neorej avatar peterbrinck avatar princejohnsantillan avatar rolexam avatar romalytvynenko avatar rra3b avatar sc-bruno avatar timschwartz avatar tontonsb avatar wildego avatar

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

scramble's Issues

Add `uuid` validation rule support

<?php

namespace App\Http\Requests\API\Item;

use Illuminate\Foundation\Http\FormRequest;

class StoreItemRequest extends FormRequest
{
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'section_id' => ['required', 'uuid', 'exists:App\Models\Section,id'],
            'item_catalog_id' => ['required', 'uuid', 'exists:App\Models\ItemCatalog,id'],
            'value' => ['required', 'numeric'],
            'number_required' => ['nullable', 'numeric'],
            'line_value' => ['nullable', 'numeric']
        ];
    }
}

Originally posted by @marcusr21 in #25 (reply in thread)

Document could not be loaded

Discussed in #118

Originally posted by skills-up March 31, 2023
Getting this error while trying to visit /docs/api

The API description document could not be fetched. This could indicate connectivity problems, or issues with the server hosting the spec.

NGINX log shows this:

open() "/docs/api.json" failed (2: No such file or directory)

However, when I visit /docs/api.json then the JSON is visible alright.

How do I resolve this error?

Subdomain API routes are not documented properly

Hello!

I have a tenant-aware application that has subdomains for each team. There are API routes that are for central (without subdomain) and there are API routes that have a subdomain to them.

I use this code in the route service provider:

Route::prefix('api/v1')
            ->middleware('api:team')
            ->domain('{subdomain}.' . config('app.domain'))
            ->group(base_path('routes/team/api.php'));

The problem is that in the documentation it does not add that {subdomain} parameter to the URL but as a request parameter. This is then not a proper route and a 404 error occurs.

The documentation request, response:
Screenshot_20221114_154644

The displayed URL:
Screenshot_20221114_154801

But it should be:

https://{subdomain}.carbon.test/api/v1/starcrest/user

Add `operationId` support

By default, use @operationId php doc tag value. If it is not set, use route name, if it is not set, use {base controller name}.{method name} convention.

If using route name, maybe consider removing name prefix if some is set on API level.

So for an action \App\Http\Controllers\EventsController@store the operation id would be events.store if route has no name and @operationId tag.

Add support for multiple responses

While 200 responses are the nicest responses to get, in reality many statuses can be returned from the controller. Add a support for multiple statuses responses.

if ($errors) {
    return response()->json(['error' => $errors], 500);
}

return new UserResource(...);

Default config file causes error

Steps to reproduce:

  1. Install scramble in clean Jetstream project
  2. Publish scramble config
  3. Run php artisan serve
In UrlGenerator.php line 121:

  Illuminate\Routing\UrlGenerator::__construct(): Argument #2 ($request) must be of type Illuminate\Http\Request, null given, called in /Users/**redacted**/vendor/laravel/framew
  ork/src/Illuminate/Routing/RoutingServiceProvider.php on line 67

Commenting out the 'api_base_url' line fixes it

Call to a member function toArray() on null in file

The function toArray() in files Dedoc\Scramble\Support\Generator\Combined\AnyOf and Dedoc\Scramble\Support\Generator\Combined\AllOf is not null safe and can throw unexpected errors. Adding null safe operator seems to solve the issue

fn ($item) => $item?->toArray(),

JsonResource toArray method type hint

Hi there,

Thank you for this great package!

Probably not a bug, since the laravel JsonResource class toArray method does not use a type hint. But it seems like the JsonResource is only resolving the model fields, when the toArray method has no type hint.

This works:

class TodoItemResource extends JsonResource
{
    public function toArray()
    {
        return [
            'id' => $this->id,
        ];
    }
}

This shows body of TodoItemResource as string:

class TodoItemResource extends JsonResource
{
    public function toArray(): array
    {
        return [
            'id' => $this->id,
        ];
    }
}

Just wondering why this makes a difference?

Allow adding responses description

Response description would be added as a comment right before return in the controller's action. In most simple case it would look like this:

// A client error has occurred. One possible cause is that something went wrong.
return response()->json([], 400);

In some more complex cases, you would be able to add response code and response body as well:

/**
 * A client error has occurred. One possible cause is that something went wrong.
 * 
 * @code 400
 * @body array{code: int, message: string}
 */ 
return some_not_analyzable_code();

Add support for `Validator` facade when validating request data

A common way to validate request (other than validate call on $this and $request) is to use Validator facade directly on the requests payload:

$validator = Validator::make($request->all(), [
    'email' => 'required|email|exists:users,email'
]);

if ($validator->fails()) {
    return response()->json(['error' => $validator->errors()], 401);
}

P.S.: Notice how make is not doing validation itself. Not sure this should be handled though. Maybe make is enough.

Improve `array` validation rule

These cases aren't handled correctly:

$request->validate([
    'foo' => 'array',
    'foo.id' => 'int',
]);


$request->validate([
    'destination' => 'array:lat,lon|required',
    'destination.lat' => 'numeric|required|min:54|max:60',
    'destination.lon' => 'numeric|required|min:20|max:28.5',
]);

Add an ability to exclude a route from security

Using annotation @unathenticated on the route doc.


Hi there, again!

I've been reading this discussion which I found useful as I want to inform our third parties that they have to authenticate through /api/login before continuing with future requests. As docs says, the problem is that EVERY request has to be authenticated.

It would be nice that the plugin checks routes/api.php routes in order to know which routes are protected or to allow us to customize the security function/scheme in order to set which routes are excluded or included in security. Actually, I didn't find anything related in docs or in PHP files, so I dont know if that is possible right now.

Thanks for your time and effort! 👍

Best regards,
D.

Originally posted by @DaGLiMiOuX in #37

[crash] declare(strict_types=1) breaks Eloquent Resource response generation

context: I have an API that returns Eloquent Resources. The response type parser fails, as the type resolved seems to lose context of the fully qualified class name of the resource (namespace is dropped). This results in a fatal error when the JsonResourceTypeToSchema class attempts to read the $wrap property.

The context of the fully qualified name is lost in JsonResourceTypeToSchema.php on line 150 when $type = $this->infer->analyzeClass($type->name); is invoked.

relevant stack-trace:

"message": "Class \"CartResource\" not found",
    "exception": "Error",
    "file": "/var/www/vendor/dedoc/scramble/src/Support/TypeToSchemaExtensions/JsonResourceTypeToSchema.php",
    "line": 161,
    "trace": [
        {
            "file": "/var/www/vendor/dedoc/scramble/src/Support/Generator/TypeTransformer.php",
            "line": 256,
            "function": "toResponse",
            "class": "Dedoc\\Scramble\\Support\\TypeToSchemaExtensions\\JsonResourceTypeToSchema",
            "type": "->"
        },
        {
            "function": "Dedoc\\Scramble\\Support\\Generator\\{closure}",
            "class": "Dedoc\\Scramble\\Support\\Generator\\TypeTransformer",
            "type": "->"
        },
        {
            "file": "/var/www/vendor/dedoc/scramble/src/Support/Generator/TypeTransformer.php",
            "line": 261,
            "function": "array_reduce"
        },
        {
            "file": "/var/www/vendor/dedoc/scramble/src/Support/Generator/TypeTransformer.php",
            "line": 208,
            "function": "handleResponseUsingExtensions",
            "class": "Dedoc\\Scramble\\Support\\Generator\\TypeTransformer",
            "type": "->"
        },
        {
            "file": "/var/www/vendor/dedoc/scramble/src/Support/OperationExtensions/ResponseExtension.php",
            "line": 31,
            "function": "toResponse",
            "class": "Dedoc\\Scramble\\Support\\Generator\\TypeTransformer",
            "type": "->"
        },
        {
            "function": "Dedoc\\Scramble\\Support\\OperationExtensions\\{closure}",
            "class": "Dedoc\\Scramble\\Support\\OperationExtensions\\ResponseExtension",
            "type": "->"
        },
        {
            "file": "/var/www/vendor/laravel/framework/src/Illuminate/Collections/Arr.php",
            "line": 560,
            "function": "array_map"
        },
        {
            "file": "/var/www/vendor/laravel/framework/src/Illuminate/Collections/Collection.php",
            "line": 739,
            "function": "map",
            "class": "Illuminate\\Support\\Arr",
            "type": "::"
        },
        {
            "file": "/var/www/vendor/dedoc/scramble/src/Support/OperationExtensions/ResponseExtension.php",
            "line": 31,
            "function": "map",
            "class": "Illuminate\\Support\\Collection",
            "type": "->"
        },
        {
            "file": "/var/www/vendor/dedoc/scramble/src/Support/OperationBuilder.php",
            "line": 28,
            "function": "handle",
            "class": "Dedoc\\Scramble\\Support\\OperationExtensions\\ResponseExtension",
            "type": "->"
        },
        {
            "file": "/var/www/vendor/dedoc/scramble/src/Generator.php",
            "line": 146,
            "function": "build",
            "class": "Dedoc\\Scramble\\Support\\OperationBuilder",
            "type": "->"
        },
        {
            "file": "/var/www/vendor/dedoc/scramble/src/Generator.php",
            "line": 42,
            "function": "routeToOperation",
            "class": "Dedoc\\Scramble\\Generator",
            "type": "->"
        },
        {
            "function": "Dedoc\\Scramble\\{closure}",
            "class": "Dedoc\\Scramble\\Generator",
            "type": "->"
        },
        {
            "file": "/var/www/vendor/laravel/framework/src/Illuminate/Collections/Arr.php",
            "line": 560,
            "function": "array_map"
        },
        {
            "file": "/var/www/vendor/laravel/framework/src/Illuminate/Collections/Collection.php",
            "line": 739,
            "function": "map",
            "class": "Illuminate\\Support\\Arr",
            "type": "::"
        },
        {
            "file": "/var/www/vendor/dedoc/scramble/src/Generator.php",
            "line": 53,
            "function": "map",
            "class": "Illuminate\\Support\\Collection",
            "type": "->"
        },
        {
            "file": "/var/www/vendor/dedoc/scramble/routes/web.php",
            "line": 8,
            "function": "__invoke",
            "class": "Dedoc\\Scramble\\Generator",
            "type": "->"
        },

OpenAPI info block

Hi there,

First of all let me thank you for this amazing package. Is so easy to use and very useful. We recently had to implement OpenAPI for a project and we were using OpenAPI package from Laravel-OpenAPI and was really painful to create doc blocks, create OpenAPI classes for each OpenAPI section, etc.

Btw, I didn't find any information about how to configure info block in dedoc/scramble package documentation. I don't know if that is possible via config file or something like that, but would be awesome. I ask it, because I would like to change the version in info block of the OpenAPI JSON string.

Searching in the sources, I've found this line of code in Generator.php:

// Generator.php
$openApi = OpenApi::make('3.1.0')
            ->setComponents($this->transformer->getComponents())
            ->setInfo(InfoObject::make(config('app.name'))->setVersion('0.0.1'));

And would be nice to have something like this:

// Generator.php
$openApi = OpenApi::make('3.1.0')
            ->setComponents($this->transformer->getComponents())
            ->setInfo(InfoObject::make(config('app.name'))->setVersion(config('scramble.info.version')));
// config/scramble.php
return [
    // ...
    'info' => [
        'version': env('OPENAPI_INFO_VERSION', '0.0.1'),
    ]
];

This was just an example, but I hope you get the idea.

Thanks for your time on reading this.

Best regards,
D.

Add support for a response created from `response()->` calls

It is common to create responses using response()->... call. More than that, these calls should be pretty easy to analyze and implement.

For example, call to response()->noContent() creates 204 empty response. Very common for DELETE endpoints. response()->json([/* content */], $status) is another example of the response.

Abort helpers do not add response code to the responses section

If using the abort helpers (abort, abort_if, abort_unless), the exception is not added to the responses.

Code example:

public function register(Request $request, Device $device)
{
    $validated = $request->validate(['name' => 'required|string']);

    abort_if($device->registered_at, 400, 'The given device has been already registered.');

    $device->update(array_merge($validated, [
        'registered_at' => now(),
        'last_seen_at' => now(),
    ]));

    return $device->fresh();
}

Docs:
Screenshot_20221130_115449

Root path rules wors wrong

'' => 'array',
'*' => 'int',

In Laravel validation it works like array<int>, but package think that it is array{array<string>, *: integer}.
If write

'.' => 'array',
'.*' => 'int',

than package think that it is array<int>, but it is wrong too)

Not reading app url from env

On my local environment this is fine, but when i go to dev, stage or prod they all force https, due to the package not reading url from the App url from env or config, the url is http which results in errors

Using $this->whenLoaded causes 502 Bad Gateway

No idea why this is happening, but using $this->whenLoaded() in a HTTP Resources causes the /docs/api.json route to throw a 502 Bad Gateway error. Example Resource:

public function toArray($request)
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        'subareas' => $this->subareas,
        'schools' => SchoolResource::collection($this->whenLoaded('schools')),
    ];
}

I've tried debugging but can't really seem to grasp it.

TypeError modelType Return value must be of type Type

I am getting this error when I open the scramble page, Unfortunetely I didnt got time to debug it yet, just pasting it here, peraphs anyone know what can it be and is easy fixeble, otherway I will try to debug it later

TypeError: Dedoc\Scramble\Support\InferExtensions\JsonResourceTypeInfer::modelType(): Return value must be of type Dedoc\Scramble\Support\Type\Type, null returned in file /var/www/vendor/dedoc/scramble/src/Support/InferExtensions/JsonResourceTypeInfer.php on line 120

#0 /var/www/vendor/dedoc/scramble/src/Support/InferExtensions/JsonResourceTypeInfer.php(39): Dedoc\Scramble\Support\InferExtensions\JsonResourceTypeInfer::modelType()
#1 /var/www/vendor/dedoc/scramble/src/Infer/Handler/ExpressionTypeInferringExtensions.php(29): Dedoc\Scramble\Support\InferExtensions\JsonResourceTypeInfer->getType()
#2 [internal function]: Dedoc\Scramble\Infer\Handler\ExpressionTypeInferringExtensions->Dedoc\Scramble\Infer\Handler{closure}()
#3 /var/www/vendor/dedoc/scramble/src/Infer/Handler/ExpressionTypeInferringExtensions.php(35): array_reduce()
#4 /var/www/vendor/dedoc/scramble/src/Infer/TypeInferringVisitor.php(95): Dedoc\Scramble\Infer\Handler\ExpressionTypeInferringExtensions->leave()
#5 /var/www/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(153): Dedoc\Scramble\Infer\TypeInferringVisitor->leaveNode()
#6 /var/www/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(223): PhpParser\NodeTraverser->traverseNode()
#7 /var/www/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(114): PhpParser\NodeTraverser->traverseArray()
#8 /var/www/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(146): PhpParser\NodeTraverser->traverseNode()
#9 /var/www/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(223): PhpParser\NodeTraverser->traverseNode()
#10 /var/www/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(114): PhpParser\NodeTraverser->traverseArray()
#11 /var/www/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(223): PhpParser\NodeTraverser->traverseNode()
#12 /var/www/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(114): PhpParser\NodeTraverser->traverseArray()
#13 /var/www/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(223): PhpParser\NodeTraverser->traverseNode()
#14 /var/www/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(91): PhpParser\NodeTraverser->traverseArray()
#15 /var/www/vendor/dedoc/scramble/src/Support/ClassAstHelper.php(59): PhpParser\NodeTraverser->traverse()
#16 /var/www/vendor/dedoc/scramble/src/Support/ClassAstHelper.php(40): Dedoc\Scramble\Support\ClassAstHelper->init()
#17 /var/www/vendor/dedoc/scramble/src/Infer/Infer.php(34): Dedoc\Scramble\Support\ClassAstHelper->__construct()
#18 /var/www/vendor/dedoc/scramble/src/Infer/Infer.php(29): Dedoc\Scramble\Infer\Infer->traverseClassAstAndInferType()
#19 /var/www/vendor/dedoc/scramble/src/Support/TypeToSchemaExtensions/JsonResourceTypeToSchema.php(107): Dedoc\Scramble\Infer\Infer->analyzeClass()
#20 /var/www/vendor/dedoc/scramble/src/Support/Generator/TypeTransformer.php(257): Dedoc\Scramble\Support\TypeToSchemaExtensions\JsonResourceTypeToSchema->toResponse()
#21 [internal function]: Dedoc\Scramble\Support\Generator\TypeTransformer->Dedoc\Scramble\Support\Generator{closure}()
#22 /var/www/vendor/dedoc/scramble/src/Support/Generator/TypeTransformer.php(262): array_reduce()
#23 /var/www/vendor/dedoc/scramble/src/Support/Generator/TypeTransformer.php(209): Dedoc\Scramble\Support\Generator\TypeTransformer->handleResponseUsingExtensions()
#24 /var/www/vendor/dedoc/scramble/src/Support/OperationExtensions/ResponseExtension.php(31): Dedoc\Scramble\Support\Generator\TypeTransformer->toResponse()
#25 [internal function]: Dedoc\Scramble\Support\OperationExtensions\ResponseExtension->Dedoc\Scramble\Support\OperationExtensions{closure}()
#26 /var/www/vendor/laravel/framework/src/Illuminate/Collections/Arr.php(560): array_map()
#27 /var/www/vendor/laravel/framework/src/Illuminate/Collections/Collection.php(739): Illuminate\Support\Arr::map()
#28 /var/www/vendor/dedoc/scramble/src/Support/OperationExtensions/ResponseExtension.php(31): Illuminate\Support\Collection->map()
#29 /var/www/vendor/dedoc/scramble/src/Support/OperationBuilder.php(21): Dedoc\Scramble\Support\OperationExtensions\ResponseExtension->handle()
#30 /var/www/vendor/dedoc/scramble/src/Generator.php(121): Dedoc\Scramble\Support\OperationBuilder->build()
#31 /var/www/vendor/dedoc/scramble/src/Generator.php(39): Dedoc\Scramble\Generator->routeToOperation()
#32 [internal function]: Dedoc\Scramble\Generator->Dedoc\Scramble{closure}()
#33 /var/www/vendor/laravel/framework/src/Illuminate/Collections/Arr.php(560): array_map()
#34 /var/www/vendor/laravel/framework/src/Illuminate/Collections/Collection.php(739): Illuminate\Support\Arr::map()
#35 /var/www/vendor/dedoc/scramble/src/Generator.php(44): Illuminate\Support\Collection->map()
#36 /var/www/vendor/dedoc/scramble/routes/web.php(8): Dedoc\Scramble\Generator->__invoke()
#37 /var/www/vendor/laravel/framework/src/Illuminate/Routing/CallableDispatcher.php(40): Illuminate\Support\ServiceProvider->{closure}()
#38 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php(237): Illuminate\Routing\CallableDispatcher->dispatch()
#39 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php(208): Illuminate\Routing\Route->runCallable()
#40 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(798): Illuminate\Routing\Route->run()
#41 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\Routing\Router->Illuminate\Routing{closure}()
#42 /var/www/vendor/dedoc/scramble/src/Http/Middleware/RestrictedDocsAccess.php(12): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}()
#43 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Dedoc\Scramble\Http\Middleware\RestrictedDocsAccess->handle()
#44 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}()
#45 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Routing\Middleware\SubstituteBindings->handle()
#46 /var/www/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}()
#47 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\View\Middleware\ShareErrorsFromSession->handle()
#48 /var/www/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}()
#49 /var/www/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\Session\Middleware\StartSession->handleStatefulRequest()
#50 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Session\Middleware\StartSession->handle()
#51 /var/www/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}()
#52 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle()
#53 /var/www/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}()
#54 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Cookie\Middleware\EncryptCookies->handle()
#55 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}()
#56 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(799): Illuminate\Pipeline\Pipeline->then()
#57 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(776): Illuminate\Routing\Router->runRouteWithinStack()
#58 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(740): Illuminate\Routing\Router->runRoute()
#59 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(729): Illuminate\Routing\Router->dispatchToRoute()
#60 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(190): Illuminate\Routing\Router->dispatch()
#61 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http{closure}()
#62 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}()
#63 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle()
#64 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull->handle()
#65 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}()
#66 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle()
#67 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Middleware\TrimStrings->handle()
#68 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}()
#69 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Middleware\ValidatePostSize->handle()
#70 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}()
#71 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance->handle()
#72 /var/www/vendor/fruitcake/laravel-cors/src/HandleCors.php(38): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}()
#73 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Fruitcake\Cors\HandleCors->handle()
#74 /var/www/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(39): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}()
#75 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Http\Middleware\TrustProxies->handle()
#76 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}()
#77 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(165): Illuminate\Pipeline\Pipeline->then()
#78 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(134): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter()
#79 /var/www/public/index.php(52): Illuminate\Foundation\Http\Kernel->handle()
#80 {main}
-->

Add ability to document request body params (in validation rules): allow overriding a rule, adding description, and example

$request->validate([
    /**
     * A foo property.
     *
     * @example 'bar'
     */
    'foo' => 'string',
]);

Or simply like so without an example:

$request->validate([
    /** A foo property. */
    'foo' => 'string',
]);

Users should be able to override the type as well:

$request->validate([
    /**
     * @var array{bar: string}
     */
    'foo' => 'array',
]);

Questions

What about comments support?

Seems like this needs to be supported too, because of responses documenting.

$request->validate([
    // A foo property.
    'foo' => 'string',
]);

Route param type is not changed by PhpDoc

Version: 0.7.2
Goal: change route param from integer to string

route: Route::put('/api/professions/{profession}', UpdateProfessionController::class)->middleware(['role:MANAGER']);

controller:

/**
* @tags Profession
*/
class UpdateProfessionController extends Controller
{
   /**
    * Update Profession
    * 
    * @param string $profession Profession ID which is of type UUID
    */
   public function __invoke(ProfessionStoreRequest $request, Profession $profession)
   {
       $profession->update($request->only('name'));

       return response()->json(null);
   }
}

model:

class Profession extends Model
{
   use HasUuids, HasFactory;

   protected $fillable = [
       'id',
       'name',
       'status',
   ];

   protected $casts = [
       'status' => ProfessionStatus::class,
   ];
}

image

So as you can see despite having PhpDoc in controller, param is always marked as integer in dashboard and json documentation. I can still send string in this field, but in my particular case I use another tool to generate typescript classes from documentation so I finish with this field marked as number in typescript. It is also worth noticing that description of this field which is in the same line in controller PhpDoc is correct.

Models responses and schemas support

Add model support to the schemas and responses.

It is common to return models right from the controller.

public function show(User $user)
{
    return $user;
}

When it is possible to infer returned var type (like in example), this also can be documented automatically.

It may be pretty complex to implement as it required var type tracking.

Configurable API domain

We have one application where we use a subdomain for the api. It would be good to have an option to configure the domain for the api and maybe an option for the docs path.


'api_domain' => env('API_DOMAIN'),
'api_path' => '',
'docs_path => 'docs'

If the domain is set, the routes could be filtered by default:


Scramble::routes(fn (Route $route) => $route->getDomain() === config('scramble.api_domain'));

Originally posted by @m-lotze in #45

Does not work without `doctrine/dbal`

The docs imply that scramble will function without doctrine/dbal, just the types won't be shown correctly:

Without the doctrine/dbal, Scramble won't know the types of model attributes, so they will be shown as string in resulting docs.

Instead, the request to docs/api.json returns the following message:

LogicException: doctrine/dbal package is not installed. It is needed to get model attribute types. in file /path/to/project/vendor/dedoc/scramble/src/Support/ResponseExtractor/ModelInfo.php on line 73

Documenting responsable exceptions as responses (401, 422, 404)

  Hi,

If it is possible it would be great to have another response when a Laravel Request object has been used in the controller for request validation.
For example a CreateUserRequest contains some rules and messages to check the request. If it fails Laravel automatically return with an exception based on the rule messages. This is really important to put this information into the API doc.

Thanks,

Originally posted by @szana8 in #46

If model uses a different database connection, then for that model all values will be "string"

I'm using two database connections: mysql and mssql. MySQL is the primary connection, but the MS SQL connection is a dynamic one set from each tenant.

I'm having issues where creating a resource, all the listed values would be "string" type, ignoring the real types. Also, they are all required, even though that is not true.

I have a custom model, where I am overriding the getConnectionName() method.

I looked into writing a type extension, but the documentation isn't that great around this.

Here's how it looks in Stoplight:
Screenshot_20221130_112222

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.