Вот маршруты, над которыми я работаю (сгенерированные методом apiResource Laravel). Как видите, есть 1 или 2 заполнителя. Моя проблема возникает, когда я пытаюсь ПОЛУЧИТЬ anything/customers. Это вызывает это исключение:
Missing required parameters for [Route: json-api.customers.show] [URI: {tenant}/customers/{customer}].
Если я не упускаю очевидной вещи, маршрутизатор должен принять этот запрос, потому что anything/customers соответствует {tenant}/customers.
Я был бы очень признателен за любую помощь в этом. Заранее спасибо.
Обновлено: Я добавляю этот код, чтобы ответить на комментарий, но не думаю, что это поможет разобраться в этой проблеме (я реализую пакет на основе спецификации JSON:API).
protected function jsonApiResource()
{
return function (string $class, array $options = []) {
if ($routerMethod = $class::getRouterMethod()) {
$middleware = array_merge(
$options['middleware'] ?? [],
$class::getApiMiddlewares()
);
$as = $options['as'] ?? '';
$prefix = $class::getRouterPrefix();
$this->group(compact('middleware', 'as', 'prefix'), function ($router) use ($class, $routerMethod, $options) {
$alias = $class::getAlias();
$controller = $class::getControllerClass();
$router->{$routerMethod}(
$alias,
$controller,
Arr::only($options, ['only', 'except'])
);
foreach ($class::getRelationsRoutes() as $relationshipName => $relationshipMethods) {
$router->resourceRelationship(
$alias,
$relationshipName,
$controller,
$relationshipMethods
);
}
});
}
};
}
Код добавлен, но боюсь он вам не поможет
Хорошо, это намного сложнее, чем я думал :) Я бы попробовал отладить роутер, начиная с Illuminate\Routing\Router::findRoute()
Что ты хочешь, чтобы я выкинул?
Откуда этот пакет получает список имен маршрутов? Загружается ли он из БД? (Я знаю, что очень важно определять маршруты в правильном порядке, иначе сработает неправильный)
У меня нет никакого контроля над порядком генерации, потому что эти маршруты исходят из apiResource метода маршрутизатора самого Laravel.






Маршрутизатору довольно сложно определить переменную на любой стороне. Это может помочь добавить сплошной путь перед первым / лайком something/{tenant}/customers. Однако причина ошибки, скорее всего, в том, что первый GET-путь к маршрутизатору в соответствии с вашим списком маршрутов:
{tenant}/customers/{customer}
Потому что это первый, Laravel ожидает поступления переменной клиента. Если вы поместите эту строку выше, она не будет ожидать переменную каждый раз. Так:
{tenant}/customers/{customer}
{tenant}/customers/
Это должно помочь ... но это может быть не из-за подстановочных знаков с обеих сторон - вам придется проверить.
Если у вас есть эти наборы как resource, я предлагаю вам разбить их на отдельные методы маршрута для тестирования.
У меня не получилось воспроизвести проблему с битыми маршрутами Route::get('{tenant}/tests', function () {return response()->json(['test0']);}); Route::get('{tenant}/tests/{test1}', function () {return response()->json(['test1']);}); работает и наоборот (оба отвечают test0). Упаковать их в группу маршрутов с префиксом тоже можно...
Я думаю, это означает, что проблема, возможно, связана с двумя вещами, которые я отметил выше. Возможно, из-за подстановочного знака в первом слове вы неосознанно дублируете первое слово другого маршрута. IE {Route1}/customers на самом деле уже является жестко запрограммированным маршрутом Route1/customers где-то еще. Я бы проверил ваш текущий resource словом перед {tenant}, например testing/{tenant}/customers и т. д.
Я уже пробовал это, прежде чем открывать этот вопрос, и проблема также возникает здесь, к сожалению. Missing required parameters for [Route: json-api.customers.show] [URI: testing/{tenant}/customers/{customer}].
Стреляй, это печально. Мое единственное предложение — объединить две вещи — добавить первое слово (тестирование) и отделить их от resource. У меня это случалось раньше, и обычно это была одна или другая из этих двух вещей, которые я отметил выше (или обе).
Я попробую несколько тестов и дам вам знать, если найду рабочий способ. Спасибо, в любом случае.
Наконец, через 3 дня я узнал источник, сообщение об исключении ввело меня в заблуждение.
/**
* Get links to fetch the model or one of its relationships.
*
* @param string|null $relationshipName
* @return array
*/
public function getApiLinks(string $relationshipName = null)
{
$urlGenerator = app()->make('url');
$identifiers = $this->getApiIdentifiers();
if ($relationshipName) {
return [
'self' => $urlGenerator->jsonApiRelationship($identifiers['type'], $identifiers['id'], $relationshipName, 'index'),
'related' => $urlGenerator->jsonApiRelationship($identifiers['type'], $identifiers['id'], $relationshipName, 'related')
];
}
return [
'self' => $urlGenerator->route(
'json-api.'.$identifiers['type'].'.show',
[ Str::singular($identifiers['type']) => $identifiers['id'] ]
];
Проблема возникла из-за генерации URL-адреса при возврате, любой дополнительный заполнитель URL-адреса не был включен в массив и, кстати, привел к этому сообщению.
С этим исправлением теперь работает:
/**
* Get links to fetch the model or one of its relationships.
*
* @param string|null $relationshipName
* @return array
*/
public function getApiLinks(string $relationshipName = null)
{
$urlGenerator = app()->make('url');
$identifiers = $this->getApiIdentifiers();
$otherParams = $urlGenerator->getRequest()->route()->parameters();
if ($relationshipName) {
return [
'self' => $urlGenerator->jsonApiRelationship($identifiers['type'], $identifiers['id'], $relationshipName, 'index', $otherParams),
'related' => $urlGenerator->jsonApiRelationship($identifiers['type'], $identifiers['id'], $relationshipName, 'related', $otherParams)
];
}
return [
'self' => $urlGenerator->route(
'json-api.'.$identifiers['type'].'.show',
array_merge(
$otherParams,
[ Str::singular($identifiers['type']) => $identifiers['id'] ]
)
)
];
}
Спасибо в любом случае за вашу помощь!
Можете ли вы опубликовать код, определяющий маршруты?