#scrambledrop: Scramble 0.12.31
September 4, 2025
Improved request parameters documentation, improved API responses documentation (headers, links support, etc), better type inference.
Hey Laravel community!
This summer Scramble got much smarter under the hood while also adding long overdue full OpenAPI compliant responses support. This allows you to document responses better: you can add headers documentation, links, etc.
Scramble is a Laravel API documentation generator that creates docs without requiring PHPDoc annotations: https://scramble.dedoc.co/introduction.
Now, let’s take a look at the most notable changes.
Using static analysis for request parameters documentation
Scramble creates request API documentation by analyzing the validation rules (not only that, but it doesn’t matter for this part). Validation rules essentially describe the possible shape of a request and hence are such a good source for API documentation.
The thing is, Scramble doesn’t run your route code! So how does it know the rules? This is a bit of a tedious process. But long story short, by analyzing the source code of the controller method, Scramble “finds” the part of the code where rules are defined (it can be an argument to validate
method calls, the form request, etc).
Consider this example:
$request->validate([ // The parameter documentation. 'foo' => ['required', 'integer'],]);
Scramble will find rules’ source:
[ // The parameter documentation. 'foo' => ['required', 'integer']]
But the issue is that at this point internally this is just source code, not the array that can be easily analyzed. So Scramble attempts to evaluate them. In this simple case the evaluation will be successful and Scramble will have the array of rules.
After this, Scramble has both the value of the rules array which is used to document the structure, and the source of rules which is used to get the manual documentation of rules.
But sometimes the real code is more complex.
For example, composing multiple form requests into one:
class BasePayoutFormRequest{ public function rules() { return [ // The amount that must be payed. 'amount' => ['required', 'int'], ]; }}
class PaypalPayoutFormRequest extends BasePayoutFormRequest{ public function rules() { return [ ...parent::rules(),
// The receiver of the payout. 'email' => ['required', 'email'], ]; }}
Previously, when Scramble analyzed PaypalPayoutFormRequest
, it still got the correct shape (due to invoking the rules
method), but it would lose the manual documentation of the amount
property, keeping only the email
property documentation.
This happened because there is no amount
property in PaypalPayoutFormRequest@rules
source code so Scramble couldn’t get the documentation for it.
The new release fixes this by relying on type inference of rules instead. The type inference in this case will have both amount
and email
properties, including the comments that were added in the source code. Thanks to this, manual documentation is not lost even for properties that are defined in other places.
Responses documentation improvements
The set of Scramble summer releases also brings a ton of improvements to response documentation. Now, Scramble supports the OpenAPI specification in regards to responses. So it became possible to document response headers, links, etc.
Also, new attributes were introduced so you can manually add headers and response documentation.
Manual headers documentation:
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;use App\Http\Requests\PaypalPayoutFormRequest;use App\Http\Resources\CampaignResource;use App\Models\Campaign;use Dedoc\Scramble\Attributes\Header;
class CampaignsController extends Controller{ #[Header('X-RateLimit-Limit', 'The amount of requests allowed per minute', 'int')] public function store(PaypalPayoutFormRequest $request) { return CampaignResource::make( Campaign::create($request->all()) ); }}
Manual response documentation:
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;use App\Exports\CampaignPerformanceExport;use Dedoc\Scramble\Attributes\Response;use Maatwebsite\Excel\Excel;
class CampaignsController extends Controller{ #[Response(200, 'Campaign performance report', 'application/vnd.ms-excel')] public function __invoke() { return Excel::download(new CampaignPerformanceExport, 'campaign-performance.xlsx'); }}
Stream and download responses inference
Now, when returning streamed and file responses, Scramble will infer the detailed return type and document the correct response.
These ResponseFactory
methods automatic documentation is supported:
response()->file(...)
response()->download(...)
response()->stream(...)
response()->streamJson(...)
response()->streamDownload(...)
response()->eventStream(...)
Deep setters analysis
When analyzing method calls, Scramble now infers much more useful type information thanks to deeper setter analysis.
Consider this example:
class Foo{ property int $foo;
public function __construct() { $this->setFoo(42); }
public function setFoo(int $foo): self { $this->foo = $foo; return $this; }}
Previously, Scramble correctly inferred that new Foo()
produces a Foo<42>
.
However, if you move the setter call into a setup
method, Scramble used to lose that information:
class Foo{ property int $foo;
public function __construct() { $this->setup(); }
private function setup(): void { $this->setFoo(42); }
public function setFoo(int $foo): self { $this->foo = $foo; return $this; }}
In this case, Scramble would no longer know that $foo
had been set to 42
.
The summer releases fix that: the example above now works perfectly as expected. Deep setter analysis applies not only in __construct
but in any class method.
This enhancement makes Scramble more accurate across a broader range of codebases, letting you focus on your business logic instead of adding extra annotations.
Other changes
- Improve API resources and resource collections inference and documentation by @romalytvynenko in https://github.com/dedoc/scramble/pull/937
- Add ability to configure inference (internal) by @romalytvynenko in https://github.com/dedoc/scramble/pull/940
- Add support for transforming inferred paginator types by @romalytvynenko in https://github.com/dedoc/scramble/pull/931
- Add support for transforming response type with headers to schema and improve collection responses type to schema transformation by @romalytvynenko in https://github.com/dedoc/scramble/pull/932
- Add support for
system
color theme by @macbookandrew in https://github.com/dedoc/scramble/pull/923 - Fixed Scramble silently logs error when
mixed
used in a function return type hint by @romalytvynenko in https://github.com/dedoc/scramble/pull/920 - Preserve enum cases description when adding description to enum class or properties where enum is used by @romalytvynenko in https://github.com/dedoc/scramble/pull/926
- Fixed duplicated schemas in generated spec when using FQN with leading slash in PHPDoc by @romalytvynenko in https://github.com/dedoc/scramble/pull/929
- Fixed document serialization issue when response is removed from components by @romalytvynenko in https://github.com/dedoc/scramble/pull/930
- Fixed
ClassConstFetchTypeGetter
breaking when fetchingclass
const onnew
expression by @romalytvynenko in https://github.com/dedoc/scramble/pull/918 - Added
'present'
validation rule support by @chrisvanlier2005 in https://github.com/dedoc/scramble/pull/915 - Change extensions order to handle custom inference extensions before default inference extensions by @chrisvanlier2005 in https://github.com/dedoc/scramble/pull/831
- Reference type resolver cleanup by @romalytvynenko in https://github.com/dedoc/scramble/pull/909
- Add support for adding custom headers to responses by @romalytvynenko in https://github.com/dedoc/scramble/pull/884
- Fixed issue when analyzing properties of internal classes by @romalytvynenko in https://github.com/dedoc/scramble/pull/886
- Fixed empty
api_path
config was not matching any routes by @romalytvynenko in https://github.com/dedoc/scramble/pull/889 - Improved documentation of complex query parameters (arrays, objects) by @romalytvynenko in https://github.com/dedoc/scramble/pull/890
- Added response attribute by @romalytvynenko in https://github.com/dedoc/scramble/pull/894
- Added
between
validation rule support by @romalytvynenko in https://github.com/dedoc/scramble/pull/895 - Simplified header attribute behavior by @romalytvynenko in https://github.com/dedoc/scramble/pull/896
- Fixed response type parsing with correct PHPDoc file name context by @romalytvynenko in https://github.com/dedoc/scramble/pull/898
- Preparation for the next release by @romalytvynenko in https://github.com/dedoc/scramble/pull/899
- Added support for binary and streamed responses automatic documentation by @romalytvynenko in https://github.com/dedoc/scramble/pull/901
- Cleaned up reference resolver (moved away vendor analysis responsibility) by @romalytvynenko in https://github.com/dedoc/scramble/pull/903
Thanks!
Give Scramble 0.12.31 a try and let me know what you think! Thanks for checking this post out. If you have any questions, ideas, suggestions, feel free to drop me a line to roman@dedoc.co