39otrebla
39otrebla

Reputation: 1442

Laravel 5 - Customize JSON response on a Rest API server

I am completely new on Laravel, I am migrating my application from Slim Framework to, indeed, Laravel 5. Googling I haven't find much information about how to customize a JSON response. Let's say I have:

MODEL

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected $visible = [
        'username', 'posts',
    ]; 
}

CONTROLLER

<?php

namespace App\Http\Controllers;

use [...]

/* *
 *  Implicit controller
 */
class UserController extends Controller
{
    public function getIndex()
    {
        return response()->json(User::all(), 200);
    }
}

ROUTE

Route::controller('users', 'UserController');

What if I want to output that data in a JSON object like:

{"success": bool, "message": string, "data": array} 
// in this case 'array' would be User::all()

?

Does anyone know whether there's a library to handle this kind of stuff? Or Has anyone already addressed this in laravel somehow?

N.B. I know I can write a Middleware to "modify" the response, but I am not sure it is the right solution, and it is also painful to check into the middleware whether the response should contain an error or not.

Thank you.

Upvotes: 4

Views: 18374

Answers (2)

Hamlet Minjares
Hamlet Minjares

Reputation: 151

Is a kinda late response but maybe it'll be helpfull for someone further.

You can solve this with a Response Factory creating a Provider on your project, here is an example for Success and Error responses:

<?php
// Place this file on the Providers folder of your project
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Routing\ResponseFactory;

class ResponseServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot(ResponseFactory $factory)
    {
        $factory->macro('success', function ($message = '', $data = null) use ($factory) {
            $format = [
                'status' => 'ok',
                'message' => $message,
                'data' => $data,
            ];

            return $factory->make($format);
        });

        $factory->macro('error', function (string $message = '', $errors = []) use ($factory){
            $format = [
                'status' => 'error', 
                'message' => $message,
                'errors' => $errors,
            ];

            return $factory->make($format);
        });
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

Then on your providers value placed in config/app.php just add the class:

'providers' => [
    ...

    App\Providers\ResponseServiceProvider::class,
]

And it's done, as the provider is already aggregated, you can just call the macro using the response helper passing the respectives attributes. Eg:

$user = User::find(1); 

if($user) {
   return response()->success('Your custom success message', $user);
} else {
   return response()->error('Your custom error message', 'Validation errors or else');
}

Upvotes: 15

Yurich
Yurich

Reputation: 577

Did You try

return response()->json([
    'success'=>true, 
    'message'=>'string', 
    'data'=>User::all()
]);

?

Upvotes: 8

Related Questions