0

Within a Laravel project, I want to create a POST /movies route associated with a controller that has been created with its model:

sail artisan make:model --controller --api --requests -- Movie

which has created among others the POST Form Request Validator (cf documentation Laravel 10.x) StoreMovieRequest and the controller MovieController with among others the store method:

public function store(StoreMovieRequest $request)

Finally, I declared the route within routes/api.php:

Route::post('/movies', [MovieController::class, 'store']);

But I only got a 404 Not Found, while this dummy route would succeeds:

Route::post('/movies', fn () => 'not implemented yet');

I tried many variation of the route declaration, they all produced a 404 Not Found:

Route::controller(MovieController::class)->group(function () {
    Route::get('/movies', 'index');
    Route::get('/movies/{id}', 'show');
    Route::post('/movies', 'store');
    Route::put('/movies/{id}', 'update');
    Route::delete('/movies/{id}', 'destroy');
});  // 404
Route::post('movies', [MovieController::class, 'store']);  // 404
Route::resource('movies', MovieController::class);  // 404
Route::apiResource('movies', MovieController::class);  // 404

I checked for many possible bug: bad namespace, bad file name, conflicting file name, etc. nothing has worked.

I found many stackoverflow potentially related to my problem, but none has solved this problem:

1 Answer 1

0

I finally found the issue thanks to this github issue: when using a Form Request Validator you need to add this header

Accept: application/json

in order to Laravel to find the controller’s method.

TL;DR

// With a "Form Request Validator", the header "Accept: application/json" is mandatory, otherwise 404
public function store(StoreMovieRequest $request) {}

// With the model directly, the method/route is found even if header "Accept: application/json" is missing
public function store(Movie $movie) {}

In Postman: Screenshot of the header in Postman

Sign up to request clarification or add additional context in comments.

4 Comments

The issue with not including the Accept: application/json has nothing to do with your Route definition; public function store(Movie $movie) {} isn't a valid Route, as the store() method is for creating a new Movie, so you wouldn't inject the Model the same way you do for show(Movie $movie) or edit(Movie $movie). If you don't include Accept: application/json, then the StoreMovieRequest triggers a redirect to a Route that likely doesn't exist (so you get the 404). This would happen as well if you do $request->validate() w/o that header. Correct solution, wrong explanation 😅
The Github issue you posted also goes into more details, with the same reasoning: github.com/laravel/framework/issues/…
Thanks @TimLewis for this precision, it looks like I was too quick to conclude once it worked after a lot of trial and error; on top of that, I just start to learn Laravel! I’ll correct my answer :-) !
No worries! Like I said, you got the correct solution, just needed a bit of clarification 🙂 Hope you enjoy working with Laravel!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.