Builds nice, normalized and easy to consume REST JSON responses for Laravel powered APIs.

Last update: Aug 8, 2022

REST API Response Builder for Laravel

REST API Response Builder for Laravel

Latest Stable Version Codacy Grade Badge Monthly Downloads Code Quality Code Coverage License

Master branch: Unit Tests Static Analysis Coding Standards

Development branch: Unit Tests Static Analysis Coding Standards

Table of contents


Introduction

ResponseBuilder is a Laravel package, designed to help you build a nice, normalized and easy to consume REST API JSON responses.

Benefits

ResponseBuilder is written for REST API developers by REST API developer and is based on long-lasting experience on both "sides" of API. It's lightweight, with no dependencies, extensively tested and simple to use yet flexible and powerful, with support for on-the-fly data conversion, localization support, automatic message building, chained APIs and (hopefully) exhaustive documentation. But that's not all! The JSON structure produced by ResponseBuilder is designed with users of your API in mind, so its structure is predictible and well-defined which makes dealing with your API using ResponseBuilder library a breeze. Simple JSON response, with well-defined and predictable structure, easy to consume without any hassle or trickery. Your clients will love it. And will love you too :)

You are also covered in a case of emergency, as provided ExceptionHandlerhelper, ensures your API keeps talking JSON (and NOT lame HTML) to its clients even in case of unexpected.

Did I mention, you would also get testing traits that automatically add PHPUnit based unit test to your whole ResponseBuilder related code and configuration with just a few lines of code absolutely for free?

Features

