laravel icon indicating copy to clipboard operation
laravel copied to clipboard

route model binding (Variable name cannot be longer than 32 characters in route pattern)

Open matthijs opened this issue 1 year ago • 9 comments

Hi,

Due to the naming of one of our resources the variable name became too long. (more then 32 characters)

Simplest solution was to short the variable name by using the following:

$server->resource('some-very-long-name-activities', '\\' . JsonApiController::class)
    ->parameter('short_name')
    ->readOnly();

Now when executing a request like:

GET /api/v1/some-very-long-name-activities/<id>

Now I get a 404 Not found. The record that I am trying to fetch exists.

Usual without laravel-json-api I fix this by using:

Route::model('short_name', SomeModel::class);

But due to the fact that laravel-json-api uses its own substitute bindings this does not seem to work.

The question now is: What am I missing?

matthijs avatar Apr 18 '24 08:04 matthijs

Can you show the php artisan route:list?

ben221199 avatar Apr 18 '24 09:04 ben221199

Sure, here it is (only the routes related to this problem):

GET|HEAD        api/v1/external-service-provider-activities ....................................................... api.v1.external-service-provider-activities.index › LaravelJsonApi\Laravel › JsonApiController@index
GET|HEAD        api/v1/external-service-provider-activities/{esp_activity} .......................................... api.v1.external-service-provider-activities.show › LaravelJsonApi\Laravel › JsonApiController@show

The index is action is working correctly.

matthijs avatar Apr 18 '24 09:04 matthijs

I think the '\\' . is not neccessary.

Do you also have the schema?

ben221199 avatar Apr 18 '24 09:04 ben221199

Ok, nevermind. I found the problem.

In our schema we had a double ID::make() definition like:

    /**
     * Get the resource fields.
     */
    public function fields(): array
    {
        return [
            ID::make()->uuid(),

            Str::make('name')->sortable(),
            Str::make('description')->sortable(),

            ID::make('chain')->sortable(); // causing the trouble...

            DateTime::make('created_at')->sortable()->readOnly(),
            DateTime::make('updated_at')->sortable()->readOnly(),
        ];
    }

The fact that ID::make('chain')->sortable() had no ->uuid() did change the regex for the route pattern to an integer regex. And that caused the 404 not found exception.

Thanks for trying to help out and sorry for the trouble.

Maybe check if there are multiple ID::make() definitions returned and throw an exception in that case? That could help catching this kind of bug earlier...

matthijs avatar Apr 18 '24 10:04 matthijs

Yeah, that makes sense. I had the feeling it had something to do with the ID anyway.

ben221199 avatar Apr 18 '24 10:04 ben221199

@lindyhopchris Is this an option in some way?

Maybe check if there are multiple ID::make() definitions returned and throw an exception in that case? That could help catching this kind of bug earlier...

ben221199 avatar Apr 18 '24 10:04 ben221199

@lindyhopchris Is this an option in some way?

Maybe check if there are multiple ID::make() definitions returned and throw an exception in that case? That could help catching this kind of bug earlier...

So "checking something" has cost, that you incur every single time the schema is created in a request. Just to catch a mistake a developer has made...

I'll take a look but will only do something if it doesn't add in any extra processing.

lindyhopchris avatar Apr 19 '24 12:04 lindyhopchris

Maybe you could do something with debug mode? Performance is less important when debugging locally why something doesn't work.

ben221199 avatar Apr 19 '24 14:04 ben221199

So "checking something" has cost, that you incur every single time the schema is created in a request. Just to catch a mistake a developer has made...

I'll take a look but will only do something if it doesn't add in any extra processing.

I completely agree! For debugging purposes it would be handy if this could be catched but if that has a performance hit in production then please leave it out. Maybe add an extra note to the documentation about this.

matthijs avatar Apr 20 '24 08:04 matthijs