Laravel 13.19.0 rounds out support for the HTTP QUERY method across the HTTP client and testing helpers, and adds a handful of collection, string, and queue improvements alongside the usual fixes.
Http::query()client method for sending QUERY requestsquery()andqueryJson()HTTP testing helpersreduceInto()collection method for mutating an accumulatorcounted()helper onStrandStringable- Bulk SQS dispatch via
SendMessageBatch, plus reserved-job inspection on the queue fake
What's New
Http::query() Client Method
The HTTP client gains a query() method for issuing requests with the HTTP QUERY verb, which carries its parameters in the request body rather than the URL. It mirrors the existing post(), put(), and patch() methods, sending JSON by default or form-encoded data when you call asForm().
$response = Http::query('https://api.example.com/search', [ 'filter' => ['status' => 'active'],]);
Existing URL query handling is unchanged: withQueryParameters() and the $query argument to get() continue to work as before. See #60663.
query() and queryJson() Testing Helpers
To match the client-side addition, the test suite gains query() and queryJson() helpers for exercising routes that respond to QUERY. They mirror verb-specific methods like delete() and deleteJson(), placing the test data in the request body.
Route::match(['QUERY'], '/search', fn () => request()->input('filter')); $this->queryJson('/search', ['filter' => 'active'])->assertOk();
See #60662.
reduceInto() Collection Method
reduceInto() is a variant of reduce() for cases where you mutate an accumulator in place instead of returning a new value each iteration. The callback receives the accumulator and the current item, and its return value is ignored, so object accumulators need no return:
$stats = $orders->reduceInto(new OrderStats, function ($stats, $order) { $stats->total += $order->amount; $stats->count++; $stats->largest = max($stats->largest, $order->amount);});
For array or scalar accumulators, take the accumulator by reference:
$tagsMap = $posts->reduceInto([], function (&$map, $post) { $post->tags->each(fn ($tag) => $map[$tag][] = $post->title);});
See #60651.
counted() String Helper
Str::counted() and its Stringable equivalent pluralize a word and prepend the count in one call, a shorthand for plural($count, prependCount: true):
str('order')->counted(1); // "1 order"str('order')->counted(2); // "2 orders"
See #60649.
Queue Improvements
Bulk SQS dispatches now go out through the SendMessageBatch API instead of one call per job, cutting the number of requests when pushing many jobs at once (#60645). The queue fake can now inspect reserved jobs, so tests can assert on jobs that have been picked up but not yet completed (#60644).
Other Fixes and Improvements
- Pass
deletedAtColumnthrough toassertSoftDeleted()andassertNotSoftDeleted()(#60657) - Allow mail config options to be defined without a name (#60668)
- Terminate the default style value with a semicolon in
ComponentAttributeBag::merge()(#60665) - Added tests for relative date where clauses and the date rule's past/future methods (#60675, #60687)
References