2
votes

I'm building web api along side with website in laravel 5.2, when user visit unavailable url on my web like http://stage.dev/unavailable/link then it will throw on 404 page on errors view resource, then i want to catch with different way if user try to access my API with unavailable url like http//stage.dev/api/v1/unavailable/link, then i want to return json/xml response

{
  'status' : 'not found',
  'code' : 404,
  'data' : []
}

not the view, is there a way to detect it by url prefix 'api/*' or how.., maybe another approach with similar result, so the device/client which access it could proceed by standard format (i have simple format in all json response)

{
  'status' : 'success|failed|restrict|...',
  'api_id' : '...',
  'token' : '...',
  'data' : [
    {'...' : '...'},
    {'...' : '...'},
    ...
  ]
}

SOLVED

I figure out something after read answer from Chris and Alexey this approach works for me i add couples of lines in handler.php at render() method,

    if($e instanceof ModelNotFoundException || $this->isHttpException($e)) {
        if($request->segment(1) == 'api' || $request->ajax()){
            $e = new NotFoundHttpException($e->getMessage(), $e);
            $result = collect([
                'request_id' => uniqid(),
                'status' => $e->getStatusCode(),
                'timestamp' => Carbon::now(),
            ]);
            return response($result, $e->getStatusCode());
        }
    }

my header request respond 404 error code and return json data like i want..

3
If it's solved, and was of your own accord, please submit an answer and mark it as correctChris

3 Answers

1
votes

Maybe there's a better way to do that, but you could create custom error 404 handler. Follow this tutorial, but change case 404 part to something like this:

if(str_contains(Request::url(), 'api/v1/')){
    return response()->json(your_json_data_here);
}else{
    return \Response::view('custom.404',array(),404);
}
1
votes

Inside App\Exception\Handler.php you have a render method which can be handy for general purpose error catching and handling.

In this case you can also use the request()->ajax() method to determine if it's ajax. It does this by checking that certain headers are present, in particular:

'XMLHttpRequest' == $this->headers->get('X-Requested-With')

Anyway, back to the render method in Handler.php.

You can do something like:

public function render($request, Exception $e)
{        

    if($e instanceof HttpException && $e->getStatusCode() == 404) {
        if (request()->ajax()) {
            return response()->json(['bla' => 'foo']);
        } else {
            return response()->view('le-404');
        }
    }

    return parent::render($request, $e);
}
0
votes

I figure out something after read answer from Chris and Alexey this approach works for me i add couples of lines in handler.php at render() method,,

    if($e instanceof ModelNotFoundException || $this->isHttpException($e)) {
        if($request->segment(1) == 'api' || $request->ajax()){
            $e = new NotFoundHttpException($e->getMessage(), $e);
            $result = collect([
                'request_id' => uniqid(),
                'status' => $e->getStatusCode(),
                'timestamp' => Carbon::now(),
            ]);
            return response($result, $e->getStatusCode());
        }
    }