What is the difference between Configuration and Content in Drupal? Give examples.
Configuration represents the site structure and behavior stored in YAML files — such as content types, views, fields, permissions, and site settings. Content is the actual data stored in the database — like nodes, users, taxonomy terms. Configuration is deployed across environments using config management, while content is environment-specific.
Explain the request flow in Drupal 9/10 from URL hit to HTML response.
When a request hits Drupal, it goes through index.php, which boots the Symfony kernel. The routing system matches the URL to a route defined in routing.yml. The matched controller returns a render array, which is processed by the theme layer and Twig templates to generate the final HTML response, with caching applied at multiple layers.
How do you structure a custom module in Drupal 9+? What files are mandatory and why?
A custom module contains .info.yml for metadata, .routing.yml for routes, .services.yml for dependency injection, and optionally .module for hooks. Controllers handle request logic, while services contain business logic. This separation keeps the module maintainable and testable.
What is Dependency Injection in Drupal? Why is it preferred over \Drupal::service()?
Dependency Injection means passing required services into a class via the constructor instead of calling \Drupal::service(). This improves testability, decouples code, and follows Symfony best practices used in Drupal 8+.
Explain Cache Tags, Cache Contexts, and Cache Max-Age with a real example.
Cache Tags handle invalidation (e.g., when a node updates). Cache Contexts vary cache based on conditions like user role or language. Max-age defines how long content is cached. Together they ensure correct and efficient caching.
Ex: A node page uses cache tag node:1, context user.roles, and max-age 3600.
public function content($node) {
$build = [
'#markup' => $node->getTitle(),
'#cache' => [
'tags' => ['node:' . $node->id()],
'contexts' => ['user.roles', 'languages'],
'max-age' => 3600,
],
];
return $build;
}
Whenever I build dynamic render arrays in controllers, blocks, or custom plugins, I explicitly define cache metadata. Cache tags ensure content invalidates when related entities update, contexts vary cache based on user or language, and max-age controls cache lifetime.
How do you manage configuration across Dev → Stage → Prod in Acquia Cloud?
Configuration is exported using drush cex, committed to Git, deployed via Acquia pipelines, and imported using drush cim. Environment-specific values are handled in settings.php to avoid conflicts.
When would you avoid using Entity API and use a direct database query?
Entity API should be avoided only in performance-critical bulk operations or reporting queries where direct DB queries are more efficient, while ensuring data integrity is not compromised.
Direct DB queries bypass Drupal’s cache, access checks, and field system. Entity API ensures data integrity and proper cache invalidation.
I use Entity API for all CRUD operations because it respects field API, access control, caching, and hooks. For listing and filtering, I use EntityQuery instead of DB queries to maintain Drupal standards.
Ex: $node = \Drupal::entityTypeManager()->getStorage('node')->load(1);
What is the purpose of composer.lock in a Drupal project?
composer.lock ensures consistent dependency versions across all environments, preventing unexpected issues during deployments.
What happens if you change configuration directly in Production?
Any configuration change made directly in Production will be overwritten during the next deployment because config is managed via version control and imported from YAML files.
How do you debug a Drupal site that is slow only in Production but fast in Dev?
I would check caching layers, CDN, database load, external API delays, and enabled modules. I’d use New Relic, Acquia Insight, logs, and check cache metadata to identify bottlenecks. Production slowness is usually related to caching, infrastructure, or third-party integrations.
What is Render Cache?Render cache stores the HTML output of render arrays so Drupal doesn’t rebuild the same component repeatedly. It works using cache metadata like tags, contexts, and max-age to ensure proper invalidation and variation.
Why Dependency Injection?
Dependency Injection allows services to be passed into a class via the constructor instead of calling global functions like \Drupal::service(). This improves testability, decouples code, and follows Symfony architecture used in Drupal 8+.
What is Lazy Builder?
Lazy builder defers heavy processing of a render element until after the initial page load. Drupal renders the page quickly and later calls the lazy builder callback to generate that part, improving performance.
Why EntityQuery over DB Query?
EntityQuery is Drupal’s API to fetch entity IDs based on conditions. It respects access control, field API, caching, and hooks. Direct DB queries bypass Drupal systems and should be avoided unless absolutely necessary for performance-critical cases.
Difference :
| EntityQuery | DB Query |
| Drupal API to fetch entity IDs | Direct SQL query to database tables |
| Respects Drupal access control | Bypasses access control |
| Works with Field API | Must manually join field tables |
| Supports cache metadata | No cache awareness |
| Triggers hooks & integrations | Bypasses Drupal system |
| Database independent | Tied to DB structure |
| Recommended approach | Only for rare performance cases |
How to optimize a heavy page?
By using render cache metadata, avoiding unnecessary entity loads, implementing lazy builders for heavy components, using BigPipe, and ensuring proper use of EntityQuery instead of loading full entities.
Drupal APIS
Drupal is API-driven; we rarely write raw PHP or SQL because Drupal APIs handle architecture, security, and caching.
Drupal provides several APIs like Entity API for entity operations, Field API for managing fields, EntityQuery for filtering entities, Form API for forms, Render API for output, Plugin API for extensibility, Services API for clean architecture, and Cache API for performance.
- Entity API - Used to create, load, update, and delete Drupal entities like nodes, users, taxonomy, media, and custom entities. $node = Node::load(1); / $nodes = Node::loadMultiple($nids);
- Field API - Used to define and manage fields attached to entities (like title, body, tags, image). Ex : $node->get('field_tags')->value;
- EntityQuery API - Used to fetch entity IDs based on conditions (lightweight filtering). Ex: \Drupal::entityQuery('node')->condition('status', 1)->execute();
- Form API (FAPI) - Used to build forms in Drupal with validation and submission handling. Ex : $form['name'] = [ '#type' => 'textfield','#title' => 'Name'];
- Render API - Used to return structured render arrays to generate HTML with cache metadata.
- Database API - Used to run safe DB queries when absolutely needed. Ex: \Drupal::database()->select('node_field_data', 'n');
- Routing API - Defines URLs and maps them to controllers.
- Plugin API - Used to create reusable components like blocks, field formatters, views handlers.
- Services API / Dependency Injection - Used to define reusable services and inject them into classes.
- Cache API - Used to store and invalidate cached data properly.
Difference between Entity API vs EntityQuery (Very Important) ?
EntityQuery is used to fetch entity IDs efficiently, and Entity API is used afterward to load and manipulate those entities.
| Entity API | EntityQuery |
| Used to load, create, update entities | Used to find entity IDs |
| Example: Node::load($nid) | Find nodes matching condition |
| Works on full entity objects | Works on IDs only |
| Used for CRUD operations | Used for filtering/searching |
| Heavier | Lightweight |
Comments
Post a Comment