[Laravel] 7.0がリリースされました

Laravelのバージョン7.0がリリースされました。追加された機能について確認します。

Version 7

Laravelのv6.0の時点でアナウンスされた通り、バージョニングの方法が変更され、6ヶ月ごとに行われるメジャーリリースが行われました。

Bug Fixesは2020年09月03日、Security Fixesは2021年03月03日までサポートされます。

現在のLTSバージョンであるv6.0は、Bug Fixesは2021年09月03日、Security Fixesは2022年09月03日までサポートされます。

laravel/laravelでのPHPのバージョンが7.2.5以上に変更されています。

Releases

リリースノートでは以下のような追加機能が発表されています。

  • Laravel Airlockの導入
  • ルーティング速度の改善
  • カスタムEloquentキャスト
  • Bladeコンポーネントクラスの追加
  • 新しい文字列操作クラスの追加
  • HTTPクライアントの追加
  • CORSのサポート
  • ルートモデルバインディングの改善
  • Stubのカスタマイズのサポート
  • データベースキューの改善
  • メール送信時のマルチドライバ
  • データベースクエリ発行時のキャスト設定
  • Artisanコマンドの追加

各項目についての詳細を確認します。

Laravel Airlock

Laravel Airlockは、SPA(単一ページアプリケーション)、モバイルアプリケーション、およびシンプルなトークンベースのAPI向けのフェザーウェイト認証システムを提供します。

Airlockを使用すると、アプリケーションの各ユーザーがアカウントに対して複数のAPIトークンを生成できます。

これらのトークンには、トークンが実行できるアクションを指定する能力/スコープが付与することが可能です。

LaravelにはOAuth2に対応したLaravel Passportがありましたが、これとの共存も可能です。

LaravelのエコシステムであるVaporForgeNovaなどのフロント部分はVue.js等を利用したAPIベースの実装がされています。

このようにバックエンドにLaravelを利用し、フロントエンドは別で用意する場合などにLaravel Airlockは大変便利な機能を提供します。

詳しい利用方法についてはこちらをご覧ください。

Custom Eloquent Casts

Eloquentモデルクラスでは、値の出力時には用意されたフォーマットにキャストすることが可能です。

CastsAttributesインターフェイスを実装するクラスを定義することで、オリジナルのキャストが行えるようになりました。

実装はget()set()のみのシンプルな実装です。

get()メソッドはデータベースからの生の値をキャストする際に呼び出されます。

set()メソッドは与えられた値をデータベースに保存する際に呼び出されます。

Laravelに組み込まれているJsonタイプへのキャストは以下のような実装になっています。

<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

class Json implements CastsAttributes
{
    /**
     * Cast the given value.
     *
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @param  string  $key
     * @param  mixed  $value
     * @param  array  $attributes
     * @return array
     */
    public function get($model, $key, $value, $attributes)
    {
        return json_decode($value, true);
    }

    /**
     * Prepare the given value for storage.
     *
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @param  string  $key
     * @param  array  $value
     * @param  array  $attributes
     * @return string
     */
    public function set($model, $key, $value, $attributes)
    {
        return json_encode($value);
    }
}

カスタムキャストタイプを定義したら、クラス名を使用してモデルにアタッチできます。

<?php

namespace App;

use App\Casts\Json;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'options' => Json::class,
    ];
}

詳しい利用方法についてはこちらをご覧ください。

Blade Component Tags & Improvements

コンポーネントは、受け入れるデータを指定する関連クラスを持つことができます。

コンポーネントクラスで定義されているすべてのパブリックプロパティとメソッドは、コンポーネントビューで自動的に使用可能になります。

コンポーネントで指定された追加のHTML属性は、自動的に含まれる$ attribute変数を使用して管理できます。

この例では、App\View\Components\Alertコンポーネントが次のように定義されていると仮定します。

<?php

namespace App\View\Components;

use Illuminate\View\Component;

class Alert extends Component
{
    /**
     * The alert type.
     *
     * @var string
     */
    public $type;

    /**
     * Create the component instance.
     *
     * @param  string  $type
     * @return void
     */
    public function __construct($type)
    {
        $this->type = $type;
    }

    /**
     * Get the class for the given alert type.
     *
     * @return string
     */
    public function classForType()
    {
        return $this->type == 'danger' ? 'alert-danger' : 'alert-warning';
    }

    /**
     * Get the view / contents that represent the component.
     *
     * @return \Illuminate\View\View|string
     */
    public function render()
    {
        return view('components.alert');
    }
}

そして、コンポーネントのBladeテンプレートが次のように定義されていると仮定します。

<!-- /resources/views/components/alert.blade.php -->

