I am using Laravel to create API and postman to check my API. When I am putting a right URL in postman it is working fine, but when I am putting a wrong URL it is showing HTML and Laravel 404 error, I want to return a message in JSON format, how would I do that.
-
3Does the fact it's a 404 not convey enough information already? It should be fairly clear to the caller what the problem is, no? A 404 means "What you asked for doesn't exist"...a client can detect the status code and use that to decide what to do next. What other information would you be wanting to provide, exactly? – ADyson Nov 13 '18 at 10:46
-
@ADyson I think you did not get me, I am saying when my URL is `http://localhost:8005/api/login` in postman it's showing token and values but when my URL is `http://localhost:8005/api/log` this is showing some HTML and Laravel 404 error page, I want this time to return a message in JSON format. like "Messege"=>"not found" – shashi verma Nov 13 '18 at 10:52
-
My point is that _you don't need to_ - the fact it's a 404 should be enough for the client to know what to do. A client expecting JSON is not going to try and display the HTML anyway. If the client encounters a HTTP error, it stops processing and deals with the error. It can just discard the HTML. If all you're planning to put in the JSON is "Not Found", that's redundant - everyone already knows what a 404 means. I don't think you need to do this - you'll go to a lot of effort for no practical gain. Perhaps I'm wrong - can you tell me how your client applications will benefit from this? – ADyson Nov 13 '18 at 10:55
-
@ADyson There is no client, this is my task to do, I google a lot and found that I have to update my `Exceptions/handler.php` but it did not work, that is why I am here. – shashi verma Nov 13 '18 at 11:02
-
"There is no client,"...there's always a client. Otherwise how is the request being made? "This is my task to do". Why? For what purpose exactly? If you want to do this, you must have some reason in mind why you think it will be helpful to whoever is reading the response. My point is that I don't think it provides any useful functionality, so there's really very little reason to spend your time on it. Judging by the upvotes on my first comment I'm not the only person who believes that. I'm trying to help you by stopping you wasting your time on something which has no practical value. – ADyson Nov 13 '18 at 11:04
-
@ADyson https://medium.com/techcompose/create-rest-api-in-laravel-with-authentication-using-passport-133a1678a876 I am following this to create API with passport auth and I thought the client who uses the project after production, I am a beginner with all this. So, I apolozies if I am wrong. – shashi verma Nov 13 '18 at 11:11
-
Ok but they don't need a JSON response for that, the fact that the server responds with 404 tells them everything they need to know already. If they simply requested a wrong URL then you don't need to give any extra info. It's usually the result of a bug in the application which is calling the API. You can override the default rendering, sure, but it's almost certainly not necessary. – ADyson Nov 13 '18 at 11:16
4 Answers
You should add the Accept
header set to application/json
to your postman request in the headers tab like so: :
This will tell Laravel that you want a json response, instead of HTML. The same would apply for any request inside your application.
As you can see, this is checked on the Illuminate\Http\Response
object, when the payload is set, it checks if it should be morphed to JSON:
/**
* Set the content on the response.
*
* @param mixed $content
* @return $this
*/
public function setContent($content)
{
$this->original = $content;
// If the content is "JSONable" we will set the appropriate header and convert
// the content to JSON. This is useful when returning something like models
// from routes that will be automatically transformed to their JSON form.
if ($this->shouldBeJson($content)) {
$this->header('Content-Type', 'application/json');
$content = $this->morphToJson($content);
}
// If this content implements the "Renderable" interface then we will call the
// render method on the object so we will avoid any "__toString" exceptions
// that might be thrown and have their errors obscured by PHP's handling.
elseif ($content instanceof Renderable) {
$content = $content->render();
}
parent::setContent($content);
return $this;
}
You can find the code here.
Hope this helps you.