License

  • Written and copyrighted ©2016-2021 by Marcin Orlowski <mail (#) marcinorlowski (.) com>
  • ResponseBuilder is open-sourced software licensed under the MIT license

GitHub

https://github.com/MarcinOrlowski/laravel-api-response-builder
Comments
  • 1. Support for Eloquent API Resources

    We're using API Resources to filter the model attributes that are transformed in JSON.

    Do you plan to support UserResources in the ResponseBuilder in addition to Collections and Arrays?

    Reviewed by aubreychiduku at 2019-11-04 12:31
  • 2. Pagination with Laravel API Resource Collections

    Not sure this is 100% correct place, but I've seen people are really active so hoping this is ok?

    This has been briefly mentioned in #109 but I must be missing something. Still not sure how to best get additional pagination information with the request. So far I have:

    public function index(Request $request)
        {
            return ResponseBuilder::success(new GraphicDownloadCollection(GraphicDownload::byAccount($request->user()->account->id)->jsonPaginate()));
        }
    

    NOTE The jsonPaginate comes from https://github.com/spatie/laravel-json-api-paginate, but even if I put standard Laravel paginate, I get same result.

    Which returns:

    {
        code: 0
        data: {
            items: {
                current_page: 1
                data: []
                first_page_url: "http://domain.test/api/v1/graphic-downloads?page%5Bnumber%5D=1"
                from: null
                last_page: 1
                last_page_url: "http://domain.test/api/v1/graphic-downloads?page%5Bnumber%5D=1"
                next_page_url: null
                path: "http://domain.test/api/v1/graphic-downloads"
                per_page: 10
                prev_page_url: null
                to: null
                total: 0
                locale: "en"
                message: "OK"
                success: true
            }
        }
    }
    

    Seems a better response would be:

    {
        code: 0
        data: {
            current_page: 1
            items: []
            first_page_url: "http://domain.test/api/v1/graphic-downloads?page%5Bnumber%5D=1"
            from: null
            last_page: 1
            last_page_url: "http://domain.test/api/v1/graphic-downloads?page%5Bnumber%5D=1"
            next_page_url: null
            path: "http://domain.test/api/v1/graphic-downloads"
            per_page: 10
            prev_page_url: null
            to: null
            total: 0
            locale: "en"
            message: "OK"
            success: true
        }
    }
    

    This is my ResourceCollection class for that particular model:

    <?php
    
    namespace App\Http\Resources;
    
    use Illuminate\Http\Resources\Json\ResourceCollection;
    
    class GraphicDownloadCollection extends ResourceCollection
    {
        /**
         * Transform the resource collection into an array.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return array
         */
        public function toArray($request = null)
        {
            return $this->resource;
        }
    }
    

    Any help would be greatly appreciated.

    Reviewed by mbaxter91288 at 2019-11-13 17:06
  • 3. ExceptionHandlerHelper always returns HTTP500 and code 113

    ExceptionHandlerHelper always returns HTTP 500 status code and API code 113 with default config file (no mappings).

    {
        "success": false,
        "code": 113,
        "locale": "fr",
        "message": "Unauthenticated.",
        "data": null,
        "debug": {
            "trace": {
                "class": "Illuminate\\Auth\\AuthenticationException",
                "file": "/var/www/project/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php",
                "line": 81
            }
        }
    }
    
    {
        "success": false,
        "code": 113,
        "locale": "fr",
        "message": "No query results for model X",
        "data": null,
        "debug": {
            "trace": {
                "class": "Illuminate\\Database\\Eloquent\\ModelNotFoundException",
                "file": "/var/www/project/vendor/laravel/framework/src/Illuminate/Routing/ImplicitRouteBinding.php",
                "line": 38
            }
        }
    }
    

    Expected behavior Is this correct behavior ? I thought it would handle basic framework exceptions and return appropriate HTTP codes out of the box.

    To reproduce In app/Exceptions/Handler.php

        public function render($request, Exception $exception)
        {
            return ExceptionHandlerHelper::render($request, $exception);
        }
    

    Environemnt:

    • PHP version 7.3
    • Laravel version 6.6.0
    • Laravel Response Builder 7.0.1
    Reviewed by nonovd at 2019-11-26 17:00
  • 4. [WIP] Made localization optional

    This is a wonderful package, but sometimes we don't want localization. If, for instance, localization is managed differently on some front-end, then we may not want to received a localized string when consuming an API.

    With those changes, I propose to add an use_localization option in the configuration, which would simply make the response builder not translate the localization.

    I did not add test coverage since the localization is too deeply implemented in the package. I think this feature would require more changes than what I made.

    What do you think?

    Reviewed by innocenzi at 2019-10-31 14:26
  • 5. Setting status code for the response.

    I've been using the package for 3 months now and i noticed that if the request is returning any status -except- 200 it fails to set the response status with the returning status, let's say if we're returning 404 the response builder will format the response json with code, etc ... but the response status it self is not as the returning code, it gives 200, so if this a misunderstanding from me of is this feature not supported?

    Reviewed by magdi14 at 2021-06-17 11:27
  • 6. Response builder is not working with Laravel resource and resource collection

    What's wrong? Resource Builder is not working with the resource collection objects. In my case, it is Resources\UserCollection Object

    Steps to reproduce the behavior:

    1. Create resource and resource collection
    2. use the Resource Builder and resource collection in the controller.
    use App\Http\Resources\User as UserResource;
    use App\Http\Resources\UserCollection;
    use MarcinOrlowski\ResponseBuilder\ResponseBuilder;
    
    class UserController extends Controller
    {
        /**
         * Display a listing of the resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function index(Request $request)
        {
        	$users = User::all();
            $collection = new UserCollection($users);
            return ResponseBuilder::success($collection);
        }
    }
    
    1. Another version by using the collection method.
    use App\Http\Resources\User as UserResource;
    use App\Http\Resources\UserCollection;
    use MarcinOrlowski\ResponseBuilder\ResponseBuilder;
    
    class UserController extends Controller
    {
        /**
         * Display a listing of the resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function index(Request $request)
        {
        	$users = User::all();
            $collection = NcfResource::collection($users);
            return ResponseBuilder::success($collection);
        }
    }
    

    You will get this error when you run the step 2 code:- Too few arguments to function App\Http\Resources\UserCollection::toArray(), 0 passed in vendor\marcin-orlowski\laravel-api-response-builder\src\Converters\ToArrayConverter.php on line 39 and exactly 1 expected

    You will get this error when you run the step 3 code:- Too few arguments to function Illuminate\Http\Resources\Json\ResourceCollection::toArray(), 0 passed in vendor\marcin-orlowski\laravel-api-response-builder\src\Converters\ToArrayConverter.php on line 39 and exactly 1 expected

    Expected behavior It should be working with the resource collection and Json\ResourceCollection.

    Runtime environment

    • Name and version of OS: Windows 10
    • PHP version: PHP 7.3.7
    • Laravel version: 7.30.4
    • ResponseBuilder version used: 9.2

    Notes Any additional information that may be helpful in diagnosing the problem.

    Reviewed by sachinkumar121 at 2021-03-03 12:15
  • 7. Unable to translate validation exception

    Describe the bug When Laravel validation fails and HTTP code 422 is returned, I'm getting something like this:

        "success": false,
        "code": 115,
        "locale": "fa",
        "message": "The given data was invalid.",
        "data": ...
    

    Expected behavior How can I translate the The given data was invalid.? I'm using v6.3.1 of this package

    Environemnt:

    • Name and version of OS: Windows 10
    • PHP version 7.3
    • Laravel version 6.5.0
    Reviewed by FaridAghili at 2019-11-06 14:45
  • 8. Release v9.3.0

    • Added data_always_object config option that, when enabled enforces response data node to always be JSON object (for NULL it will return empty object {}).
    • Improved code quality (fully pass on PHPStan's strict mode)
    • Fixed floats being rejected as direct primitive payload.
    • Fixed Converter unit tests for primitives-as-payload.
    • Fixed ResponseBuilderProvider throwing incorrect Exception in case of invalid config file.
    • Added Validator::assertIsObjectOrExistingClass() method.
    • Validator::assertIsInt() throws now NotIntegerException as expected.
    • Corrected Validator class tests to check agains specific exceptions thrown, not base class.
    • Improved error handling in JsonSerializableConverter
    • Switched Composer's autoload to follow psr-4 instead of plain classmap (thanks to Viktor Szépe).
    • Added TestingHelpers::getResponseContent(), TestingHelpers::langGet() to satisfy static analyzers.
    • Updated and corrected PHPDocs (incl. some type hints).
    • Added missing type hint to success().
    • Added strict type header to classes.
    • Updated documentation.
    Reviewed by MarcinOrlowski at 2021-06-18 13:58
  • 9. Add optional wrapper key condition for object responses

    Hey @MarcinOrlowski ! This is regarding the Laravel pagination response related to #127 and this comment

    I'm on Laravel 8

    'converter'         => [
       'classes' => [
           ...
    
           \Illuminate\Http\Resources\Json\ResourceCollection::class => [
              'handler' => App\Http\Converters\CustomJsonResourceCollectionConverter::class,
              'key' => null,  // <---- setting an empty key
              'pri' => 10,
           ],
       ],
    ]
    

    The output as mentioned in the issue comment will be,

    {
        "success": true,
        "code": 0,
        "locale": "en",
        "message": "OK",
        "data": {
            "items": [
                {
                    "id": 137,
                    "uuid": "b2f94a2f-42a8-4b9b-8e56-ea3ef54987f2",
                }
            ],
            "links": {
                "first": "https://example.com/api/public/v1/specs?page%5Bnumber%5D=1",
                "last": "https://example.com/api/public/v1/specs?page%5Bnumber%5D=11",
                "prev": null,
                "next": "https://example.com/api/public/v1/specs?page%5Bnumber%5D=2"
            },
            "meta": {
                "current_page": 1,
                "from": 1,
                "last_page": 11,
                "path": "https://example.com/api/public/v1/specs",
                "per_page": 30,
                "to": 30,
                "total": 316
            }
        }
    }
    
    Reviewed by iamroi at 2020-10-24 02:07
  • 10. Handle Forbidden StatusCode in ExceptionHandlerHelper

    Describe the bug A clear and concise description of what the bug is.

    To Reproduce Steps to reproduce the behavior:

    1. Add abort(403) in some API route
    2. Make request to that route.

    Expected behavior I expect to work like abort(401).

    {
        "success": false,
        "code": 114,
        "locale": "en",
        "message": "Forbidden",
        "data": null
    }
    

    **Environemnt:Desktop (please complete the following information):

    • Name and version of OS MacOS Catalina
    • PHP version 7.3
    • Laravel version 6.4.0

    Additional context Now in this case it returns:

    {
        "success": false,
        "code": 112,
        "locale": "en",
        "message": "HTTP exception Symfony\\Component\\HttpKernel\\Exception\\HttpException",
        "data": null
    }
    
    Reviewed by emog at 2019-11-03 22:01
  • 11. Laravel 5.7 support?

    Hey there,

    I am looking to use a legacy version along with Laravel 5.7, however, the link from the home page to legacy has a dead link

    https://github.com/MarcinOrlowski/laravel-api-response-builder/blob/master/docs/docs/legacy.md
    

    Does a Laravel 5.7 version exist, or am I SOL?

    Reviewed by mikeerickson at 2020-10-22 18:52
  • 12. errors key for validation

    I'm trying to create a validation error with this package. can you generate a new key for the error? I'm not comfortable entering validation error data into the key data.

    {
        "success": false,
        "code": 422,
        "locale": "en",
        "message": "validation error, please check the input form",
        "data" : null,
        "errors": {
            "email": [
                "The email field is required."
            ],
            "password": [
                "The password field is required."
            ]
        }
    }
    
    LoginRequest.php
        protected function failedValidation(Validator $validator)
        {
            $response = RB::asError($apiCode)->withError($validator->errors()->toArray())->withMessage($msg)->build();
            throw new HttpResponseException($response);
        }
    
    or more simply by adding a key parameter to replace the key data.
    withData($errors, "errors")->build();
    
    Reviewed by farahis92 at 2022-05-08 08:32
  • 13. "Undefined array key" for ex handler config lacking i.e. api_code entry.

    I have checked this

    /** @var \Symfony\Component\HttpKernel\Exception\HttpException $ex */
    $http_code = $ex->getStatusCode();
    

    And $ex->getStatusCode() indeed returns 404, but at the same time, the final output has 500 status code. Here, I just opened a non-existent route: image

    I tried to implement your solution:

      \Symfony\Component\HttpKernel\Exception\HttpException::class => [
          'handler' => \MarcinOrlowski\ResponseBuilder\ExceptionHandlers\HttpExceptionHandler::class,
          'pri' => -100,
          'config' => [
              Symfony\Component\HttpFoundation\Response::HTTP_NOT_FOUND => [
                  'http_code' => Symfony\Component\HttpFoundation\Response::HTTP_NOT_FOUND,
              ],
    

    And after that, I receive this error whenever I try to access a wrong route:

    {"success":false,"code":113,"locale":"en","message":"Undefined array key \u0022api_code\u0022","data":null,"debug":{"trace":{"class":"ErrorException","file":"\/var\/www\/api\/vendor\/marcin-orlowski\/laravel-api-response-builder\/src\/ExceptionHandlerHelper.php","line":104}}}
    

    Originally posted by @beeyev in https://github.com/MarcinOrlowski/laravel-api-response-builder/discussions/225#discussioncomment-2238369

    Reviewed by MarcinOrlowski at 2022-02-23 18:40
  • 14. Cannot configure a converter key as NULL

    What's wrong? MarcinOrlowski\ResponseBuilder\Exceptions\IncompatibleTypeException Incompatible types. Cannot merge NULL into string (key 'key'). marcin-orlowski\laravel-api-response-builder\src\Util.php:46

    Steps to reproduce the behavior:

    1. Install new Laravel with "composer create-project laravel/laravel example-app"
    2. Install this package with "composer require marcin-orlowski/laravel-api-response-builder"
    3. Publish a configuration with "php artisan vendor:publish"
    4. Edit a "collection converter" to use "key" as NULL
    5. Create any sample API to return a convert with method "RB::success($items)"

    Expected behavior Return a successful response without problem and without key

    Runtime environment

    • Name and version of OS: Windows 10
    • PHP version: 7.4
    • Laravel version: 8
    • ResponseBuilder version used: 9.2.3

    Notes The problem lines in MarcinOrlowski\ResponseBuilder\Util::mergeConfig(). The original configuration has a string type, where the actual environment wants NULL type. That is whey it will conflicts, the NULL for "key" configuration should be possible according to the document. I'm not personally sure how this should be handle but I am current do a quick work around by override a class myself without checking the type when merging.

    Reviewed by sitawit at 2021-06-17 09:18
A Laravel Wrapper for the CoinDCX API. Now easily connect and consume the CoinDCX Public API in your Laravel apps without any hassle.
A Laravel Wrapper for the CoinDCX API. Now easily connect and consume the CoinDCX Public API in your Laravel apps without any hassle.

This package provides a Laravel Wrapper for the CoinDCX API and allows you to easily communicate with it. Important Note This package is in early deve

Feb 16, 2022
Laravel Ajax Datatable is a nice laravel admin panel which includes authentication, CRUD and Ajax datatable.

Laravel Ajax Datatable is a nice laravel admin panel which includes authentication, CRUD and Ajax datatable. the datatable is created with laravel & ajax so No need to install another package, yout can do search, sort, paginate and show records per page fastly.

Jun 15, 2022
Prerender Laravel pages using Clusteer and this nice package.
Prerender Laravel pages using Clusteer and this nice package.

Laravel Clusteer Prerender Prerender Laravel pages using Clusteer and this nice package. ?? Supporting If you are using one or more Renoki Co. open-so

Jan 6, 2022
A nice GUI for Laravel Artisan, ready out of the box, configurable and handy for non-CLI experienced developers.

Artisan UI A nice GUI for Laravel Artisan, ready out of the box, configurable and handy for non-CLI experienced developers. Supported commands must be

Dec 3, 2021
Laravel Responder - a package for building API responses, integrating Fractal into Laravel and Lumen
Laravel Responder - a package for building API responses, integrating Fractal into Laravel and Lumen

A Laravel Fractal package for building API responses, giving you the power of Fractal with Laravel's elegancy.

Aug 1, 2022
Backend application using Laravel 9.x REST APIs for games topup from digiflazz.com and payment gateway using xendit.co

TOPUP - Laravel 9.x REST API Documentation is still on progress. For now, you can fork this postman collection Installation Clone this project git clo

Jul 31, 2022
Execute Laravel Artisan commands via REST APIs and HTTP requests safely.

Artisan Api There might be some times you wanted to execute an Artisan command, but you did not have access to shell or SSH. Here we brought REST API

Aug 4, 2022
A simple package allowing for consistent API responses throughout your Laravel application
A simple package allowing for consistent API responses throughout your Laravel application

Laravel API Response Helpers A simple package allowing for consistent API responses throughout your Laravel application. Requirements PHP ^7.4 | ^8.0

Aug 15, 2022
Laravel Jsonable - Well-Formated Responses & Exceptions.
Laravel Jsonable - Well-Formated Responses & Exceptions.

Laravel Jsonable Well-Formated Responses & Exceptions. Documentation You can find the detailed documentation here in Laravel Jsonable Documentation. C

Mar 12, 2022
This package aims to help you standardize all your API responses in a simple and structured way.

Laravel API Response This package aims to help you standardize all your API responses in a simple and structured way. By default, the stucture of the

Jul 24, 2022
Caches responses as static files on disk for lightning fast page loads.

Laravel Page Cache This package allows you to easily cache responses as static files on disk for lightning fast page loads. Introduction Installation

Aug 4, 2022
A lightweight package for handling API error responses.

Laravel API Errors This package provides an easy way to manage and handle error response for JSON API's. Installation You can install the package via

Feb 9, 2022
The fastest way to make a powerful JSON:API compatible Rest API with Laravel.
The fastest way to make a powerful JSON:API compatible Rest API with Laravel.

The first fully customizable Laravel JSON:API builder. "CRUD" and protect your resources with 0 (zero) extra line of code. Installation You can instal

Aug 8, 2022
Pronto Fuel is a heavilly opnionated starter kit for Laravel and Inertia.js powered by Vite

Pronto Fuel Pronto Fuel is a heavilly opnionated starter kit for Laravel and Inertia.js powered by Vite. It ships with autoimporting features and leve

Aug 7, 2022
⛽ Set of utilities to test Laravel applications powered by Octane.

⛽ Octane Testbench Set of utilities to test Laravel applications powered by Octane. Install Via Composer: composer require --dev cerbero/octane-testbe

Aug 2, 2022
It's like React for PHP. Powered by Laravel, Livewire, Tailwind, & Alpine.

Tailwire It's like React for PHP. Powered by Laravel, Livewire, Tailwind, & Alpine. Features: Use a custom view component class namespace Declare rout

Dec 12, 2021
🧱 A Roblox clone written in PHP powered by the Laravel framework.

Laravel Roblox Clone Originally written in June-July 2021 to get better with Laravel and to have something fun to work on. If you need any help, feel

Jul 21, 2022
Durable workflow engine that allows users to write long running persistent distributed workflows in PHP powered by Laravel queues

Durable workflow engine that allows users to write long running persistent distributed workflows (orchestrations) in PHP powered by Laravel queues. Inspired by Temporal and Azure Durable Functions.

Mar 23, 2022
Ani Cast - Anime List & Trending App. (Powered by Jikan API)

(Under Development) Ani Cast - Anime Shows App.

Jun 15, 2022