Drupal 9维护模式下如何保持JSON:API可用(不修改核心)
解决方案
方法一:用自定义模块实现钩子
创建一个自定义模块(比如命名为maintenance_jsonapi_bypass),在模块的.module文件中添加以下代码:
/** * Implements hook_maintenance_mode(). */ function maintenance_jsonapi_bypass_maintenance_mode() { $path = \Drupal::request()->getPathInfo(); // 检查当前请求路径是否以/jsonapi/开头 if (strpos($path, '/jsonapi/') === 0) { // 对JSON:API请求跳过维护模式 return FALSE; } // 其他请求遵循站点的维护模式设置 return NULL; }
模块启用后,站点处于维护模式时,所有以/jsonapi/开头的请求会绕过维护模式,正常返回数据。
方法二:装饰核心MaintenanceMode服务
通过Drupal的服务装饰器机制替换核心服务,逻辑更贴近核心代码的实现方式:
- 在自定义模块的
services.yml文件中添加服务配置:
services: maintenance_jsonapi_bypass.maintenance_mode: class: Drupal\maintenance_jsonapi_bypass\JsonApiMaintenanceMode decorates: maintenance_mode arguments: ['@maintenance_jsonapi_bypass.maintenance_mode.inner', '@config.factory', '@current_user'] public: false
- 创建
src/JsonApiMaintenanceMode.php文件,继承核心类并重写applies()方法:
<?php namespace Drupal\maintenance_jsonapi_bypass; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Site\MaintenanceMode; /** * 扩展核心MaintenanceMode类,实现JSON:API路径跳过维护模式 */ class JsonApiMaintenanceMode extends MaintenanceMode { /** * {@inheritdoc} */ public function applies(RouteMatchInterface $route_match) { // 先执行父类的维护模式判断逻辑 $applies = parent::applies($route_match); if (!$applies) { return FALSE; } $path_info = \Drupal::request()->getPathInfo(); // 检查是否为JSON:API请求路径 if (strpos($path_info, '/jsonapi/') === 0) { return FALSE; } return $applies; } }
启用模块后,核心的维护模式逻辑会被装饰后的服务替代,自动跳过JSON:API路径的维护模式限制。
注意事项
- 自定义模块需符合Drupal 9规范,包含
maintenance_jsonapi_bypass.info.yml文件定义模块基本信息。 - 测试时需验证JSON:API请求在维护模式下正常返回,同时其他页面正确显示维护模式页面。
内容的提问来源于stack exchange,提问作者rhodes
相关产品推荐
相关产品推荐

