├── .gitattributes ├── .github └── workflows │ └── run-tests.yml ├── .gitignore ├── LICENSE.md ├── README.md ├── _config.yml ├── composer.json └── src ├── JsendExceptionFormatter.php └── helpers.php /.gitattributes: -------------------------------------------------------------------------------- 1 | /tests export-ignore 2 | -------------------------------------------------------------------------------- /.github/workflows/run-tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | 8 | jobs: 9 | test: 10 | runs-on: ubuntu-latest 11 | strategy: 12 | matrix: 13 | php: 14 | - '8.2' 15 | - '8.1' 16 | - '8.0' 17 | - '7.4' 18 | - '7.3' 19 | - '7.2' 20 | 21 | name: Tests (PHP ${{ matrix.php }} 22 | 23 | steps: 24 | - uses: actions/checkout@v2 25 | - name: Setup PHP ${{ matrix.php }} 26 | uses: shivammathur/setup-php@v2 27 | with: 28 | php-version: ${{ matrix.php }} 29 | extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath 30 | coverage: none 31 | - run: composer install 32 | - run: composer test 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | composer.lock 3 | .idea/ -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Shalvah Adebayo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # laravel-jsend 2 | 3 | [![Latest Stable Version](https://poser.pugx.org/shalvah/laravel-jsend/v/stable)](https://packagist.org/packages/shalvah/laravel-jsend) 4 | [![Total Downloads](https://poser.pugx.org/shalvah/laravel-jsend/downloads)](https://packagist.org/packages/shalvah/laravel-jsend) 5 | 6 | Simple helpers to generate [JSend-compliant](https://labs.omniti.com/labs/jsend) responses for your Laravel app 7 | 8 | The [JSend specification](https://labs.omniti.com/labs/jsend) lays down some rules for how JSON responses from web servers should be formatted. JSend is especially suited for REST-style applications and APIs. 9 | 10 | ## Installation 11 | Laravel 7 and above: 12 | ```bash 13 | composer require shalvah/laravel-jsend 14 | ``` 15 | 16 | Laravel 5.1 - 6.*: 17 | ```bash 18 | composer require shalvah/laravel-jsend:^1.0 19 | ``` 20 | 21 | ## Usage 22 | In your controller: 23 | 24 | ```php 25 | public function create(Request $request) 26 | { 27 | $userData = $request->input('data'); 28 | if (empty($userData['email'])) 29 | return jsend_fail(['email' => 'Email is required']); 30 | 31 | try { 32 | $user = User::create($userData): 33 | return jsend_success($user); 34 | } catch (Exception $e) { 35 | return jsend_error('Unable to create user: '.$e->getMessage()); 36 | } 37 | } 38 | ``` 39 | 40 | You can also add the `JsendExceptionFormatter` trait in `App\Exceptions\Handler` to format JSON responses for unhandled exceptions and Laravel validation errors as JSend: 41 | ```php 42 | class Handler extends ExceptionHandler 43 | { 44 | use Shalvah\LaravelJsend\JsendExceptionFormatter; 45 | 46 | // ... 47 | } 48 | ``` 49 | 50 | ## Available helpers 51 | ### `jsend_success` 52 | The `jsend_success` function creates a JSend **success** response instance. 53 | ```php 54 | return jsend_success([ 55 | "id" => 2, 56 | "title" => "New life", 57 | "body" => "Trust me, this is great!" 58 | ]); 59 | ``` 60 | 61 | Generates a response: 62 | ```json 63 | { 64 | "status": "success", 65 | "data": { 66 | "id": 2, 67 | "title": "New life", 68 | "body": "Trust me, this is great!" 69 | } 70 | } 71 | ``` 72 | You may pass an Eloquent model instead of an array as the "data" object: 73 | 74 | ```php 75 | $post = Post::find($id); 76 | return jsend_success($post); 77 | ``` 78 | 79 | ### `jsend_fail` 80 | The `jsend_fail` function creates a JSend **fail** response instance. 81 | ```php 82 | return jsend_fail([ 83 | "title" => "title is required", 84 | "body" => "body must be 50 - 10000 words" 85 | ]); 86 | ``` 87 | 88 | Generates a response: 89 | ```json 90 | { 91 | "status": "fail", 92 | "data": { 93 | "title": "title is required", 94 | "body": "body must be 50 - 10000 words" 95 | } 96 | } 97 | ``` 98 | 99 | ### `jsend_error` 100 | The `jsend_error` function creates a JSend **error** response instance. 101 | ```php 102 | return jsend_error("Unable to connect to database"); 103 | ``` 104 | 105 | Generates a response: 106 | ```json 107 | { 108 | "status": "error", 109 | "message":"Unable to connect to database" 110 | } 111 | ``` 112 | You may also pass optional `code` and `data` objects. 113 | ```php 114 | return jsend_error("Unable to connect to database", 'E0001', ['type' => 'database error']); 115 | ``` 116 | 117 | Generates a response: 118 | ```json 119 | { 120 | "status": "error", 121 | "message":"Unable to connect to database", 122 | "code": "E001", 123 | "data": { 124 | "type": "database error" 125 | } 126 | } 127 | ``` 128 | 129 | > Note: for each helper, the HTTP status codes are set automatically (to 200, 400, and 500 for `success`, `fail`, and `error` respectively), and the header `Content-type: application/json` is set. If you wish, you may specify a HTTP status code and additional headers as the last two parameters. 130 | ```php 131 | return jsend_success($post, 201, ["X-My-Header" => "header value"]); 132 | return jsend_fail(["location_id" => "Location not found"], 404); 133 | return jsend_error("Unable to connect to database", 'E0001', [], 503, ["X-My-Header" => "header value"]); 134 | ``` 135 | 136 | ## License 137 | MIT 138 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-slate -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shalvah/laravel-jsend", 3 | "description": "Laravel helpers to easily send JSend-compliant responses", 4 | "keywords": ["jsend", "laravel", "json"], 5 | "license": "MIT", 6 | "homepage": "http://shalvah.me/laravel-jsend", 7 | "support": { 8 | "issues": "https://github.com/shalvah/laravel-jsend/issues", 9 | "source": "https://github.com/shalvah/laravel-jsend" 10 | }, 11 | "authors": [ 12 | { 13 | "name": "Shalvah Adebayo", 14 | "email": "shalvah.adebayo@gmail.com" 15 | } 16 | ], 17 | "require": { 18 | "php": ">=7.2.5", 19 | "laravel/framework": ">= 7.0" 20 | }, 21 | "require-dev": { 22 | "orchestra/testbench": "^5.0|^6.0|8.0", 23 | "phpunit/phpunit": "^8.0|^10.0", 24 | "ext-json": "*" 25 | }, 26 | "autoload": { 27 | "files": [ 28 | "src/helpers.php" 29 | ], 30 | "psr-4": { 31 | "Shalvah\\LaravelJsend\\": "src/" 32 | } 33 | }, 34 | "autoload-dev": { 35 | "psr-4": { 36 | "Shalvah\\LaravelJsend\\Tests\\": "tests/" 37 | } 38 | }, 39 | "scripts": { 40 | "test": "phpunit tests" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/JsendExceptionFormatter.php: -------------------------------------------------------------------------------- 1 | errors(), 25 | $exception->status 26 | ); 27 | } 28 | 29 | /** 30 | * Prepare a JSON response for the given exception. 31 | * 32 | * @param \Illuminate\Http\Request $request 33 | * @param \Exception $e 34 | * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response 35 | */ 36 | protected function prepareJsonResponse($request, Throwable $e) 37 | { 38 | $message = 'Server Error'; 39 | if (config('app.debug') || $this->isHttpException($e)) { 40 | $message = $e->getMessage(); 41 | } 42 | 43 | $data = config('app.debug') ? [ 44 | 'exception' => get_class($e), 45 | 'file' => $e->getFile(), 46 | 'line' => $e->getLine(), 47 | 'trace' => collect($e->getTrace())->map(function ($trace) { 48 | return Arr::except($trace, ['args']); 49 | })->all(), 50 | ] : null; 51 | 52 | return jsend_error( 53 | $message, 54 | $e->getCode(), 55 | $data, 56 | $this->isHttpException($e) ? $e->getStatusCode() : 500, 57 | $this->isHttpException($e) ? $e->getHeaders() : [] 58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/helpers.php: -------------------------------------------------------------------------------- 1 | "error", 16 | "message" => $message 17 | ]; 18 | !is_null($code) && $response['code'] = $code; 19 | !is_null($data) && $response['data'] = $data; 20 | 21 | return response()->json($response, $status, $extraHeaders); 22 | } 23 | } 24 | 25 | if (!function_exists("jsend_fail")) { 26 | /** 27 | * @param array $data 28 | * @param int $status HTTP status code 29 | * @param array $extraHeaders 30 | * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response 31 | */ 32 | function jsend_fail($data, $status = 400, $extraHeaders = []) 33 | { 34 | $response = [ 35 | "status" => "fail", 36 | "data" => $data 37 | ]; 38 | 39 | return response()->json($response, $status, $extraHeaders); 40 | } 41 | } 42 | 43 | if (!function_exists("jsend_success")) { 44 | /** 45 | * @param array | Illuminate\Database\Eloquent\Model $data 46 | * @param int $status HTTP status code 47 | * @param array $extraHeaders 48 | * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response 49 | */ 50 | function jsend_success($data = [], $status = 200, $extraHeaders = []) 51 | { 52 | $response = [ 53 | "status" => "success", 54 | "data" => $data 55 | ]; 56 | 57 | return response()->json($response, $status, $extraHeaders); 58 | } 59 | } 60 | --------------------------------------------------------------------------------