movepixels's avatar

Get Route method

Just curious if there is a way to return the method expected from a route?

Laravel acts as a backend only and I would like to return in the response a links object which is easily done in a resource like:

'links'=> [
    'delete' => route('user.destroy', ['user' => $this->id]),
],

But I would like to include the method expected so the frontend would not need to code the http method.

'links' => [
    'delete' => [
        'url' => route('user.destroy', ['user' => $this->id),
        'method' => ??? How to get the expected method ???
   ] 
],

Anyone know how or if this is possible?

0 likes
15 replies
movepixels's avatar

Thanks, but pointless.

I took a quick read, but as stated Laravel is backend API. No view / blade so including @route to blade is where I stopped reading.

For the sake of manually typing "method" => 'post' vs adding a complete package is just over kill I think.

All I wanted was something like this.

'method/ => array_values(\Route::current()->methods())[0]; // returns patch, or get whatever the method is.

But that only works on the current active route being called to the API. I need to get a complete set of routes per request related specific to that request.

Manually typed out

'links' => [
        'delete' => [
          'url' => route('user.destroy', ['user' => $this->id, 'profile' => $profile]),
          'method' => 'delete',
        ],
        'update' => [
          'url' => route('user.update', ['user' => $this->id, 'profile' => $profile]),
          'method' => 'patch',
        ]
],

If there was a way to get methods() from a route by using the route name.

\Route::whereName('user.update')->methods();

Thats all I am asking. If there is something like that.

Thanks,

Dave

mstrauss's avatar

Hey @movepixels

Not sure if this is what you are looking for but\Illuminate\Routing\Route has a method called methods, see below:

    /**
     * Get the HTTP verbs the route responds to.
     *
     * @return array
     */
    public function methods()
    {
        return $this->methods;
    }

So you can do something like this in a controller

   public function index(Route $route)
    {

        dd($methodsRespondedTo = $route->methods());
        
        return view('home');
    }

The dumped output is like the below:

array:2 [▼
  0 => "GET"
  1 => "HEAD"
]
1 like
Snapey's avatar

Sorry it was pointless. Yes, I should have gone to bed.

Study the code behind the artisan route:list command?

movepixels's avatar

Sorry guys. Its not accessed via a route.

The current route has nothing to do with it.

I am using a Resource for the API which returns a formatted / structured JSON object to the front end.

Now when I return this I also want to include links I deem necessary for that request. So on say a request to the named route users.index I say to myself what links will be needed on the front end for this?

Well there will be a link to add a new user, one to edit a user, one to delete a user so I write out .

https://laravel.com/docs/5.7/eloquent-resources#adding-meta-data

// these are the links i need on the front end
'links' => [
        'create' => [
          'url' => route('user.create']),
          'method' => 'post',
        ],
        'delete' => [
          'url' => route('user.destroy', ['user' => $this->id, 'profile' => $profile]),
          'method' => 'delete',
        ],
        'update' => [
          'url' => route('user.update', ['user' => $this->id, 'profile' => $profile]),
          'method' => 'patch',
        ]
],

So the front end all i need to use as a button / link is links.create.url or links.delete.url but I am manually typing the method in laravel.

Thats why I was asking how I can get the method from the route name. I am not on any of these route so current() would do nothing.

Thanks,

Hope that makes it clearer the idea.

dev_nope's avatar
dev_nope
Best Answer
Level 10

That makes total sense now :)

As @snapey suggested, by looking at the logic behind the php artisan route:list artisan command, you can see how Laravel is getting info about a given route. See the source code here: https://github.com/laravel/framework/blob/5.8/src/Illuminate/Foundation/Console/RouteListCommand.php

I did a quick test to see what's the result of $router->getRoutes() from the file above and it for sure returns a list of routes grouped by the HTTP methods (I created this temp route in my routes/web.php file):

Route::get('/test', function (\Illuminate\Routing\Router $router) {
    dd($router->getRoutes());
});

TBH, I think what you have is clean enough and not sure if you need to complicate things. You just need to make sure to update the HTTP method for a route in 2 different places. That's up to you obviously.

1 like
movepixels's avatar

Thanks!

Yeah it was not a top priority feature. I was just curious to avoid possible typing the wrong method, but easily traceable if that did happen to fix it.

Dave

1 like
Snapey's avatar

remember Ziggy that you dismissed as pointless?

Well of course there is a back end element to what ziggy does. It still has to prepare an array of named routes and send them to the client. It also supports blacklist and whitelist filtering which is akin to your filtering of the routes to be relevant to the current resource.

https://github.com/tightenco/ziggy/blob/master/src/RoutePayload.php

movepixels's avatar

Sorry Snapey, you dont understand the situation. Thanks for the suggestion all the same.

The Current route has no effect / value.

I could be on the dashboard page which has no model, no relations to anything just a page. Yet on that page are 25 widgets each with its own set of links / route. Each widget has its own Resource, so on dashboard those Resources are used to create a multi dimensional response. If I use the widget as a page it still returns the same links required.

I know what links are required for each "widget" so to get a full list / filter that list vs typing method => post? Seems like overkill, if I lived across the street from work and took a helicopter would that be the most efficient way?

Your time is appreciated, but as dev_nope said just keep it as it is "I think what you have is clean enough and not sure if you need to complicate things."

Snapey's avatar

I wasn't suggesting that it was related to current route or that you get a full route list. I thought you might be looking to create a function with an api like

    $links = $this->resolveLinks(['user.create', 'user.destroy', 'user.update'], $user);

and it would resolve those named routes from all the routes and build the appropriate url and tag with the appropriate method.

1 like
movepixels's avatar

Thats more the ideas I was looking for Snapey, but I am getting error.

resolveLinks does not exist

But I will play around with it.

Snapey's avatar

Well no, it does not exist. You have to write it based on the earlier suggestions. Sorry if I falsely got your hopes up.

movepixels's avatar

No worries. I will just hard code them as I have it. Not a big issue. I was just curious if there was a 1 line simple way to get the method. But hard coding it, once its set and tested it will never change anyways so in the end the idea is rather pointless.

Thanks again all for your time and ideas!

Dave

ahmedsaber111's avatar
public static function getRouteMethod($namedRoute)
    {

        $routeCollection = Route::getRoutes();
        if($routeCollection->hasNamedRoute($namedRoute))
        {
            $route = $routeCollection->getByName($namedRoute);
            return $route->methods[0];
        }

    }

Please or to participate in this conversation.