#scrambledrop: Scramble 0.11.30

#scrambledrop: Scramble 0.11.30

December 12, 2024

File uploads, JSON API updates, all pagination types support & more.

Since the latest update post about Scramble, a ton of improvements have been shipped as minor versions bumps. These include support for file uploads, more comprehensive JSON API resource handling, better pagination documentation, and more!

File uploads

Thanks to a contribution from @yvoitenko, Scramble now supports file uploads directly in the API documentation. If an attribute has the file validation rule, you can now select a file when trying out the endpoint in the generated docs.

For example:

public function store(Request $request)
{
$request->validate([
'logo' => 'file'
]);
// ...
}

And the result:

File upload

JSON API updates

From the beginning, Scramble supported documenting JSON API resources by inferring the return type of the toArraymethod. It handled common resource methods like when and mergeWhen.

With this update, all JSON API resource methods are now supported.

One of my favorite additions is support for the attributes method. It lets you include and merge model attributes into the response, like this:

<?php
namespace App\Http\Resources;
use App\Models\Company;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
/**
* @mixin Company
*/
class CompanyResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
$this->attributes(['id', 'created_at']),
'jobs_count' => $this->whenAggregated('jobs', 'id', 'count'),
];
}
}
Resulting documentation
Get company
get
http://demo-scramble-pro.test/api/company/{campaign}
Request
path Params
campaign
integer
The campaign ID
Responses
200
·
OK
`CompanyResource`
Body
object
data
object
required
- Hide properties
id
integer
required
created_at
string or null<date-time>
required
jobs_count
integer

Comprehensive pagination support

Previously, Scramble only supported LengthAwarePaginator. If you used other pagination types, like cursor pagination, you had to create custom extensions.

Now, Scramble supports all paginator classes out of the box:

  • Illuminate\Pagination\LengthAwarePaginator (returned by the paginate method),
  • Illuminate\Pagination\Paginator (returned by simplePaginate),
  • Illuminate\Pagination\CursorPaginator (returned by cursorPaginate).

In addition, Scramble can now document paginated results that aren’t wrapped in a collection.

<?php
namespace App\Http\Controllers\Api;
use App\Models\Company;
use Illuminate\Http\Request;
use App\Http\Resources\CompanyResource;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Pagination\CursorPaginator;
class CompanyController extends Controller
{
/**
* List companies.
*
* List all the companies which looking for the applicants.
*
* @response AnonymousResourceCollection<CursorPaginator<CompanyResource>>
*/
public function index(Request $request)
{
return CompanyResource::collection(Company::cursorPaginate());
}
}
Resulting documentation
List companies
get
http://demo-scramble-pro.test/api/company
List all the companies which looking for the applicants.
Responses
200
·
OK
Paginated set of `CompanyResource`
Body
object
data
CompanyResource[]
required
- Hide properties
id
integer
required
created_at
string or null<date-time>
required
jobs_count
integer
meta
object
required
- Hide properties
path
string or null
required
Base path for paginator generated URLs.
per_page
integer
required
Number of items shown per page.
next_cursor
string or null
required
The "cursor" that points to the next set of items.
prev_cursor
string or null
required
The "cursor" that points to the previous set of items.
links
object
required
- Hide properties
first
string or null
required
last
string or null
required
prev
string or null<uri>
required
next
string or null<uri>
required

Laravel Data support improvements: include, exclude support, and more

When using Laravel Data, you can include or exclude properties during data transformation with the include and exclude methods. Scramble PRO now fully supports these methods, as well as defaultIncluded.

To support defaultIncluded properly, Scramble PRO also recognizes the fromModel method in your data class.

<?php
namespace App\Http\Controllers\Api;
use App\Models\Company;
use Illuminate\Http\Request;
use App\Http\Resources\CompanyResource;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Pagination\CursorPaginator;
class CompanyController extends Controller
{
/**
* Get companies.
*/
public function show(Request $request, Company $company)
{
return LazyCompanyData::from($company)->exclude('contact');
}
}
Resulting documentation
Get company
get
http://demo-scramble-pro.test/api/company/{company}
Request
path Params
company
integer
The company ID
Responses
200
·
OK
Body
object
id
integer
required

Ability to exclude routes from documentation using attributes

Previously, excluding routes from documentation required redefining the route resolution function:

app/Providers/AppServiceProvier.php
public function boot()
{
Scramble::routes(function (Route $route) {
if ($route->getName() === 'api.company.show') {
return false;
}
if ($route->getName() === 'api.company.store') {
return false;
}
return Str::startsWith($route->uri(), 'api');
});
}

Now, you can simply mark routes with a specific attribute to exclude them:

use Dedoc\Scramble\Attributes\ExcludeRouteFromDocs;
#[ExcludeRouteFromDocs]
public function show(Request $request, Company $company)
{
// ...

You can also exclude entire groups of routes by adding the attribute to a controller:

use Dedoc\Scramble\Attributes\ExcludeAllRoutesFromDocs;
#[ExcludeAllRoutesFromDocs]
class CompanyController extends Controller
{
// ...

Other fixes

  • Fix the extensions ordering so users extensions’ result is not overwritten
  • Add file upload in OAS 3.1 format description support by @yvoitenko in #569
  • Fixed incorrect parsing of inline JSON resource model annotating comments
  • Added immutable_date casts support
  • Fix failing when fetching constants using variables
  • Added proper mixed type support
  • Added required field support to request body as well as automatically documenting it when some fields in schema required
  • mixed type is serialized as {}, not as []
  • Change default OpenAPI JSON export to pretty print by @coffee-r in #582
  • Improved merging of dot-notated params originated from method calls
  • Fix: brought back binary format for marking files so more OpenAPI UI clients support by @axelrindle in #587
  • Proper parent::toArray support in JSON API resource
  • Added the resolution of class names of PHPDoc for SchemaClassDocReflector
  • Added size validation rule support
  • Fix reference being ignored if one type had many type to schema extensions associated
  • Added enum case type
  • Implemented invokable objects return type inference
  • Added method calls extensions for exception inference
  • Added support PHPDoc v2 without introducing breaking changes
  • Prevent failing when analyzing __invoke call on \Closure
  • Improved mapping of route path parameters to route signature parameters
  • Improved default documentation for explicitly bound route params
  • Make sure models from vendor are properly documented

Scramble PRO fixes

  • Documenting when request body is required if some property is required
  • Fixed parameters inferred from request method calls overriding Laravel Query Builder parameters
  • Fixed name alias of allowed includes
  • Documenting 422 response when using Laravel Data object as a form request
  • Added class names resolution in PHPDoc annotations
  • Added proper handling of fields that are not marked for validation (#[Computed]#[WithoutValidation] support)
  • Fixed integer constraints (#[Min]#[Max]) info being lost
  • Added proper handling of nullable fields that are marked with #[Required] attribute
  • Added #[Present] rule support on nullable
  • Fixed recursive data properties documentation - now it is possible to have nested data objects with cyclic relations
  • Added support for properties that are filled from route parameters (#[FromRouteParameter]#[FromRouteParameterProperty])

This update brings significant improvements to Scramble, making it easier to generate comprehensive and accurate API documentation. Try out the new features and let me know what you think!

Scramble PRO
Comprehensive API documentation generation for Spatie’s Laravel Data and Laravel Query Builder.