Laravel optional parameter in API-request perceived incorrectly

432 Views Asked by At

In my api.php I've these routes.

I can request endpoint: /api/v2/commodities/1 - this request is being redirected to APICommodityController@read - this is OK!

The problem occur whenever I GET-request /v2/commodities/categories/. I'd like this request to be redirected into the route-group: 'categories', but instead Laravel perceive this as a optional parameter within the first group (~ ref. "HERE" in code-comment).

How do I fix this?

Route::group( [ 'prefix' => 'v2' ], function() {

    /**
     * Commodity
     */
    Route::group( [ 'prefix' => 'commodities' ], function() {

        /**
         * C: CREATE
         */
        Route::post( '{id?}', 'API\v2\Commodity\APICommodityController@updateOrCreate' );

        /**
         * U: UPDATE
         */
        Route::put( '{id}', 'API\v2\Commodity\APICommodityController@updateOrCreate' );

        /**
         * R: READ (HERE)
         */
        Route::get( '{id?}', 'API\v2\Commodity\APICommodityController@read' );

        /**
         * D: DELETE
         */
        Route::delete( '{id}', 'API\v2\Commodity\APICommodityController@delete' );

        /**
         * Commodity categories
         */
        Route::group( [ 'prefix' => 'categories' ], function() {

            /**
             * C: CREATE
             */
            Route::post( '{id?}', 'API\v2\CommodityCategories\APICommodityCategoriesController@updateOrCreate' );

            /**
             * U: UPDATE
             */
            Route::put( '{id}', 'API\v2\CommodityCategories\APICommodityCategoriesController@updateOrCreate' );

            /**
             * R: READ
             */
            Route::get( '{id?}', 'API\v2\CommodityCategories\APICommodityCategoriesController@read' );

            /**
             * D: DELETE
             */
            Route::delete( '{id}', 'API\v2\CommodityCategories\APICommodityCategoriesController@delete' );

        } );

    } );
2

There are 2 best solutions below

0
Masoud Haghbin On BEST ANSWER

add this condition at the end of your id parameters :

->where('id', '[0-9]+')

so it becomes something like this :

Route::get( '{id?}', 'API\v2\Commodity\APICommodityController@read' )->where('id', '[0-9]+');
0
ortho On

Simply move your Commodity categories route section above all other route definition. This will make laravel register this static route and not be caught by dynamic routing.

Something like that:

Route::group( [ 'prefix' => 'v2' ], function() {

    /**
     * Commodity
     */
    Route::group( [ 'prefix' => 'commodities' ], function() {
        /**
         * Commodity categories
         */
        Route::group( [ 'prefix' => 'categories' ], function() {

            /**
             * C: CREATE
             */
            Route::post( '{id?}', 'API\v2\CommodityCategories\APICommodityCategoriesController@updateOrCreate' );

            /**
             * U: UPDATE
             */
            Route::put( '{id}', 'API\v2\CommodityCategories\APICommodityCategoriesController@updateOrCreate' );

            /**
             * R: READ
             */
            Route::get( '{id?}', 'API\v2\CommodityCategories\APICommodityCategoriesController@read' );

            /**
             * D: DELETE
             */
            Route::delete( '{id}', 'API\v2\CommodityCategories\APICommodityCategoriesController@delete' );

        } );

        /**
         * C: CREATE
         */
        Route::post( '{id?}', 'API\v2\Commodity\APICommodityController@updateOrCreate' );

        /**
         * U: UPDATE
         */
        Route::put( '{id}', 'API\v2\Commodity\APICommodityController@updateOrCreate' );

        /**
         * R: READ (HERE)
         */
        Route::get( '{id?}', 'API\v2\Commodity\APICommodityController@read' );

        /**
         * D: DELETE
         */
        Route::delete( '{id}', 'API\v2\Commodity\APICommodityController@delete' );
    } );