【ITニュース解説】Laravel Doesn’t Need GraphQL Part 1: Use DTOs and AQC for Exact Data
2025年10月02日に「Dev.to」が公開したITニュース「Laravel Doesn’t Need GraphQL Part 1: Use DTOs and AQC for Exact Data」について初心者にもわかりやすく解説しています。
ITニュース概要
Laravel開発者は、GraphQLのような複雑な仕組みなしに、DTOとAQCパターンで必要なデータだけを正確に取得できる。既存のLaravel知識とやり方を活用し、新たな学習コストやレイヤー追加を避け、効率的かつ柔軟にデータを提供可能だ。
ITニュース解説
Webアプリケーション開発において、フロントエンド(ユーザーインターフェース)がバックエンド(サーバー側)から必要なデータだけを効率的に取得する方法は重要な課題だ。近年、この目的のために「GraphQL」という技術が注目されている。GraphQLは、フロントエンドが欲しいデータの形を自分で指定できるという強力な特徴を持っている。例えば、「ユーザーのIDと名前とメールアドレスだけが欲しい」と具体的にリクエストすれば、バックエンドはそれらの情報だけを厳密に返してくれる。これにより、不要なデータが転送される「オーバーフェッチング」を防ぎ、通信効率を高めることができるのが魅力だ。
しかし、GraphQLを導入するには、バックエンドに新たなレイヤーを追加する必要がある。これは、GraphQLのクエリを解析するための「スキーマ」の定義、データ取得ロジックを記述する「リゾルバ」の実装、そしてGraphQL独自のルールや規約を学ぶ学習コストを伴う。既存のLaravelプロジェクトにこれを導入する場合、Laravelが元々持っている開発の知識体系とは異なる、全く新しい概念やツールセットを習得・維持しなければならないという負担が生じる可能性がある。
そこで、この記事では、もしあなたがLaravel開発者であれば、GraphQLのような複雑な新しい技術を導入しなくても、既存のLaravelの知識とパターンを応用して、GraphQLと同等かそれ以上のデータ取得の精度と柔軟性を実現できる代替アプローチが存在することを示している。それが「DTO(Data Transfer Object)」と「AQC(Atomic Query Construction)」という二つのパターンを組み合わせる方法だ。
まず、GraphQLの基本的な動作を考えてみよう。フロントエンドはJSON形式で、欲しいデータの構造を直接クエリとして送信する。例えば「usersというデータが欲しい、その中からid、name、emailフィールドをください」といった具体的な要求をバックエンドに送る。バックエンドはこのクエリを受け取ると、GraphQL専用のレイヤーでクエリを解析し、定義されたスキーマとリゾルバに従ってデータベースからデータを取得し、フロントエンドが要求した通りのJSON形式で応答する。この仕組みは強力ではあるが、その裏にはGraphQLレイヤーの構築と維持というコストが隠れているのだ。
次に、Laravelネイティブな代替アプローチ、DTOとAQCの組み合わせについて詳しく見ていこう。このアプローチでは、フロントエンドはGraphQLのようにデータの形をクエリで指定しない。ごく一般的なWebアプリケーションと同じように、特定のAPIエンドポイントに対してシンプルなリクエストを送るだけだ。
バックエンドでは、Laravelの開発者が普段から行っているように、Eloquentモデルやリポジトリパターンを使ってデータベースからデータを取得する。ここに「DTO」と「AQC」が加わる。
「DTO(Data Transfer Object)」とは、データベースから取得したデータを、実際にクライアント(フロントエンド)に送るための厳密な形に整形する役割を担うシンプルなクラスだ。例えば、ユーザーモデルがデータベースに多数のフィールドを持っていても、BasicUserというDTOクラスには、ID、名前、メールアドレスといった、フロントエンドに返したい特定のフィールドだけをプロパティとして定義する。このDTOクラスは、まるで契約書のように機能し、ここで定義されたフィールドだけが選択され、クライアントに渡されることを保証する。つまり、モデルが持つ余計な情報が誤って公開されるのを防ぎ、必要な情報だけを厳選して提供する仕組みになる。
このDTOを使ってデータを選択する具体的な方法としては、DTOクラスに定義されたプロパティ名を自動的に取得するヘルパーメソッドを用意し、それをEloquentのselect()メソッドに渡すことで、指定されたカラムだけを選択してデータベースからデータを取得できる。例えば、User::select(BasicUser::columns())->get();のように記述することで、BasicUserDTOに定義されたid、name、emailカラムだけが取得されることになる。これにより、GraphQLが提供する「必要なフィールドだけを取得する」という精密さを、Laravelの既存のORMであるEloquentの範囲内で実現できる。
一方、「AQC(Atomic Query Construction)」は、データベースへのクエリ(問い合わせ)を構造化し、再利用可能な形で構築するためのデザインパターンだ。複雑な条件やビジネスロジックに基づいてデータを取得する際、クエリの構築ロジックをAQCクラスとしてカプセル化(一つのまとまりとして扱うこと)する。例えば、GetUsersというAQCクラスを作り、is_activeが特定の条件を満たすユーザーだけを取得するといったロジックをその中に記述する。これにより、クエリの意図が明確になり、テストしやすくなり、複数の箇所で同じクエリロジックを再利用できるようになる。また、AQCクラスもDTOと同様に、取得するカラムを明示的に指定できるため、不要なデータ取得を防ぎつつ、クエリの柔軟性を高めることができる。
このDTOとAQCを組み合わせることで、LaravelのバックエンドはGraphQLのような精密なデータ取得を実現しながらも、応答の形式においてより高い柔軟性を持つ。GraphQLでは、その性質上、常にJSON形式でデータを返すことが前提となる。しかし、DTOとAQCを用いたLaravelのアプローチでは、APIとしてJSONデータを返すこともできるし、場合によってはサーバーサイドでレンダリングされたHTMLの断片を直接返すことも可能だ。これは、フロントエンドが特定のHTMLフラグメントをDOM(Webページの構造)に挿入するだけで済むようなシナリオにおいて、JSONデータをHTMLに変換するクライアントサイドの処理を省略でき、より高速なUI更新を実現できるというメリットがある。
なぜLaravel開発者にとって、GraphQLよりもDTOとAQCが優れていると言えるのだろうか。第一に、GraphQLのための特別なレイヤーを追加する必要がないため、Laravelの既存のフレームワーク内で完結し、学習コストと運用コストを削減できる。第二に、APIコントローラー、リポジトリ、Eloquentモデルといった、Laravel開発者にとって馴染み深いワークフローをそのまま活用できるため、開発効率が落ちることがない。第三に、DTOが厳密な契約として機能することで、バックエンドから返されるフィールドを確実に制御し、GraphQLと同等の「必要なものだけを返す」精度を保証できる。第四に、JSONだけでなく、BladeでレンダリングされたHTMLフラグメントも返せるという柔軟性があり、様々なフロントエンドのニーズに対応できる。最後に、バックエンドがデータアクセス戦略の主導権を握ることで、フロントエンドがデータベースの構造を直接的に決定することなく、システムの健全性を保つことができる。
もちろん、このアプローチが万能の解決策というわけではない。入れ子になったリレーションの取得や、複雑な条件分岐を持つクエリの場合、適切なEager Loading(関連データを事前に読み込む仕組み)やカラム選択を賢く行う必要がある。しかし、DTOを使うことで、これらの選択が明示的になり、開発者が意図せず大量のデータを取得してしまう「オーバーフェッチング」を未然に防ぐことができるという大きな利点がある。また、既存の巨大なレガシープロジェクトに一気に導入するのではなく、新規プロジェクトや、既存プロジェクトの一部に段階的に導入していくことで、その恩恵を最大限に享受できるだろう。
結論として、GraphQLは「必要なものだけを取得する」という強力な約束を提供するが、Laravel開発者はDTOとAQCを組み合わせることで、その約束を新たな学習曲線や複雑さを導入することなく実現できる。DTOはデータ構造の契約を定義し、AQCはクエリを明確かつ効率的にする。そして、応答はフロントエンドのニーズに応じてJSONにもHTMLにもなり得る。GraphQLだけが唯一のデータ取得方法ではないということを理解し、Laravelの既存ツールを活用することで、よりシンプルで効率的な開発が可能になるのだ。