[Drupal] ResourceResponseで作成したレスポンスにURLを入れるとエラーが出る場合の対処方
カスタムのRESTリソースプラグインを作成するときは、こんな感じで\Drupal\rest\ResourceResponse
オブジェクトを返す必要があるのですが、
/**
* Responds to entity GET requests.
* @return \Drupal\rest\ResourceResponse
*/
public function get() {
$response = ['message' => 'Hello, this is a rest service'];
return new ResourceResponse($response);
}
この配列の中に\Drupal\Core\Url
オブジェクトから作ったURLを入れると、
public function get() {
$response = [
'message' => 'Hello, this is a rest service'
'url' => Url::fromUri('internal:/test')->toString(), // '/test'という文字列
];
return new ResourceResponse($response);
}
以下のようなエラーになります。
サイトに予期せぬエラーが起こりました。しばらくたってから再度お試しください。<br><br><em class="placeholder">LogicException</em>: The controller result claims to be providing relevant cache metadata, but leaked metadata was detected. Please ensure you are not rendering content too early. Returned object class: Drupal\rest\ResourceResponse. in <em class="placeholder">Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext()</em> (line <em class="placeholder">154</em> of <em class="placeholder">core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php</em>). <pre class="backtrace">Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 158)
Symfony\Component\HttpKernel\HttpKernel->handleRaw() (Line: 80)
Symfony\Component\HttpKernel\HttpKernel->handle() (Line: 58)
Drupal\Core\StackMiddleware\Session->handle() (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle() (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass() (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle() (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle() (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle() (Line: 23)
Stack\StackedHttpKernel->handle() (Line: 708)
Drupal\Core\DrupalKernel->handle() (Line: 19)
</pre>
ちなみに、URLっぽい文字列に反応してるのかと思い、Url
から作らずにただの文字列をそのまま入れたらエラーにならなかった。
public function get() {
$response = [
'message' => 'Hello, this is a rest service',
'url' => '/test',
];
return new ResourceResponse($response);
}
とにかくプロセス中にUrl::fromUri()->toString()
が走るとだめっぽい。
この質問見ると、コントローラーでも同じ事象が起きるらしい。
https://drupal.stackexchange.com/a/225963/90523
public function demo() {
$build = ['#markup' => 'early rendering'];
$markup = \Drupal::service('renderer')->render($build);
$build = [
'#cache' => [
'contexts' => ['ip'],
],
];
return (new CacheableJsonResponse(['test'], 200))->addCacheableDependency(CacheableMetadata::createFromRenderArray($build));
}
レスポンスの問題というより、
Url::fromUri('internal:/test')->toString()
$markup = \Drupal::service('renderer')->render($build);
に対してエラーが起きてるのか。。。?
同じような質問のコメント欄。
https://drupal.stackexchange.com/questions/187086/trustedresponseredirect-failing-how-to-prevent-cache-metadata/187094#187094
To make Matthew's comment abundantly clear, Url::toString() seems to count as a render apparently, so if you are using this in your controller anywhere and do not sent TRUE to gather the cacheable meta data you will hit this trap.
つまり、Url::fromUri('internal:/test')->toString()
で実はレンダリング処理が走っていると。
よくわかんないけど以下のように書き換えたら治った。
public function get() {
$response = [
'message' => 'Hello, this is a rest service',
'url' => Url::fromUri('internal:/test')
// Drupal\Core\GeneratedUrlオブジェクトにする
->toString(TRUE)
// /testの文字列取得
->getGeneratedUrl(),
];
return new ResourceResponse($response);
}
Author And Source
この問題について([Drupal] ResourceResponseで作成したレスポンスにURLを入れるとエラーが出る場合の対処方), 我々は、より多くの情報をここで見つけました https://qiita.com/863/items/2b097a514d4746c9688d著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .