DEV Community

Viktor Le
Viktor Le

Posted on

How to detect a request is API or Web in laravel

I am working on a Project, of which the structure is based on Laravel and, my situation is to return a Validation Error JSON Format or Auto-Carried in Flashed Session (stored in $errors variable) given by a Request.
To strategize the JSON response format, I actually work with Handler Exception. So, I implement a custom ApiValidationErrorException class for Json Format, which looks like as bellow:

<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpFoundation\Response;

class ApiValidationErrorException extends ValidationException
{
    public function render($request): JsonResponse
    {
        return new JsonResponse([
            // This is the array that you will return in case of an error.
            // You can put whatever you want inside.
            'message' => 'There were some errors',
            'status' => false,
            'additionalThings' => 'Some additional things',
            'errors' => $this->validator->errors()->getMessages(),
        ], Response::HTTP_UNPROCESSABLE_ENTITY);
    }
}
Enter fullscreen mode Exit fullscreen mode

then, call this custom class in Handler->register function, it looks like

<?php

namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Validation\ValidationException;
use Throwable;

class Handler extends ExceptionHandler
{

    /**
     * Register the exception handling callbacks for the application.
     */
    public function register(): void
    {
        $this->renderable(function (ValidationException $exception, $request) {
            throw ApiValidationErrorException::withMessages(
                $exception->validator->getMessageBag()->getMessages()
            );
        });

        $this->reportable(function (Throwable $e) {
            //
        });
    }
}

Enter fullscreen mode Exit fullscreen mode

However, this register throws a problem for returning errors on web request. Instead of displaying messages in HTML which is generated from blade templates, it returns a JSON response because the renderable method always throws ApiValidationErrorException format.

So, this definitely needs a if else statement here to control the response properly.

So, the conditional statement detect the request whether it is RESTful Request or Form Request. Alright, Laravel provides a method on request Object name wantsJson(), which checks the client request sends Accept=application/json in Header. So to use it, we have to set Accept=application/json in Header otherwise, this method returns false always. Then, I ask myself, is there any options to check API request? . Right, I search and search ... it comes up with a method, $request->is('api/*'). Utimately, the register() method looks like

    public function register(): void
    {
        $this->renderable(function (ValidationException $exception, $request) {
            if ($request->wantsJson() || $request->is('api/*')) {
                throw ApiValidationErrorException::withMessages(
                    $exception->validator->getMessageBag()->getMessages()
                );
            }

            return null;

        });

        $this->reportable(function (Throwable $e) {
            //
        });
    }
Enter fullscreen mode Exit fullscreen mode

I hope this post could help some of you strategize the reponse format in such a situation

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read full post →

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up