LaravelのAPI Resourceとは?作り方と3つの絶大メリット

Laravel
スポンサーリンク
OANDA証券 MT4

はじめに:モデルをそのまま返すのは危険?

こんにちは、編集長Kです。

APIを作るとき、つい手を抜いていませんか?

DBから取ったデータをそのままJSONで返す。

実はこれ、すごく危険な行為かも。

見せてはいけないパスワード等の情報が漏れる原因になります。

今日は、安全なAPI作りに欠かせないお話をします。

「API Resource(リソース)」クラスの作り方です。

この記事で解説する全体像は以下の通りです。

  • なぜResourceクラスが必要なのか?
  • 導入することで得られる3つの絶大メリット
  • 手順①:Resourceクラスの作成
  • 手順②:データの整形(中身の書き方)
  • 手順③:コントローラーでの呼び出し方

【前提条件】

  • Laravelの開発環境が手元にあること
  • データベースからデータを取得した経験があること

なぜ必要?レストランに例えて解説

システムをレストランだと想像してみてください。

データベースは冷蔵庫の中の「生の食材」です。

お客さん(画面側)から「ハンバーグ定食!」と注文が入ります。

このとき、冷蔵庫から出した生のひき肉を直接投げつけますか?

絶対にしませんよね。お腹を壊してしまいますし、お店の秘伝のレシピもバレてしまいます。

ここで必要なのが「キレイに盛り付けるシェフ」です。

このシェフの役割こそが、API Resourceというわけです。

シェフを雇うメリットは大きく3つあります。

【1. セキュリティ向上】見せたくない裏側のメモ(パスワード等)を隠してくれます。

【2. 型の安定】画面側が扱いやすいデータ形式に整えてくれます。

【3. パフォーマンス向上】N+1問題という重たい処理を防いでくれます。

まさに一石三鳥の素晴らしい仕組みなんです。

手順①:Resourceクラスを作成する

それでは、実際にシェフを雇いましょう。

コマンドライン(ターミナル)を開いてください。

まずは、下記を実行してください。

php artisan make:resource UserResource

これでOKです。

「app/Http/Resources」の中に新しいファイルができましたね。

準備はとても簡単ですね。

手順②:データの整形ルールを書く

次に、シェフに盛り付けのルールを教えます。

作成されたUserResource.phpを開いてください。

続いて、下記のように書き換えます。

<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class UserResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            // 基本情報だけをお皿に乗せる
            'id' => $this->id,
            'name' => $this->name,
            
            // パスワードなどの機密情報は絶対にここに入れない!
            
            // プロフィールは一緒に注文された時だけ乗せる
            'profile' => $this->whenLoaded('profile', function () {
                return [
                    'avatar_url' => $this->profile->avatar_url,
                ];
            }),
        ];
    }
}

これで安心です。

【whenLoaded】を使うのがプロの技です。

事前にデータが読み込まれている時だけ出力してくれます。

これで無駄なデータベースへの問い合わせが消え去ります。

手順③:コントローラーで呼び出す

最後に、出来上がった料理をお客さんに出します。

UserControllerなどを開いてください。

続いて、下記のように記述します。

<?php
namespace App\Http\Controllers;
use App\Http\Resources\UserResource;
use App\Models\User;
class UserController extends Controller
{
    // 1人のデータを返す場合
    public function show($id)
    {
        $user = User::findOrFail($id);
        
        // 1人の場合は「new」を使う
        return new UserResource($user);
    }
    // 複数のデータを返す場合
    public function index()
    {
        // 関連データも一緒に事前取得(Eager Loading)
        $users = User::with('profile')->get();
        
        // 複数の場合は「collection」を使う
        return UserResource::collection($users);
    }
}

バッチリですね、これで完了です。

お客さんには、安全で綺麗なデータだけが届きます。

1人の時は【new】を使い、複数の時は【collection】を使います。

ここだけ注意してくださいね。

現場のリアル:よくあるエラーと解決策

私が現場でよくハマったポイントを共有しておきます。

プロパティが存在しないエラー

「Trying to get property of non-object」などのエラーです。

これはResource内で「$this->」を忘れた時によく出ます。

単なる「id」ではなく「$this->id」と書く必要があります。

コピペした時に忘れがちなので、しっかり確認しましょう。

whenLoadedを使っているのにN+1が起きる

Resource側は正しくても、コントローラー側でミスがあるかも。

データの取得時に「with(‘profile’)」を忘れていませんか?

コントローラーでの「事前注文」が必須というわけです。

まとめ:Resourceクラスで安全なAPIを!

お疲れ様でした。

これであなたもAPI Resourceマスターですね。

生のモデルをそのまま返すのは今日で卒業しましょう。

少しの手間で、何百時間ものバグ探しから解放されます。

Trade Agencyでは、こうした実践的な開発テクニックを発信中です。

ぜひ、あなたのプロジェクトでも今日から取り入れてみてください!

この記事を書いた人
Trade Agency編集長K

■ 投資歴: 10年以上
■ スタイル: Fintokei(プロップファーム)× 株式投資
■ 職業: ITコンサルタント、アプリ開発

【詳細】
USD/JPYの裁量トレードでプロップファーム攻略に挑むエンジニアトレーダー。
Fintokeiで稼いだ利益を、堅実なバリュー・グロース株へ投資して資産を最大化する「資金循環スタイル」を実践中。

本業のWeb開発スキルを活かし、FXに役立つツール(Lot計算機など)を自作・無料公開しています。

Trade Agency編集長Kをフォローする
Laravelシステム開発
スポンサーリンク
Trade Agency編集長Kをフォローする

コメント

タイトルとURLをコピーしました