Novedades de Laravel 10.14

Esta semana se publicó una pequeña actualización de Laravel 10 (versión 10.14) y trae algunas novedades interesantes:

La regla de validación can

Supongamos que tenemos esta policy:

class ProductPolicy
{
    public function updatePrice(User $user, Product $product)
    {
        return $user->isAdmin();
    }
}

Podemos validar que el usuario tenga permisos para actualizar el precio desde la validación del request, en lugar de tener que validarlo después a mano:

use App\Models\Product;
 
class ProductRequest extends FormRequest
{
    public function rules()
    {
        return [
            'price' => Rule::can('update-price', Product::class, $this->route('product')),
            'name' => '...',
            'description' => '...',
        ];
    }
}

Middleware global para las peticiones HTTP

Ahora es posible añadir middlewares que se ejecutan en cada petición de la facade Http. Para ello, nos vamos a nuestro service provider:

use Illuminate\Support\Facades\Http;
 
// Middleware global para los requests
Http::globalRequestMiddleware(
    fn ($request) => $request->withHeader('User-Agent', config('app.name'))
);
 
// Middleware global para las respuestas
Http::globalResponseMiddleware(
    fn ($response) => $response->withHeader('X-Finished-At', now()->toDateTimeString())
);

Método withQueryParameters

Parece mentira que no estuviera antes :-)

// Antes
Http::baseUrl('https://api.myapp.com/v1/')
    ->withOptions([
        'query' => [
            'api_secret' => config('services.myapp.api_secret'),
        ],
    ])
    ->acceptJson();
 
// Con el nuevo `withQueryParameters()`
Http::baseUrl('https://api.myapp.com/v1/')
    ->withQueryParameters([
        'api_secret' => config('services.myapp.api_secret'),
    ])
    ->acceptJson();

Release Notes

¡Esto no es todo! Son las que me han parecido más interesantes para mí, pero puedes ver la lista completa de actualizaciones en Github. Estas son las release notes oficiales:

v10.14.0

  • [10.x] Add test for withCookies method in RedirectResponse by @milwad-dev in https://github.com/laravel/framework/pull/47383
  • [10.x] Add new error message "SSL: Handshake timed out" handling to PDO Dete… by @yehorherasymchuk in https://github.com/laravel/framework/pull/47392
  • [10.x] Add new error messages for detecting lost connections by @mfn in https://github.com/laravel/framework/pull/47398
  • [10.x] Update phpdoc except method in Middleware by @milwad-dev in https://github.com/laravel/framework/pull/47408
  • [10.x] Fix inconsistent type hint for $passwordTimeoutSeconds by @devfrey in https://github.com/laravel/framework/pull/47414
  • Change visibility of path method in FileStore.php by @foremtehan in https://github.com/laravel/framework/pull/47413
  • [10.x] Fix return type of buildException method by @milwad-dev in https://github.com/laravel/framework/pull/47422
  • [10.x] Allow serialization of NotificationSent by @cosmastech in https://github.com/laravel/framework/pull/47375
  • [10.x] Incorrect comment in PredisConnector and PhpRedisConnector by @hungthai1401 in https://github.com/laravel/framework/pull/47438
  • [10.x] Can set custom Response for denial within Gate@inspect() by @cosmastech in https://github.com/laravel/framework/pull/47436
  • [10.x] Remove unnecessary param in addSingletonUpdate by @milwad-dev in https://github.com/laravel/framework/pull/47446
  • [10.x] Fix return type of prefixedResource & prefixedResource by @milwad-dev in https://github.com/laravel/framework/pull/47445
  • [10.x] Add Factory::getNamespace() by @tylernathanreed in https://github.com/laravel/framework/pull/47463
  • [10.x] Add whenAggregated method to ConditionallyLoadsAttributes trait by @akr4m in https://github.com/laravel/framework/pull/47417
  • [10.x] Add PendingRequest withHeader() method by @ralphjsmit in https://github.com/laravel/framework/pull/47474
  • [10.x] Fix $exceptTables to allow an array of table names by @cwilby in https://github.com/laravel/framework/pull/47477
  • [10.x] Fix eachById on HasManyThrough relation by @cristiancalara in https://github.com/laravel/framework/pull/47479
  • [10.x] Allow object caching to be disabled for custom class casters by @CalebDW in https://github.com/laravel/framework/pull/47423
  • [10.x] "Can" validation rule by @stevebauman in https://github.com/laravel/framework/pull/47371
  • [10.x] refactor(Parser.php): Removing the extra "else" statement by @saMahmoudzadeh in https://github.com/laravel/framework/pull/47483
  • [10.x] Add UncompromisedVerifier::class to provides() in ValidationServiceProvider by @xurshudyan in https://github.com/laravel/framework/pull/47500
  • [10.x] Reindex appends attributes by @hungthai1401 in https://github.com/laravel/framework/pull/47519
  • [10.x] Fix ListenerMakeCommand deprecations by @dammy001 in https://github.com/laravel/framework/pull/47517
  • [10.x] Add HandlesPotentiallyTranslatedString trait by @xurshudyan in https://github.com/laravel/framework/pull/47488
  • [10.x] update [JsonResponse]: using match expression instead of if-elseif-else by @saMahmoudzadeh in https://github.com/laravel/framework/pull/47524
  • [10.x] Add withQueryParameters to the HTTP client by @mnapoli in https://github.com/laravel/framework/pull/47297
  • [10.x] Allow % symbol in component attribute names by @JayBizzle in https://github.com/laravel/framework/pull/47533
  • [10.x] Fix Http client pool return type by @srdante in https://github.com/laravel/framework/pull/47530
  • [10.x] Use match expression in resolveSynchronousFake by @osbre in https://github.com/laravel/framework/pull/47540
  • [10.x] Use match expression in compileHaving by @osbre in https://github.com/laravel/framework/pull/47548
  • [10.x] Use match expression in getArrayableItems by @osbre in https://github.com/laravel/framework/pull/47549
  • [10.x] Fix return type in SessionGuard by @PerryvanderMeer in https://github.com/laravel/framework/pull/47553
  • [10.x] Fix return type in DatabaseQueue by @PerryvanderMeer in https://github.com/laravel/framework/pull/47552
  • [10.x] Fix return type in DumpCommand by @PerryvanderMeer in https://github.com/laravel/framework/pull/47556
  • [10.x] Fix return type in MigrateMakeCommand by @PerryvanderMeer in https://github.com/laravel/framework/pull/47557
  • [10.x] Add missing return to Factory by @PerryvanderMeer in https://github.com/laravel/framework/pull/47559
  • [10.x] Update doc in Eloquent model by @alirezasalehizadeh in https://github.com/laravel/framework/pull/47562
  • [10.x] Fix return types by @PerryvanderMeer in https://github.com/laravel/framework/pull/47561
  • [10.x] Fix PHPDoc throw type by @fernandokbs in https://github.com/laravel/framework/pull/47566
  • [10.x] Add hasAny function to ComponentAttributeBag, Allow multiple keys in has function by @indykoning in https://github.com/laravel/framework/pull/47569
  • [10.x] Ensure captured time is in configured timezone by @timacdonald in https://github.com/laravel/framework/pull/47567
  • [10.x] Add Method to Report only logged exceptions by @joelharkes in https://github.com/laravel/framework/pull/47554
  • [10.x] Add global middleware to Http client by @timacdonald in https://github.com/laravel/framework/pull/47525