php – 404 Issue in Laravel API when required param value not passed-ThrowExceptions

Exception or error:

Request class

class LoginRequest extends Request
{

    public function authorize() {
        return true;
    }

    public function rules() {
        return [
            'EmailAddress'  => 'required',
            'Password'      => 'required',
        ];
    }

    public function messages() {
        return [
            "EmailAddress.required" => trans("login.RequiredEmailAddress"),
            "Password.required"     => trans("login.RequiredPassword")
        ];
    }
}

Route

Route::post('/AuthenticateUser', 
    array(
        'uses' =>  'API\Login\apiLoginController@AuthenticateUser', 
        'as'   =>  'AuthenticateUser'
    )
);

Controller Action Method

I have a controller, I did so far for request class only to validate the input parameters. below is the action method

public function AuthenticateUser(LoginRequest $request) {
    dd("Hello");
}

Url

localhost:85/Laravel/public/api/v1/AuthenticateUser

I am using Postman Chrome extension to test the Url. So, as we can see that in the Request class both Email Address and the password are required parameters.

When I pass both parameters value. there is not issue and everything works. When I keep the Email Address value empty…I got 404 error and here is the screenshot.

Am I missing something to get rid of 404 error when Email address is not given? I am expecting an error message to enter Email Address

enter image description here

Below is the working state when I pass both email and password

enter image description here

How to solve:

Finally got it working by changing the request class like below.

class LoginRequest extends Request
{

    public function wantsJson() {
        return true;
    }

    public function authorize() {
        return true;
    }

    public function rules() {
        return [
            'EmailAddress'  => 'required',
            'Password'      => 'required',
        ];
    }

    public function messages() {
        return [
            "EmailAddress.required" => trans("login.RequiredEmailAddress"),
            "Password.required"     => trans("login.RequiredPassword")
        ];
    }
}

just added below code.

public function wantsJson() {
    return true;
}

Answer:

Solution 1:

I managed to get rid of the 404 and return a 422 by adding the following header in the request:

accept:application/json

This is not really a bug in Laravel as Taylor pointed out but a way to differentiate if it is an AJAX/API request or not.

Solution 2:

Alternatively, if you don’t want the client to specify that header, you can create a middleware that will add the header accept:application/json on every API requests. Here’s how:

  1. Create a new middleware: app/Http/Middleware/ForceJsonResponse.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class ForceJsonResponse
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        $request->headers->set('Accept', 'application/json');

        return $next($request);
    }
}

  1. In /app/Http/Kernel.php, inside $middlewareGroups.api, specify the namespace to your newly created middleware:
    protected $middlewareGroups = [
        'web' => [...],
        'api' => [
            [...]
            \App\Http\Middleware\ForceJsonResponse::class,
        ],
    ];

Answer:

It is because you are validating directly on route handling and not matching throughs NotFoundException. You need to pass the Request to your Controller as is and do:

$this->validate($request, [
            'EmailAddress'  => 'required|email',
            'Password'      => 'required',
        ]);

Leave a Reply

Your email address will not be published. Required fields are marked *