Рейтинг:1

Выполнение подзапроса HTTP приводит к тому, что CurrentRouteMatch имеет неправильный маршрут

флаг by

По сложным и неприятным причинам[*] я хочу встроить данные сущности из модуля JSONAPI внутрь JSON, возвращаемого из ресурса модуля REST.

Я пытаюсь сделать это, отправив подзапрос HTTP к маршруту модуля JSONAPI в классе ресурсов модуля REST.

Как это:

    $kernel = \Drupal::service('http_kernel');

    $current_request = \Drupal::request();

    $request = Request::create('/jsonapi/paragraph/' . $paragraph->bundle() . '/' . $paragraph->uuid->value);
    $request->setSession($current_request->getSession());

    $response = $kernel->handle($request, HttpKernelInterface::SUB_REQUEST);
    $json = $ответ->getContent();
    $data = json_decode($json, ИСТИНА);

Я получаю нужные мне данные, и это здорово!

Однако основной запрос к конечной точке ресурса REST завершается с ошибкой:

Symfony\Component\Serializer\Exception\NotEncodableValueException: Сериализация для формата "api_json" не поддерживается. в Symfony\Component\Serializer\Serializer->serialize() (строка 112 файла /var/www/vendor/symfony/serializer/Serializer.php).

Это связано с тем, что в Drupal\rest\EventSubscriber\ResourceResponseSubscriber->getResponseFormat(), $route = $route_match->getRouteObject(); — это маршрут модуля JSONAPI из подзапроса, а не маршрут из основного запроса.

Что я делаю не так с моим подзапросом?

[*] Огромное количество пользовательского кода, обеспечивающего работу ресурса REST для несвязанного внешнего интерфейса. Я хочу изменить его на использование JSONAPI, но это серьезное изменение с огромными последствиями для внешнего интерфейса. Чтобы постепенно перейти на JSONAPI, я хочу переключить некоторые типы абзацев на формат JSONAPI. Можно напрямую вызвать PHP-код модуля JSONAPI, но это не публичный API и поэтому будущие версии Drupal могут его сломать. Создание подзапроса использует API и поэтому более удобно в обслуживании.

Jaypan avatar
флаг de
Почему вы выполняете подзапрос, а не используете HTTP-клиент Guzzle для выполнения своего запроса?
флаг by
Кто-то предложил мне использовать подзапрос Symfony в Slack. Разве HTTP-клиент Guzzle не будет означать отдельный запрос к серверу? Задействовано МНОГО объектов абзаца, поэтому добавление фактических HTTP-запросов, по-видимому, плохо скажется на производительности.
флаг by
Обновленный вопрос, чтобы более четко объяснить, что я хочу поместить данные JSON из одного в другой.
Рейтинг:2
флаг cn

После запуска подзапроса в стеке запросов полный беспорядок, он все еще содержит подзапрос, в то время как стек сопоставления маршрутов был очищен. Если вы затем получите текущее совпадение маршрута, это вернет вновь созданное совпадение маршрута на основе запроса API json.

Быстрым решением будет очистка стека запросов вручную, включая проверку, чтобы код все еще работал, когда основная проблема исправлена:

$current_request = \Drupal::request();

$request = Request::create('/jsonapi/node/page/UUID', 'GET', [], $current_request->cookies->all(), [], $current_request->server->all() );
$request->setSession($current_request->getSession());


$response = $kernel->handle($request, HttpKernelInterface::SUB_REQUEST);
if (\Drupal::request()->getPathInfo() !== $current_request->getPathInfo()) {
  \Drupal::requestStack()->pop();
}

Кстати, вашему подзапросу, вероятно, требуется больше метаданных из основного запроса. Я добавил файлы cookie и заголовки сервера в пример кода.

флаг by
Это было именно так - совпадение маршрута подзапроса загрязняло вещи. Является ли это основной ошибкой, и есть ли проблема для нее? У меня все работает, спасибо!! :)
флаг by
Не удалось найти существующую проблему, зарегистрированную https://www.drupal.org/project/drupal/issues/3218022.
Рейтинг:1
флаг by

С тех пор я обнаружил, что модуль jsonapi_extras обеспечивает ту же самую функциональность — получение JSONAPI-представления объекта путем выполнения подзапроса. Это, кажется, позволяет избежать проблемы, используя http_kernel.basic сервис, чтобы сделать подзапрос. Похоже, что это не сохраняет стек запросов, поэтому обходит проблему отслеживания нескольких запросов?

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.