株式会社織翔
← コラム一覧に戻る
Laravel6分で読める

Laravelで混乱しやすいスネークケースとキャメルケースの考え方

Laravel開発でよく出てくるスネークケースとキャメルケースの使い分けを、DB・モデル・APIの境界ごとに整理します。

#Laravel#命名規則#スネークケース#キャメルケース

命名規則で混乱しやすい理由

Laravel開発では、データベース、PHP、JSON、JavaScriptなど複数の世界を行き来します。それぞれでよく使われる命名規則が違うため、どこでスネークケースを使い、どこでキャメルケースを使うのか迷いやすくなります。

たとえば、データベースでは user_name のようなスネークケース、PHPのメソッド名では getUserName のようなキャメルケースをよく見ます。どちらか一方に無理に統一するより、境界ごとに自然な書き方を選ぶことが大切です。

命名規則は見た目を揃えるためだけでなく、「この値はどの層の値か」を読み手に伝えるためのものです。

Laravelではスネークケースが多い

Laravelでは、テーブル名やカラム名にスネークケースを使う場面が多くあります。

Schema::create('users', function (Blueprint $table) {
    $table->string('user_name');
    $table->timestamp('email_verified_at')->nullable();
});

EloquentモデルでDBカラムを扱うときも、基本的にはカラム名に合わせて user_name のように参照します。DBに存在する物理的な名前を無理にアプリケーション側で別名にしすぎると、マイグレーション、モデル、バリデーション、APIレスポンスの対応関係が追いにくくなります。

PHP側ではキャメルケースが自然な場面もある

一方で、PHPのメソッド名や処理名ではキャメルケースが自然です。

public function getDisplayName(): string
{
    return $this->user_name;
}

ここで大事なのは、DBカラム名とアプリケーション上の振る舞いを混同しないことです。user_name は保存されている値、getDisplayName() は表示用の振る舞い、と考えると役割が分かれます。

EloquentのJSON化で気をつけること

EloquentモデルをJSONに変換するとき、読み込まれたリレーションはJSON上の属性として含まれます。Laravelでは、リレーションメソッドをキャメルケースで定義していても、JSON上の属性名はスネークケースとして表現されます。

public function latestOrder()
{
    return $this->hasOne(Order::class)->latestOfMany();
}

このようなリレーションを読み込んでJSON化すると、API利用側では latest_order のようなキーとして扱うことになります。フロントエンド側で latestOrder を期待している場合は、ここで認識違いが起きやすくなります。

Accessorとappendsの注意点

LaravelではAccessorを使って、DBには存在しない表示用の値をモデルに追加できます。たとえば getFullNameAttribute() のようなAccessorを定義し、$appends に追加するとJSONにも含められます。

このときも、PHPのメソッド名はキャメルケース寄り、JSON上の属性名はスネークケース寄りになることがあります。

protected $appends = ['full_name'];

画面側が fullName を期待しているのか、full_name を期待しているのかを曖昧にすると、APIの利用側でバグになります。Accessorを使う場合ほど、APIレスポンスのキー名を明示しておくことが重要です。

APIレスポンスの形式はプロジェクトで決める

APIでは、バックエンドとフロントエンドの都合がぶつかりやすくなります。Laravel側はスネークケース、JavaScript側はキャメルケースを好むことが多いためです。

この場合は、プロジェクトとしてレスポンス形式を決めておくのが安全です。

  • APIレスポンスはスネークケースで統一する
  • APIレスポンスはキャメルケースで統一する
  • 外部APIに合わせる
  • 変換する場所をResourceやPresenterに限定する

変換ルールが曖昧だと、同じAPI内で user_nameuserName が混在し、利用側の実装ミスにつながります。

Resourceで境界を作る

APIレスポンスを整える場合、Controller内で都度配列を作るより、Resourceなどの出力専用の層に寄せると管理しやすくなります。

return [
    'id' => $this->id,
    'user_name' => $this->user_name,
    'latest_order' => new OrderResource($this->whenLoaded('latestOrder')),
];

ここでスネークケースに統一するなら、フロントエンド側もその前提で型定義を作れます。キャメルケースに変換するなら、変換箇所をResourceに限定すると追いやすくなります。

ありがちな失敗例

命名規則の混乱は、単純なタイプミスよりも発見しづらいことがあります。

  • リクエストでは userName、DB保存では user_name を期待していて保存されない
  • APIレスポンスの一部だけキャメルケースになっている
  • Resourceで変換した値とEloquentの素のJSONが混在している
  • フロントエンド側で型定義と実レスポンスのキーがずれている
  • latestOrderlatest_order が同じレスポンス内で混在している

こうした問題を避けるには、変換する場所を増やしすぎないことが大切です。DBに近い層、API出力の層、画面表示の層でそれぞれ責務を分けます。

チームで決めておくとよいルール

プロジェクト開始時に、最低限次のルールを決めておくと後の混乱を減らせます。

  1. DBカラムはスネークケースにする
  2. PHPメソッド名はキャメルケースにする
  3. APIレスポンスはスネークケースかキャメルケースのどちらかに統一する
  4. 変換はResourceなど出力境界で行う
  5. フロントエンドの型定義は実レスポンスからずらさない

この程度でも、実装中の迷いはかなり減ります。

まとめ

スネークケースとキャメルケースは、どちらが正しいというより、どの層で何を表しているかによって使い分けるものです。

LaravelではDBやEloquentの文脈ではスネークケースを尊重し、アプリケーションロジックやフロントエンドとの境界ではチームでルールを決めると、読みやすく変更に強いコードになります。