Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Route::apiSingleton does not respect only() and except() #47088

Closed
phh opened this issue May 15, 2023 · 1 comment · Fixed by #47098
Closed

Route::apiSingleton does not respect only() and except() #47088

phh opened this issue May 15, 2023 · 1 comment · Fixed by #47098
Assignees

Comments

@phh
Copy link
Contributor

phh commented May 15, 2023

Laravel Version

10.10.1

PHP Version

8.2.5

Database Driver & Version

No response

Description

When using the apiSingleton() I have the ability to add a creatable() if I want it to be able to store the singleton. However, in my case I only want it to include store and not destroy. Which should be doable with ->only('store') or ->exist('destroy'), but it's not excluding it.

To me, I would expect the apiSingleton act kinda similar to apiResource

A quick look at the code, it seems like createable() and destroyable() does not care about these constraints and just returns their own expected methods:

    protected function getResourceMethods($defaults, $options)
    {
        $methods = $defaults;

        if (isset($options['only'])) {
            $methods = array_intersect($methods, (array) $options['only']);
        }

        if (isset($options['except'])) {
            $methods = array_diff($methods, (array) $options['except']);
        }

        if (isset($options['creatable'])) {
            $methods = isset($options['apiSingleton'])
                            ? array_merge(['store', 'destroy'], $methods)
                            : array_merge(['create', 'store', 'destroy'], $methods);

            return $this->getResourceMethods(
                $methods, array_values(Arr::except($options, ['creatable']))
            );
        }

        if (isset($options['destroyable'])) {
            $methods = array_merge(['destroy'], $methods);

            return $this->getResourceMethods(
                $methods, array_values(Arr::except($options, ['destroyable']))
            );
        }

        return $methods;
    }

Steps To Reproduce

Add following to api.php

class ApiController {
    function store() {
        return 'yay';
    }
}

Route::apiSingleton('/singleton-only-store', ApiController::class)
    ->only(['store'])
    ->creatable();

Route::apiSingleton('/singleton-except-destroy', ApiController::class)
    ->except(['destroy'])
    ->creatable();

Route::apiResource('/resource-only-store', ApiController::class)
    ->only(['store']);

Route::apiResource('/resource-except-destroy', ApiController::class)
    ->except(['destroy']);

In console run php artisan route:list:

... resource...
GET|HEAD          api/resource-except-destroy ................................. resource-except-destroy.index › ApiController@index
  POST            api/resource-except-destroy ................................. resource-except-destroy.store › ApiController@store
  GET|HEAD        api/resource-except-destroy/{resource_except_destroy} ......... resource-except-destroy.show › ApiController@show
  PUT|PATCH       api/resource-except-destroy/{resource_except_destroy} ..... resource-except-destroy.update › ApiController@update
  POST            api/resource-only-store ......................................... resource-only-store.store › ApiController@store


... singleton...

  POST            api/singleton-except-destroy ............................... singleton-except-destroy.store › ApiController@store
  DELETE          api/singleton-except-destroy ........................... singleton-except-destroy.destroy › ApiController@destroy
  GET|HEAD        api/singleton-except-destroy ................................. singleton-except-destroy.show › ApiController@show
  PUT|PATCH       api/singleton-except-destroy ............................. singleton-except-destroy.update › ApiController@update
  POST            api/singleton-only-store ....................................... singleton-only-store.store › ApiController@store
  DELETE          api/singleton-only-store ................................... singleton-only-store.destroy › ApiController@destroy
@nunomaduro
Copy link
Member

We've discussed this internally, in these methods creatable and destroyable were not meant to be combined with other things like only. However, we may reconsider this, so we've created this pull request: #47098.

Going to close this issue here, so we can follow up this issue more closely on the pull request I've created. Thank you for reporting this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants