Skip to main content
Home
Drupal life hacks

Main navigation

  • Drupal
  • React
  • WP
  • Contact
  • About
User account menu
  • Log in

Breadcrumb

  1. Home

Drupal 11.x: Deprecation of NodeStorage Methods — What You Need to Know

By admin, 13 September, 2025

As Drupal continues to evolve, version 11.3.0 brings a significant shift in how developers interact with node revisions. The NodeStorage class, once a go-to for revision-related operations, has seen most of its methods deprecated. This change is part of a broader effort to streamline the API and encourage the use of entity queries.

Let’s break down what’s changed, why it matters, and how to adapt your code.


🔧 What’s Deprecated?

The following methods in Drupal\node\NodeStorage are now deprecated:

  • revisionIds($node)
  • userRevisionIds($account)
  • countDefaultLanguageRevisions()

Only clearRevisionsLanguage() remains active.


🆕 Recommended Replacements

1. revisionIds($node) → Use Entity Query

Before:

$revision_ids = $node_storage->revisionIds($node);

After:

$query = \Drupal::entityQuery('node')
  ->allRevisions()
  ->condition('nid', $node->id())
  ->accessCheck(FALSE);
$revision_ids = array_keys($query->execute());

This approach uses the entity query system to fetch all revision IDs for a given node.


2. userRevisionIds($account) → Use Entity Query

Before:

$revision_ids = $node_storage->userRevisionIds($account);

After:

$query = \Drupal::entityQuery('node')
  ->allRevisions()
  ->accessCheck(FALSE)
  ->condition('uid', $account->id());
$revision_ids = array_keys($query->execute());

This retrieves all revisions authored by a specific user.


3. countDefaultLanguageRevisions() → Removed

This method has been completely removed with no replacement, as it was unused in Drupal core. If your module relied on it, you’ll need to implement custom logic or reconsider its necessity.


🧠 Why the Change?

Drupal is moving toward a more consistent and flexible architecture. Entity queries offer:

  • Better performance
  • Improved access control
  • Greater flexibility for custom conditions

By deprecating tightly coupled storage methods, Drupal encourages developers to write cleaner, more maintainable code.


🛠️ Migration Tips

  • Audit your custom modules for usage of deprecated methods.
  • Replace them with entity queries as shown above.
  • Use accessCheck(FALSE) cautiously—only when you're sure access control isn't needed.
  • Test thoroughly, especially if revisions are critical to your workflow.

📌 Final Thoughts

While deprecations can feel disruptive, they’re often a sign of progress. Drupal’s push toward entity queries aligns with modern development practices and opens the door to more powerful, scalable solutions.

If you’re working on a module or site that relies heavily on node revisions, now’s the time to refactor. Need help rewriting a specific snippet or debugging a migration? Drop it in—I’ve got your back.


📦 Example

Custom Drupal module that exposes filtered node revisions via a JSON API. This is perfect for building admin dashboards, REST integrations, or AJAX-powered interfaces.


📦 Step 1: Create a Custom Module — custom_revision_api

Folder structure:

custom_revision_api/
├── custom_revision_api.info.yml
├── custom_revision_api.routing.yml
├── src/
│   └── Controller/
│       └── RevisionController.php

📄 custom_revision_api.info.yml

name: 'Custom Revision API'
type: module
description: 'Provides filtered node revision data via JSON.'
core_version_requirement: ^11
package: Custom

🌐 custom_revision_api.routing.yml

custom_revision_api.revisions:
  path: '/custom-revisions'
  defaults:
    _controller: '\Drupal\custom_revision_api\Controller\RevisionController::getRevisions'
    _title: 'Filtered Revisions'
  requirements:
    _permission: 'access content'

🧠 RevisionController.php

namespace Drupal\custom_revision_api\Controller;

use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Drupal\user\Entity\User;

class RevisionController extends ControllerBase {

  public function getRevisions(Request $request): JsonResponse {
    $type = $request->query->get('type', 'article');
    $uid = $request->query->get('uid');
    $langcode = $request->query->get('langcode');
    $created = $request->query->get('created');
    $limit = (int) $request->query->get('limit', 10);
    $page = (int) $request->query->get('page', 1);

    $author = $uid ? User::load($uid) : NULL;
    $created_timestamp = $created ? strtotime($created) : NULL;

    $query = \Drupal::entityQuery('node')
      ->allRevisions()
      ->accessCheck(FALSE)
      ->condition('type', $type)
      ->sort('revision_timestamp', 'DESC')
      ->range(($page - 1) * $limit, $limit);

    if ($author) {
      $query->condition('uid', $author->id());
    }

    if ($langcode) {
      $query->condition('langcode', $langcode);
    }

    if ($created_timestamp) {
      $query->condition('created', $created_timestamp, '>');
    }

    $revision_ids = array_keys($query->execute());

    $revisions = \Drupal::entityTypeManager()
      ->getStorage('node')
      ->loadMultipleRevisions($revision_ids);

    $data = [];
    foreach ($revisions as $rev) {
      $data[] = [
        'nid' => $rev->id(),
        'title' => $rev->label(),
        'uid' => $rev->getOwnerId(),
        'langcode' => $rev->language()->getId(),
        'created' => date('Y-m-d H:i:s', $rev->getCreatedTime()),
        'revision_id' => $rev->getRevisionId(),
      ];
    }

    return new JsonResponse($data);
  }
}

🔗 Example API Call

GET /custom-revisions?type=article&uid=1&langcode=uk&created=2025-01-01&limit=5&page=1

Returns a JSON array of node revisions matching the filters.

Tags

  • #Drupal Planet
  • NodeStorage

Comments

About text formats

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
Powered by Drupal