In Drupal 6, module developers often use Nodes as an all-purpose method for having objects that can be saved into the database. This hack avoids having to write a lot of boilerplate CRUD for all custom data used in your modules. Nodes in D6 are a powerful tool for this use case when combined with the flexibility of CCK's custom fields, and the simplified integration with contrib modules. However, using Nodes for every piece of specialized content means a lot of overhead; contributed modules often modify Nodes and added hooks that operated on them. This is a major performance concern, not to mention a bad architecture for unrelated data.

In Drupal 7, we have entities. Entities not only provide all functionality available with Nodes in D6, but they offer much more. Many modules in core are now using Entities for their database records, including node.module and user.module. In this post, we'll discuss what Entities are, some poignant examples of Entities, and why you would want to use them.

What is an Entity?

Entities can be thought of as the parent class of nodes. They are the abstraction of functionality common between Nodes, Taxonomy Terms, and Users (among others). You can see this very clearly by looking at the Drupal 7 version of user_load_multiple() and node_load_multiple().

function user_load_multiple( $uids = array(), 
                             $conditions = array(),
                             $reset = FALSE) {
  return entity_load('user', $uids, $conditions, $reset);
}
function node_load_multiple( $nids = array(),
                             $conditions = array(),
                             $reset = FALSE) {
  return entity_load('node', $nids, $conditions, $reset);
}

As you can see, the loading behaviour of nodes and users is almost identical. This makes a lot of code in Drupal 7 core more maintainable and much cleaner. Building on this, the API defines a consistent set of functions for getting information such as label and uri for an entity, which was often annoying extra work in D6. One of the biggest benefits, however, is that you can define your own custom entities, and they can also be fieldable. In short, you get all of the convenience of nodes without the overhead and unnecessary code.

Entities also have revision tracking support baked in, just like the the Node module. This lets you have multiple versions of the entity stored in the database, but without having to define the revision-loading logic yourself. For example, if you made a “Wiki page” entity, you could track changes to pages and, with some ingenuity, show a diff between two revisions. Setting up these tables and writing boilerplate SQL and loading code would be time consuming and error-prone, but with entities, you can get Drupal to d the hard work for you.

Examples of entities

Some notable Entity types are Nodes, Users, and Taxonomy Terms. However, many contributed modules have moved to Entities for this kind of functionality. Here are some notable modules that use Entities:

  • Wysiwyg: Uses entities for profiles.
  • Organic Groups: Uses entities for groups, membership types, and memberships.
  • Commerce: Uses entities for products, customers, payments, and line items.
  • Field Collection: Uses entities for “Field-collection items.” The Field collection module allows you to add fields to the “Field-collection items,” which then appear to be added to the entity that the field collection was originally attached to.
  • Relation: Uses entities for — you guessed it — relations. These entities link two other entities together. But, since relations are entities, the relationships themselves can have fields.

Benefits of Entities

Why are entities so cool? Here’s a short list:

Avoiding Boilerplate loading logic and SQL

Writing loading functions like node_load and boilerplate SQL is tedious and hard to maintain. With Entities, we can focus on the important functionality that is specific to our data type.

Consistent functionality between types

As I said before, entities have a standard interface. They have URIs, labels, and you can use a standard function to load them. This means more flexible, reliable code.

Not having to work with Nodes

Not having to work with Nodes for every main chunk of data makes your architecture better. Separating Node functionality from your own module’s functionality leads to more stable code. Even contributed modules that abuse nodes won’t get in your way. And the multitude of hooks running on Node operations can be trimmed down.

The contrib Entity API Module

The confusingly named contrib Entity API module provides even more functionality than Drupal core. In addition to all the benefits mentioned above, it provides saving, deleting, and updating entities, along with a ton of extra functionality. We’ll talk about this in the next part of this series.

Related Links

Want to learn more about Entities? Here are some links to get you started.

Slides and Video

At Drupalcamp Montreal, I gave a presentation of most of this. The slides are embedded and the video is available here: Videos