<div class="alert {{ $classForType }}" {{ $attributes }}>
    {{ $heading }}

    {{ $slot }}
</div>

コンポーネントは、コンポーネントのタグを使用して別のブレードビューでレンダリングできます。

<x-alert type="error" class="mb-4">
    <x-slot name="heading">
        Alert content...
    </x-slot>

    Default slot content...
</x-alert>

詳しい利用方法についてはこちらをご覧ください。

また、Laracastでも使用法の動画が公開されています。

What's New in Laravel 7: Supercharged Blade Components

HTTP Client

Laravelは、Guzzle, PHP HTTP clientを基盤として、メソッドの追加を行うことで最小限のAPIを提供するようになりました。

これにより、他のWebアプリケーションと通信するために発信HTTPリクエストをすばやく行うことができます。

Guzzleに対するLaravelのラッパーは、開発者がより効率的に作業ができることに焦点が当てられています。

たとえば、クライアントは簡単にPOSTを実行し、JSONデータとやり取りします。

use Illuminate\Support\Facades\Http;

$response = Http::withHeaders([
    'X-First' => 'foo',
    'X-Second' => 'bar'
])->post('http://test.com/users', [
    'name' => 'Taylor',
]);

return $response['id'];

さらに、HTTPクライアントは、素晴らしいテスト機能を提供します。

Http::fake([
    // Stub a JSON response for GitHub endpoints...
    'github.com/*' => Http::response(['foo' => 'bar'], 200, ['Headers']),

    // Stub a string response for Google endpoints...
    'google.com/*' => Http::response('Hello World', 200, ['Headers']),

    // Stub a series of responses for Facebook endpoints...
    'facebook.com/*' => Http::sequence()
                            ->push('Hello World', 200)
                            ->push(['foo' => 'bar'], 200)
                            ->pushStatus(404),
]);

詳しい利用方法についてはこちらをご覧ください。

Fluent String Operations

Laravelの既存のIlluminate\Support\Strクラスはとても便利な機能を提供してくれています。

このクラスは、Illuminate\Support\Strに付け加えて有用な文字列操作関数を提供します。

Laravel 7は、これらの機能の上に構築された、よりオブジェクト指向で流な文字列操作ライブラリを提供します。

Str::ofメソッドを使用して、Illuminate\Support\Stringableオブジェクトを作成できます。

その後、さまざまなメソッドをオブジェクトにチェーンして、文字列を操作できます。

return (string) Str::of('  Laravel Framework 6.x ')
                    ->trim()
                    ->replace('6.x', '7.x')
                    ->slug();

詳しい利用方法についてはこちらをご覧ください。

また、Laracastでも使用法の動画が公開されています。

What's New in Laravel 7: Fluent String Manipulation

Route Model Binding Improvements

Key Customization

id以外の列を使用してEloquentモデルを解決したい場合があります。

そのために、Laravel 7では、ルートパラメーター定義で列を指定できます。

Route::get('api/posts/{post:slug}', function (App\Post $post) {
    return $post;
});

Automatic Scoping

1つのルート定義で複数のEloquentモデルを暗黙的にバインドする場合、2番目のEloquentモデルのスコープを設定して、最初のEloquentモデルの子にする必要がある場合があります。

たとえば、特定のユーザーのSlugでブログ投稿を取得するこの状況を考えてみましょう。

use App\Post;
use App\User;

Route::get('api/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
    return $post;
});

ネストされたルートパラメーターとしてカスタムキー付きの暗黙的なバインディングを使用する場合、Laravel 7は自動的にクエリをスコープし、親子関係を推測して、親によってネストされたモデルを取得します。

この場合、UserモデルにはPostという名前のリレーションがあり、これを使用してPostモデルを取得することができます。

詳しい利用方法についてはこちらをご覧ください。

Multiple Mail Drivers

Laravel 7では、アプリケーションに対して複数のメールドライバが設定できるようになりました。

メール設定ファイル内で構成された各ドライバには、独自のオプションと独自のトランスポートがあり、アプリケーションで特定の電子メールメッセージを送信するために異なる電子メールサービスを使用できます。

たとえば、アプリケーションでPostmarkを使用してトランザクションメールを送信し、Amazon SESを使用してバルクメールを送信する場合があります。

デフォルトでは、Laravelはメール設定ファイルでデフォルトのメーラーとして設定されたドライバを使用します。

ただし、mailer()メソッドを使用して、特定のドライバを使用してメッセージを送信できます。

Mail::mailer('postmark')
        ->to($request->user())
        ->send(new OrderShipped($order));

Route Caching Speed Improvements