- 3,727
- 1
- 26
- 34
-
Nope, that tells the server that you're _sending_ JSON. It has nothing to do with the response. You can set an "accept" header to hint to the server what kind of response you would like, but ultimately the server makes that decision – ADyson Nov 13 '18 at 10:53
-
@ADyson You are completly rigth, a huge slip on my part. I've already fixed my answer, thanks for the feedback. – Asur Nov 13 '18 at 10:57
-
Ok that's better. But if the server is unable to respond with JSON to that request (because it doesn't have the code and programming to do so) then the request would simply fail, which is not really a desirable outcome. The client would have to be sure that the endpoint can serve JSON. Currently the OP's endpoint is not doing that, and your answer doesn't provide a solution which would enable it to do so. – ADyson Nov 13 '18 at 10:57
-
2@ADyson Yes, but this is Laravel oriented, and the framework uses that header to format the response, I'm looking on the codebase for the code and I'll post it as soon as I find it. – Asur Nov 13 '18 at 10:59
-
@ADyson I found the code, check it out. The thing is laravel handles the 404 automatically, but he was getting the HTML response instead of the JSON, changing the header corrects that. I don't know, but it sounds like you are not familiar with Laravel framework, are you? – Asur Nov 13 '18 at 11:28
-
No, I just know raw PHP (and HTTP in general). Would Laravel pick up and handle in this way something which didn't map to any controller or action (as opposed to just trying to request a specific ID which doesn't exist)? And what is the content is not JSON-able? Would the regular HTML of the 404 be JSON-able? – ADyson Nov 13 '18 at 11:30
-
-
So OP would have to specify custom content? How would that be done? Where is setContent() to be called in the normal flow, especially if this problem occurs outside an action method (i.e. the URL requested does not map to any valid route)? – ADyson Nov 13 '18 at 11:34
-
1@ADyson That's briefly documented here https://laravel.com/docs/5.7/lifecycle, since Laravel intercepts every request and then route it, it can handle the missing routes aswell. – Asur Nov 13 '18 at 11:51
AS I understand OP's requriement, wants to override the the Not Found
exception rendering behaviour into a JSON response.
Laravel actually generates an exception
of type NotFoundHttpException
and render
it. To prevent this behaviour you can do this.
In 'app\Exceptions\Handler.php', you see a function
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $exception
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $exception)
{
// comment this line and return JSON Response.
//return parent::render($request, $exception);
return json_encode(array("message" => $exception->getMessage())); // or you can
}
PS: This is not an ultimate solution, just a workaround if you only want your API to return JSON
incase of errors.

- 3,975
- 3
- 27
- 36
-
what if the URL being called (incorrectly) is not even handled by PHP at all? – ADyson Nov 13 '18 at 11:18
-
@ADyson Can you state an example against your argument? Secondly, my solution will just returns the exception as `JSON` object instead of rendering it as `HTML`. – Farooq Ahmed Khan Nov 13 '18 at 11:19
-
@FarooqKhan thanks for reply, yes I found that I have to do changes in the `handler.php` something like this I found from WEB if ($exception instanceof NotFoundHttpException) { return response()->json([ 'message'=>'not found' ]); } return parent::render($request, $exception); – shashi verma Nov 13 '18 at 11:25
-
@ADyson you have a valid argument, but OP's question is more about what landed on PHP server to be specific on the `Laravel` app. – Farooq Ahmed Khan Nov 13 '18 at 11:33
-
@shashiverma yes, my solution is bit generic for all exceptions you can make it more precise by matching instance type if you only want `not-found-route` type scenarios to return JSON. – Farooq Ahmed Khan Nov 13 '18 at 11:34
You can add route fallback closure to your routes/api.php
Route::fallback(function(){
return response()->json(['message' => '<your message>'], 404);
});

- 11
- 1
https://laravel.com/docs/9.x/errors :
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Register the exception handling callbacks for the application.
*
* @return void
*/
public function register()
{
$this->renderable(function (NotFoundHttpException $e, $request) {
if ($request->is('api/*')) {
return response()->json([
'message' => 'Record not found.'
], 404);
}
});
}

- 668
- 7
- 14