How to enforce JSON format in API Requests and Responses
Best Practices for Structuring, Validating, and Enforcing JSON in Laravel API Development

I’m a Software Engineer with over 5+ years of experience in Technology with a track record in building web applications, mobile applications and Technical Writing. Readily available to explore innovations in ICT and creatively use them to build solutions. Advancing my career in software engineering and contributing to the growth of tech communities around the world. I’m also passionate about working with organizations especially tech, security experts and airline industries to learn and also make contributions that will be a legacy.
Tech is Easy to Learn - https://amazon.com/dp/B0B8T838K
Introduction
There are several ways to ensure standard JSON format in API requests and responses which enforces consistent and structured data exchange. In this article, we’ll explore how to enforce JSON format on incoming requests in a Laravel application and outgoing responses.
How to enforce Request in JSON Format
When designing APIs in Laravel, it is important to enforce requests to be in JSON format. This helps ensure consistency, prevents unexpected request formats (such as HTML or other types other than JSON), and avoids receiving data from random or unintended sources. Additionally, enforcing JSON format improves security and simplifies request handling.
Here’s out to enforce API request to be in JSON format in Laravel.
Create a middleware EnforceJsonRequest
php artisan make:middleware EnforceJsonRequest
The EnforceJsonRequest middleware is located in app/Http/Middleware/EnforceJsonRequest.php
Define EnforceJsonRequest Middleware Condition
- Open the
EnforceJsonRequest.phpand define the middleware conditions to intercept requests and check the format
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class EnforceJsonRequest
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
$contentType = $request->header('Content-Type');
if (strpos($contentType, 'application/json') === false && strpos($contentType, 'multipart/form-data') === false) {
return response()->json(['error' => 'Invalid Content-Type. Must be JSON or multipart/form-data.'], Response::HTTP_EXPECTATION_FAILED);
}
return $next($request);
}
}
The code validates the request's Content-Type header to ensure it is either application/json or multipart/form-data (commonly used for file uploads in APIs). If the request does not meet this requirement, it returns an error response, preventing invalid or unexpected data formats.
Register the EnforceJsonRequest middleware
- Register the middleware in the
withMiddlewarecallback function inbootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
$middleware->trustProxies(at: '*');
$middleware->alias([
'enforce-json-request' => EnforceJsonRequest::class,
]);
})
Set EnforceJsonRequest Middleware to Routes
Apply the middleware to the API routes that must receive request in json format:
In a fresh Laravel application, the api.php setup is not included by default. However, you can generate it using the command php artisan install:api or manually create the api.php file and register it within the withRouting method in bootstrap/app.php.
->withRouting(
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
- Create the
api.phpfile and set the middleware on the routes
<?php
use Illuminate\Support\Facades\Route;
Route::prefix('/v1')->middleware(['enforce-json-request'])->group(function () {
Route::get('/', function () {
return response()->json([
'message' => 'Request came in JSON Format',
], 200);
});
});
Serve the application using the php artisan serve command:
Incoming Request in Action
- Request to the application without
content-typeheader ofapplication/json

- Request with
content-typeset toapplication/json

How to enforce JSON response
Laravel checks the Accept header in the request to determine the appropriate response. However, browsers and Postman often send Accept: */*, so simply rewriting this header ensures Laravel handles the rest.
Create the EnforceJsonResponse Middleware
Use the command below to create a middleware with any name of your choice.
php artisan make:middleware EnforceJsonResponse
Define the EnforceJsonResponse Middleware condition
- Update the
EnforceJsonResponsemiddleware in theapp/Http/Middleware/EnforceJsonResponse.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class EnforceJsonResponse
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
$request->headers->set('Accept', 'application/json');
$response = $next($request);
if (!$response instanceof JsonResponse) {
return response()->json($response->original ?? ['message' => 'Invalid response'], $response->status());
}
return $response;
}
}
Register the middleware EnforceJsonResponse
Register the middleware in bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
$middleware->trustProxies(at: '*');
$middleware->alias([
'enforce-json-request' => EnforceJsonRequest::class,
'enforce-json-response' => EnforceJsonResponse::class,
]);
})
Enforce Response Middleware on Routes
- Define a route that returns a response not in json format
<?php
use Illuminate\Support\Facades\Route;
Route::prefix('/v1')->middleware(['enforce-json-request'])->group(function () {
Route::get('/', function () {
return 'Request came in JSON Format';
});
});
- Output is in HTML Format when request is made without
enforce-json-responseon the route returning response.

- Add the
enforce-json-responseto the API route
<?php
use Illuminate\Support\Facades\Route;
Route::prefix('/v1')->middleware(['enforce-json-request', 'enforce-json-response'])->group(function () {
Route::get('/', function () {
return 'Request came in JSON Format';
});
});
- Or use
appendToGroupon withMiddleware callback function in thebootstrap/app.phpto keep the api route clean
->withMiddleware(function (Middleware $middleware) {
$middleware->trustProxies(at: '*');
$middleware->alias([
// 'enforce-json-request' => EnforceJsonRequest::class,
// 'enforce-json-response' => EnforceJsonResponse::class,
]);
$middleware->appendToGroup('enforce-json', [
EnforceJsonResponse::class,
EnforceJsonRequest::class
]);
})
- API route
<?php
use Illuminate\Support\Facades\Route;
Route::prefix('/v1')->middleware(['enforce-json'])->group(function () {
Route::get('/', function () {
return 'Request came in JSON Format';
});
});
Response in Action
- Output in JSON format when request is made with
enforce-json-responseon the route returns response.

Handling Exceptions response in JSON format
->withExceptions(function (Exceptions $exceptions) {
$exceptions->shouldRenderJsonWhen(function (Request $request, Throwable $th) {
return $request->is('api/*') || $request->expectsJson();
});
})->create();
- Returns error in JSON format but with too much technical details needed for debugging purposes only
{
"message": "syntax error, unexpected token \"}\", expecting \";\"",
"exception": "ParseError",
"file": "/path to error file",
"line": 13,
"trace": [
]
}
- You can define a global exception handling error response in JSON to return the message alone
->withExceptions(function (Exceptions $exceptions) {
$exceptions->renderable(function (Throwable $e, Request $request) {
return new JsonResponse([
'message' => $e->getMessage(),
], $e->getCode() ?: 500);
});
})

Handle individual exception response in JSON format
Alternatively, you can handle individual exceptions by returning custom responses in JSON format.
->withExceptions(function (Exceptions $exceptions) {
$exceptions->shouldRenderJsonWhen(function (Request $request, Throwable $th) {
return $request->is('api/*') || $request->expectsJson();
});
$exceptions->renderable(function (ParseError $e) {
return response()->json([
'message' => "Syntax error",
], Response::HTTP_INTERNAL_SERVER_ERROR);
});
})
- Output

NotFoundHttpException, ParseError, MethodNotAllowedHttpException etc. You can customize how these errors are handled to make the error message clear and user friendly while logging technical details for debugging purpose.Conclusion
You can define and structure request and responses in Laravel when building APIs in JSON format. It makes provision for consistency, clean code, proper data exchange format etc. In this article, we’ve explore best practices for enforcing JSON format in Laravel, including request validation, response formatting, and error handling to create well-structured and predictable APIs. Implementing these best practices enhances API performance and improves integration with frontend applications and third-party services. Laravel developers can build more robust and maintainable APIs, by prioritizing JSON enforcement.
Find this article useful… kindly share with your network and feel free to use the comment section for questions, answers, and contributions.