Laravel 7には、route:cacheのArtisanコマンドを使用してキャッシュされたコンパイル済みのキャッシュされたルートを一致させる新しい方法が含まれています。

大規模なアプリケーション(たとえば、800以上のルートを持つアプリケーション)では、これらの改善により、単純な「Hello World」ベンチマークでの1秒あたりの要求速度が2倍になります。アプリケーションを変更する必要はありません。

CORS Support

Laravel 7には、Barry vd. Heuvelによって作成されたLaravel CORSパッケージを統合することにより、クロスオリジンリソースシェアリング(CORS)OPTIONSリクエストレスポンスを構成するためのファーストパーティサポートが含まれています。

新しいcorsの設定ファイルは、デフォルトのLaravelアプリケーションに含まれています。

詳しい利用方法についてはこちらをご覧ください。

Query Time Casts

テーブルから生の値を選択するときなど、クエリの実行中にキャストを適用する必要がある場合があります。

たとえば、次のクエリを検討してください。

use App\Post;
use App\User;

$users = User::select([
    'users.*',
    'last_posted_at' => Post::selectRaw('MAX(created_at)')
            ->whereColumn('user_id', 'users.id')
])->get();

このクエリの結果のlast_posted_atは文字列になります。

クエリの実行時に、この属性に日付キャストを適用できれば便利です。

これを達成するために、Laravel 7が提供するwithCastsメソッドを使用できます。

$users = User::select([
    'users.*',
    'last_posted_at' => Post::selectRaw('MAX(created_at)')
            ->whereColumn('user_id', 'users.id')
])->withCasts([
    'last_posted_at' => 'date'
])->get();

MySQL 8+ Database Queue Improvements

Laravelの以前のリリースでは、デッドロックのために、データベースキューは本番環境での使用に十分な堅牢性があるとは見なされていませんでした。

ただし、Laravel 7では、MySQL 8+をデータベースバックアップキューとして使用するアプリケーションに改善が加えられています。

FOR UPDATE SKIP LOCKED句およびその他のSQL拡張機能を使用することにより、データベースドライバーをより安全に使用できるようになりました。

Artisan test Command

phpunitコマンドに加えて、Artisanのtestコマンドを使用してテストを実行できます。

Artisanテストランナーは、美しいコンソールUXと、現在実行中のテストに関する詳細情報を提供します。

さらに、ランナーは最初のテストの失敗で自動的に停止します。

phpunitコマンドに渡すことができる引数は、Artisanのtestコマンドにも渡すことができます。

php artisan test --group=feature

Markdown Mail Template Improvements

デフォルトのMarkdownメールテンプレートは、Tailwind CSSカラーパレットに基づいた、より新しくモダンなデザインが導入されました。

もちろん、このテンプレートはアプリケーションのニーズに応じて公開およびカスタマイズできます。

詳しい利用方法についてはこちらをご覧ください。

Stub Customization

Artisanコンソールのmakeコマンドは、コントローラー、ジョブ、マイグレーション、テストなどのさまざまなクラスを作成するために使用されます。

これらのクラスは、入力に基づいた値が入力されたstubファイルを使用して生成されます。

ただし、Artisanによって生成されたファイルに小さな変更を加えたい場合があります。

これを実現するために、Laravel 7は、カスタマイズのために最も一般的なスタブを公開するstub:publishコマンドを提供します。

php artisan stub:publish

公開されたstubは、アプリケーションのルートにあるstubsディレクトリ内に配置されます。

これらのスタブに加えた変更は、artisan makeコマンドを使用して対応するクラスを生成するときに反映されます。

Queue maxExceptions Configuration

ジョブが何度もリトライされるように指定したい場合もありますが、指定された数の例外によって再試行がトリガーされると失敗するはずです。

Laravel 7では、ジョブクラスでmaxExceptionsプロパティを定義できます。

<?php

namespace App\Jobs;

class ProcessPodcast implements ShouldQueue
{
    /**
     * The number of times the job may be attempted.
     *
     * @var int
     */
    public $tries = 25;

    /**
     * The maximum number of exceptions to allow before failing.
     *
     * @var int
     */
    public $maxExceptions = 3;

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        Redis::throttle('key')->allow(10)->every(60)->then(function () {
            // Lock obtained, process the podcast...
        }, function () {
            // Unable to obtain lock...
            return $this->release(10);
        });
    }
}

この例では、アプリケーションがRedisロックを取得できず、最大25回再試行され続ける場合、ジョブは10秒間解放されます。

ただし、3つの未処理の例外がジョブによってスローされると、ジョブは失敗します。


詳しい変更については以下を確認してください。

Release Notes - Laravel - The PHP Framework For Web Artisans

© Xzxzyzyz