Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RESTful API response in Laravel 5

I'm building RESTful API with Laravel. My API always returns JSON. What I would like to do, is keeping response logic at one place. Here's how I do it right now in API controller, which is pointed to by Route::controller(). Funny and ultra-useful example coming:

public function getDouble($number) {
    try {
        if (!is_numeric($number)) {
            throw new HttpException(400, 'Invalid number.');
        }

        $response = $number * 2;
        $status = 200;
    }
    catch (HttpException $exception) {
        $response = $exception->getMessage();
        $status   = $exception->getStatusCode();
    }

    return response()->json($response, $status);
}

In this example, my API route would be for example /double/13 accessed by GET method. The problem is that I repeat this try ... catch block in each method. I would like my API methods to be like:

public function getDouble($number) {
    if (!is_numeric($number)) {
        throw new HttpException(400, 'Invalid number.');
    }

    return $number;
}

And then, catch those exceptions and form JSON in another place. What is the best approach here in terms of good application architecture?

like image 235
Robo Robok Avatar asked Feb 24 '15 09:02

Robo Robok


1 Answers

Response on Exception

You could do this by handling the exception in App\Exceptions\Handler.

You could do it in the render method, likeso :

/**
 * Render an exception into an HTTP response.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Exception  $e
 * @return \Illuminate\Http\Response
 */
public function render($request, Exception $e)
{
    if($e instanceof HttpException) {
        return response()->json($e->getMessage(), $e->getStatusCode());
    }

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

Success Response

There are several ways to do this but I guess Middleware would be the best suited one right.

  • Create a middleware (say, ApiResponseFormatterMiddleware)
  • In your 'App\Http\Kernel', add it to $routeMiddleware array.
  • Apply it to the api routes, response to which you want to parse.

You could do something in the lines of :

/**
 * Handle an incoming request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Closure  $next
 * @return mixed
 */
public function handle($request, Closure $next)
{
    $response = $next($request);

    return response()->json($response->getOriginalContent());
}

Ofcourse, you need to change a bit of logic to parse the content the way you want it, but skeleton remains the same.

like image 60
ultimate Avatar answered Oct 05 '22 15:10

ultimate