Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 757
Alberto Dallaporta Avatar asked Nov 30 '22 23:11

Alberto Dallaporta


1 Answers

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');
}
like image 111
Hamlet Minjares Avatar answered Dec 04 '22 03:12

Hamlet Minjares