エンティティの定義

Drupal 8におけるエンティティとは、エンティティAPIを通じて共通のメソッドでデータベースにデータを出し入れすることのできるオブジェクトのことを指します。 念のため公式の定義も確認してみましょう。

  • Drupal公式の定義

    ウェブコンテンツやコンフィグの情報を持続的に保存するために使われるオブジェクト
    (”objects that are used for persistent storage of content and configuration information.”、Entity API

  • 2009年に「エンティティ」という用語がDrupalに導入された時の定義

    オプションでフィールドを追加できる、ロード可能なモノ
    (”loadable thingy that can optionally be fieldable”、Standarized, pluggable entity loading

「エンティティ」という言葉の感じからフワフワした印象を受けるので、システムや構造のようなものをイメージする人が多いのですが、実際は「エンティティ」自体は構造化された「単一」のデータを指します。(一本のブログ記事、一人のユーザー、一つのタクソノミーなど。) これを意識しておくと、ドキュメントを読む時に便利です。

ウェブコンテンツとしてのエンティティ

Drupal 8では、全てのウェブコンテンツをエンティティ化することが推奨されています。そのため、コアモジュールの生成するデータは基本的に全てエンティティです。カスタムモジュールでもエンティティとしてデータを保存することがベストプラクティスとされています。エンティティ化されたウェブコンテンツは「コンテントエンティティ(Content Entity)」と呼ばれます。

コンフィグ としてのエンティティ

エンティティという形式があまりにも便利なので、Drupal 8ではコンフィグもエンティティ化されています。これはコンテントエンティティに対して「コンフィギュレーションエンティティ(Configuration Entity)」と呼ばれます。ただ、こちらは上級者向けなので、今回は「エンティティ=コンテントエンティティ」という前提で話を進めます。

エンティティのメリット

ウェブコンテンツをエンティティ化する、ということはつまり、「データをエンティティAPIで扱えるような形式のオブジェクトにする」ことですが、それには以下のようなメリットがあります。

  • 全エンティティ共通のパラメーターやメソッド使って簡単にデータにアクセスできる
  • 複雑なデータ構造のウェブコンテンツを簡単に実装できる
  • コードを書かずにViews、Token、RESTなどとのインテグレーションを使える
  • コードを書かずにDrupalの多言語機能に対応できる
  • どんなデータもEntityManagerを通じて操作できる
  • エンティティ間で「連鎖」が可能(とある記事の著者IDからそのIDのユーザープロフィールにアクセスする、など)
  • システムのパフォーマンスを向上できる など

エンティティ界の愉快な仲間たち

ここではコアモジュールの代表的なコンテントエンティティの種類(エンティティタイプ)を紹介したいと思います。Drupal 8では表面上は全く異なる多種多様なデータをエンティティとして一貫したワークフローで管理できるということを理解して頂ければと思います。

ノード

  • サイト上で表示され、読まれるためのモノ
  • データは修正可能
  • 一般的なコンテンツデータ

ユーザー

  • ユーザーのアカウント情報と管理をする
  • ユーザープロフィールの集合

カスタムブロック

  • 再利用可能なコンポーネント
  • スライドショーやボタン付きヒーローバナーのように構造化されており、スタイルを持つ
  • パネルの中で使える

ボキャブラリーとターム

  • 他のエンティティを整理するためのキーワード
  • 他のエンティティをソートしたり並べ替えたりできる
  • タクソノミーのメタデータを管理する

コメント

  • コメントを作る
  • 他のエンティティに構造化されたタイムライン付きのコメントを付与する

ファイル

  • プロジェクトファイルを保管・管理する
  • ファイルを管理しやすくするデータやメタデータを付与する

(参考:DrupalCon New Orleans 2016: Entities 101 : Understanding Data Structures in Drupal )

エンティティかどうかの見分け方

先ほど書いた通り、Drupal 8では全てのウェブコンテンツをエンティティ化することが推奨されており、コアモジュールが生成するコンテンツは全てエンティティであると考えることができます。ですが、コントリビュートモジュールの生成するウェブコンテンツがエンティティであるか調べたいこともあると思うので、念の為その方法も確認しておきましょう。

あるウェブコンテンツがエンティティであるかを知る一つの方法は、[モジュールディレクトリ]/src/Entity/の下のPHPファイルでエンティティタイプが定義されているかを調べることです。

例えば、「ユーザー」の場合、モジュールファイルは/core/modules/userです。その中を覗くと、src/Entityの下にUser. php というファイルがあります。

 /core/modules/user
                            └ src
                             └ Entity
                                     ├User.php ←
                                     ├Role.php
                                     └UserRouteProvider.php

User.phpファイルの中には、@ContentEntityType と書かれた注釈があり、

* @ContentEntityType(
*   id = "user",
*   label = @Translation("User"), ...

その下に ContentEntityBase を継承した User クラスが定義されています。

class User extends ContentEntityBase implements UserInterface { ...

これによってユーザーというウェブコンテンツはエンティティであることがわかります。 一つのモジュールに対して複数のエンティティを作ることも可能で、user/src/EntityにあるRole.phpは ロール(役割)というまた別のエンティティタイプを定義しています。

エンティティタイプとバンドル

エンティティタイプ

先ほどからチラチラと出てますが、「ノード」「タクソノミー」「ユーザー」のような、共通の性質を持ったエンティティを束ねるラベルを「エンティティタイプ」と呼びます。先ほど紹介したモジュールの src/Entity/ で定義されているものはエンティティタイプになります。

バンドル

エンティティタイプの中でバンドルというサブタイプが作られることもあります。例えば、Drupalを標準モードでインストールすると、「コンテンツタイプ」というものがあり、その中に「記事」と「基本のページ」が用意されてることに気づくと思います。この「記事」と「基本のページ」がバンドルです。では、「コンテンツタイプ」は何かと言うと、「ノードタイプのバンドルの通称」です。Drupalでは初期からノードが中心的な役割を果たしてきたので、慣習的に「ノードのバンドル」と呼ばずに「コンテンツタイプ」と呼ばれています。同様に、タクソノミーのバンドルの一つに「タグ」があり、タクソノミーのバンドルはまとめて「ボキャブラリー」と呼ばれます。ちなみに、「ユーザー」のバンドルは「ユーザー」一種類のみです。また、「ファイル」にはバンドルがありません。

エンティティシステムの構造図

エンティティタイプ、バンドル、エンティティの関係を示したのが以下の図です。

まとめ

今回の記事のまとめです。

  • エンテティティはエンティティAPIで扱えるように一定の形式を満たした単一のオブジェクトである
  • エンティティシステムのお陰で、多種多様なウェブコンテンツを簡単に作ったりデータ処理したり出来る
  • エンティティかどうか見分けるにはモジュールの/src/Entityディレクトリを見る
  • エンティテイタイプ > (バンドル) > エンティティ という様に階層化されている

というわけで、今回はエンティティの概要について説明しました。 実際にエンティティをどう扱うかについては次回以降また書きたいと思います。

おまけ

エンティティという英単語自体は「独立した存在物」という意味を持ちます。 コンピューター関係では、データベースの分野において「データの塊によって構成される存在物」のような意味の言葉として1970年ごろから伝統的に使われてきました。 リレーショナルDBでは、行(下の表の「田中」の行と「山田」の行)がエンティティに相当します。

蛇足ですが、こちらでも本来は「従業員」のことをエンティティタイプと呼ぶのですが、実際にはエンティティタイプのことをエンティティと呼ぶ人が多くてほとんど慣習化しているようです。 Drupalの場合も相手に伝わればいいと思いますが、やっぱりドキュメントなどを読む時は正しい定義を知っていると便利ですよ。