13
votes

I'm writing a webservice API (in laravel 4.2).
For some reason, the routing to one of my controllers is selectively failing based on HTTP method.

My routes.php looks like:

Route::group(array('prefix' => 'v2'), 
    function()
    {
        Route::resource('foo', 'FooController',
            [ 'except' => ['edit', 'create'] ]
            );
        Route::resource('foo.bar', 'FooBarController',
            [ 'except' => ['show', 'edit', 'create'] ]
            );
    }
);

So, when I try any of GET / POST / PUT / PATCH / DELETE methods for the
project.dev/v2/foo or project.dev/v2/foo/1234 urls, everything works perfectly.

But, for some reason, only GET and POST work for project.dev/v2/foo/1234/bar. The other methods just throw a 405 (MethodNotAllowedHttpException).
(fyi, I am issuing requests via the Advanced Rest Client Chrome extension.)

What's going on?
What am I missing?

5
Maybe your API only supports currentproject.dev/v2/companies/legalname/1234/?silkfire

5 Answers

18
votes

Solved!
The answer can be found by running php artisan routes.

That showed me that DELETE and PUT/PATCH expect (require) a bar ID.
I happened to be neglecting that because there can only be one of this particular type of "bar". The easy fix it to simply add it to my URL's regardless, like project.dev/v2/foo/1234/bar/5678.

3
votes

For the ones who are using Laravel versions > 4.2 use this :

php artisan route:list

This will give the list of routes set in your application. Check if routes for PUT and DELETE are allowed in your routes or not. 405 error is mostly because there is no route for these methods.

2
votes

I don't know about older Laravel versions. But I use Laravel since 5.2 and it is necessary to include a hidden method input when using put, patch or delete.

Ex:

<input type="hidden" name="_method" value="PUT"> 

Check https://laravel.com/docs/5.6/routing#form-method-spoofing

0
votes

Just add a hidden input field to your form

    <input type="hidden" name="_method" value="PUT">

And keep form method as post

    <form method="post" action="{{action('')}}">
0
votes

If you want to use the method PUT in submit form you mast to see this link https://laravel.com/docs/5.6/routing#form-method-spoofing

But if you use ajax in your project you mast to do anything like this:

<form>
@method('PUT')
// your_element

on your script add:

$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});

$.ajax({
  url: {{ route('your_route', ':id') }},
  type: 'POST',
  data: data,
  dataType: 'json',
  cache: false,
}).done(function(data,status){
    // anything
}).fail(function(){
   // anything

});