PHPackages                             donhatptit/laravel-responder - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. donhatptit/laravel-responder

ActiveLibrary[API Development](/categories/api)

donhatptit/laravel-responder
============================

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

v3.1.1(6y ago)032MITPHPPHP ^7.0

Since Jun 25Pushed 5y agoCompare

[ Source](https://github.com/donhatptit/laravel-responder)[ Packagist](https://packagist.org/packages/donhatptit/laravel-responder)[ Docs](https://github.com/flugger/laravel-responder)[ RSS](/packages/donhatptit-laravel-responder/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (9)Versions (117)Used By (0)

[![](https://camo.githubusercontent.com/b10b3306be29c1605304a9ee0ce8d98930550186c7ef599aa2b65376706fae69/687474703a2f2f64657369676e6961636b2e6e6f2f7061636b6167652d6c6f676f2e706e67)](https://camo.githubusercontent.com/b10b3306be29c1605304a9ee0ce8d98930550186c7ef599aa2b65376706fae69/687474703a2f2f64657369676e6961636b2e6e6f2f7061636b6167652d6c6f676f2e706e67)

 [![Latest Stable Version](https://camo.githubusercontent.com/63b579c17084d0100d40912b0307547fd6eee3a7421738dc0c8866c185e689cc/68747470733a2f2f706f7365722e707567782e6f72672f666c75676765722f6c61726176656c2d726573706f6e6465722f762f737461626c653f666f726d61743d666c61742d737175617265)](https://github.com/flugger/laravel-responder) [![Packagist Downloads](https://camo.githubusercontent.com/6f23f93ab79bfc653a1a263be32b341775a3f24c880ac160bf968bc773a16d16/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f666c75676765722f6c61726176656c2d726573706f6e6465722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/flugger/laravel-responder) [![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE.md) [![Build Status](https://camo.githubusercontent.com/6fe8ade686c25f07b4b0601fb6f917a6e7569460ef3a265c7fe40725285ce4d4/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f666c75676765722f6c61726176656c2d726573706f6e6465722f6d61737465722e7376673f7374796c653d666c61742d737175617265)](https://travis-ci.org/flugger/laravel-responder) [![Code Quality](https://camo.githubusercontent.com/8b5b0bdeb238e03f0e5308618dcd4d3dddf01e8a88b10ba17b7faffd4ea826a6/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f666c75676765722f6c61726176656c2d726573706f6e6465722e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/flugger/laravel-responder/?branch=master) [![Test Coverage](https://camo.githubusercontent.com/c781a40ada3190ac1d09427335c255a69c4086b2d72dedf4ffde50bab81025f6/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f636f7665726167652f672f666c75676765722f6c61726176656c2d726573706f6e6465722e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/flugger/laravel-responder/code-structure/master) [![Donate](https://camo.githubusercontent.com/d02714bfc4c3e6840248e6c7558df4d5ab66dc04a522cd3d5df29fb495a54aa7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f6e6174652d50617950616c2d79656c6c6f772e7376673f7374796c653d666c61742d737175617265)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=PRMC9WLJY8E46&lc=NO&item_name=Laravel%20Responder&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted)

Laravel Responder is a package for building API responses, integrating [Fractal](https://github.com/thephpleague/fractal) into Laravel and Lumen. It can transform your data using transformers, create and serialize success- and error responses, handle exceptions and assist you with testing your responses.

Table of Contents
=================

[](#table-of-contents)

- [Introduction](#introduction)
- [Requirements](#requirements)
- [Installation](#installation)
- [Usage](#usage)
    - [Creating Responses](#creating-responses)
    - [Creating Success Responses](#creating-success-responses)
    - [Creating Transformers](#creating-transformers)
    - [Transforming Data](#transforming-data)
    - [Creating Error Responses](#creating-error-responses)
    - [Handling Exceptions](#handling-exceptions)
- [Contributing](#contributing)
- [Donating](#contributing)
- [License](#license)

Introduction
============

[](#introduction)

Laravel lets you return models directly from a controller method to convert it to JSON. This is a quick way to build APIs but leaves your database columns exposed. [Fractal](https://fractal.thephpleague.com), a popular PHP package from [The PHP League](https://thephpleague.com/), solves this by introducing transformers. However, it can be a bit cumbersome to integrate into the framework as seen below:

```
 public function index()
 {
    $resource = new Collection(User::all(), new UserTransformer());

    return response()->json((new Manager)->createData($resource)->toArray());
 }
```

Not *that* bad, but we all get a little spoiled by Laravel's magic. Wouldn't it be better if we could refactor it to:

```
public function index()
{
    return responder()->success(User::all())->respond();
}
```

The package will allow you to do this and much more. The goal has been to create a high-quality package that feels like native Laravel. A package that lets you embrace the power of Fractal, while hiding it behind beautiful abstractions. There has also been put a lot of focus and thought to the documentation. Happy exploration!

Requirements
============

[](#requirements)

This package requires:

- PHP **7.0**+
- Laravel **5.1**+ or Lumen **5.1**+

Installation
============

[](#installation)

To get started, install the package through Composer:

```
composer require donhatptit/laravel-responder
```

Laravel
-------

[](#laravel)

#### Register Service Provider

[](#register-service-provider)

Append the following line to the `providers` key in `config/app.php` to register the package:

```
Flugg\Responder\ResponderServiceProvider::class,
```

---

*The package supports auto-discovery, so if you use Laravel 5.5 or later you may skip registering the service provider and facades as they will be registered automatically.*

---

#### Register Facades *(optional)*

[](#register-facades-optional)

If you like facades, you may also append the `Responder` and `Transformation` facades to the `aliases` key:

```
'Responder' => Flugg\Responder\Facades\Responder::class,
'Transformation' => Flugg\Responder\Facades\Transformation::class,
```

#### Publish Package Assets *(optional)*

[](#publish-package-assets-optional)

You may additionally publish the package configuration and language file using the `vendor:publish` Artisan command:

```
php artisan vendor:publish --provider="Flugg\Responder\ResponderServiceProvider"
```

This will publish a `responder.php` configuration file in your `config` folder. It will also publish an `errors.php` file inside your `lang/en` folder which can be used for storing error messages.

Lumen
-----

[](#lumen)

#### Register Service Provider

[](#register-service-provider-1)

Add the following line to `app/bootstrap.php` to register the package:

```
$app->register(Flugg\Responder\ResponderServiceProvider::class);
```

#### Register Facades *(optional)*

[](#register-facades-optional-1)

You may also add the following lines to `app/bootstrap.php` to register the facades:

```
class_alias(Flugg\Responder\Facades\Responder::class, 'Responder');
class_alias(Flugg\Responder\Facades\Transformation::class, 'Transformation');
```

#### Publish Package Assets *(optional)*

[](#publish-package-assets-optional-1)

Seeing there is no `vendor:publish` command in Lumen, you will have to create your own `config/responder.php` file if you want to configure the package.

Usage
=====

[](#usage)

This documentation assumes some knowledge of how [Fractal](https://github.com/thephpleague/fractal) works.

Creating Responses
------------------

[](#creating-responses)

The package has a `Responder` service class, which has a `success` and `error` method to build success- and error responses respectively. To use the service and begin creating responses, pick one of the options below:

#### Option 1: Inject `Responder` Service

[](#option-1-inject-responder-service)

You may inject the `Flugg\Responder\Responder` service class directly into your controller methods:

```
public function index(Responder $responder)
{
    return $responder->success();
}
```

You can also use the `error` method to create error responses:

```
return $responder->error();
```

#### Option 2: Use `responder` Helper

[](#option-2-use-responder-helper)

If you're a fan of Laravel's `response` helper function, you may like the `responder` helper function:

```
return responder()->success();
```

```
return responder()->error();
```

#### Option 3: Use `Responder` Facade

[](#option-3-use-responder-facade)

Optionally, you may use the `Responder` facade to create responses:

```
return Responder::success();
```

```
return Responder::error();
```

#### Option 4: Use `MakesResponses` Trait

[](#option-4-use-makesresponses-trait)

Lastly, the package provides a `Flugg\Responder\Http\MakesResponses` trait you can use in your controllers:

```
return $this->success();
```

```
return $this->error();
```

---

*Which option you pick is up to you, they are all equivalent, the important thing is to stay consistent. The helper function (option 2) will be used for the remaining of the documentation.*

---

### Building Responses

[](#building-responses)

The `success` and `error` methods return a `SuccessResponseBuilder` and `ErrorResponseBuilder` respectively, which both extend an abstract `ResponseBuilder`, giving them common behaviors. They will be converted to JSON when returned from a controller, but you can explicitly create an instance of `Illuminate\Http\JsonResponse` with the `respond` method:

```
return responder()->success()->respond();
```

```
return responder()->error()->respond();
```

The status code is set to `200` by default, but can be changed by setting the first parameter. You can also pass a list of headers as the second argument:

```
return responder()->success()->respond(201, ['x-foo' => true]);
```

```
return responder()->error()->respond(404, ['x-foo' => false]);
```

---

*Consider always using the `respond` method for consistency's sake.*

---

### Casting Response Data

[](#casting-response-data)

Instead of converting the response to a `JsonResponse` using the `respond` method, you can cast the response data to a few other types, like an array:

```
return responder()->success()->toArray();
```

```
return responder()->error()->toArray();
```

You also have a `toCollection` and `toJson` method at your disposal.

### Decorating Response

[](#decorating-response)

A response decorator allows for last minute changes to the response before it's returned. The package comes with two response decorators out of the box adding a `status` and `success` field to the response output. The `decorators` key in the configuration file defines a list of all enabled response decorators:

```
'decorators' => [
    \Flugg\Responder\Http\Responses\Decorators\StatusCodeDecorator::class,
    \Flugg\Responder\Http\Responses\Decorators\SuccessFlagDecorator::class,
],
```

You may disable a decorator by removing it from the list, or add your own decorator extending the abstract class `Flugg\Responder\Http\Responses\Decorators\ResponseDecorator`. You can also add additional decorators per response:

```
return responder()->success()->decorator(ExampleDecorator::class)->respond();
```

```
return responder()->error()->decorator(ExampleDecorator::class)->respond();
```

---

The package also ships with some situational decorators disabled by default, but which can be added to the decorator list:

- `PrettyPrintDecorator` decorator will beautify the JSON output;

```
\Flugg\Responder\Http\Responses\Decorators\PrettyPrintDecorator::class,
```

- `EscapeHtmlDecorator` decorator, based on the "sanitize input, escape output" concept, will escape HTML entities in all strings returned by your API. You can securely store input data "as is" (even malicious HTML tags) being sure that it will be outputted as un-harmful strings. Note that, using this decorator, printing data as text will result in the wrong representation and you must print it as HTML to retrieve the original value.

```
\Flugg\Responder\Http\Responses\Decorators\EscapeHtmlDecorator::class,
```

---

Creating Success Responses
--------------------------

[](#creating-success-responses)

As briefly demonstrated above, success responses are created using the `success` method:

```
return responder()->success()->respond();
```

Assuming no changes have been made to the configuration, the above code would output the following JSON:

```
{
    "status": 200,
    "success": true,
    "data": null
}
```

### Setting Response Data

[](#setting-response-data)

The `success` method takes the response data as the first argument:

```
return responder()->success(Product::all())->respond();
```

It accepts the same data types as you would normally return from your controllers, however, it also supports query builder and relationship instances:

```
return responder()->success(Product::where('id', 1))->respond();
```

```
return responder()->success(Product::first()->shipments())->respond();
```

---

*The package will run the queries and convert them to collections behind the scenes.*

---

### Transforming Response Data

[](#transforming-response-data)

The response data will be transformed with Fractal if you've attached a transformer to the response. There are two ways to attach a transformer; either *explicitly* by setting it on the response, or *implicitly* by binding it to a model. Let's look at both ways in greater detail.

#### Setting Transformer On Response

[](#setting-transformer-on-response)

You can attach a transformer to the response by sending a second argument to the `success` method. For instance, below we're attaching a simple closure transformer, transforming a list of products to only output their names:

```
return responder()->success(Product::all(), function ($product) {
    return ['name' => $product->name];
})->respond();
```

You may also transform using a dedicated transformer class:

```
return responder()->success(Product::all(), ProductTransformer::class)->respond();
```

```
return responder()->success(Product::all(), new ProductTransformer)->respond();
```

---

*You can read more about creating dedicated transformer classes in the [Creating Transformers](#creating-transformers) chapter.*

---

#### Binding Transformer To Model

[](#binding-transformer-to-model)

If no transformer is set, the package will search the response data for an element implementing the `Flugg\Responder\Contracts\Transformable` interface to resolve a transformer from. You can take use of this by implementing the `Transformable` interface in your models:

```
class Product extends Model implements Transformable {}
```

You can satisfy the contract by adding a `transformer` method that returns the corresponding transformer:

```
/**
 * Get a transformer for the class.
 *
 * @return \Flugg\Responder\Transformers\Transformer|string|callable
 */
public function transformer()
{
    return ProductTransformer::class;
}
```

---

*You're not limited to returning a class name string, you can return a transformer instance or closure transformer, just like the second parameter of the `success` method.*

---

Instead of implementing the `Transformable` contract for all models, an alternative approach is to bind the transformers using the `bind` method on the `TransformerResolver` class. You can place the code below within `AppServiceProvider` or an entirely new `TransformerServiceProvider`:

```
use Flugg\Responder\Contracts\Transformers\TransformerResolver;

public function boot()
{
    $this->app->make(TransformerResolver::class)->bind([
        \App\Product::class => \App\Transformers\ProductTransformer::class,
        \App\Shipment::class => \App\Transformers\ShipmentTransformer::class,
    ]);
}
```

After you've bound a transformer to a model you can skip the second parameter and still transform the data:

```
return responder()->success(Product::all())->respond();
```

---

*As you might have noticed, unlike Fractal, you don't need to worry about creating resource objects like `Item` and `Collection`. The package will make one for you based on the data type, however, you may wrap your data in a resource object to override this.*

---

### Setting Resource Key

[](#setting-resource-key)

If the data you send into the response is a model or contains a list of models, a resource key will implicitly be resolved from the model's table name. You can overwrite this by adding a `getResourceKey` method to your model:

```
public function getResourceKey(): string {
    return 'products';
}
```

You can also explicitly set a resource key on a response by sending a third argument to the ´success` method:

```
return responder()->success(Product::all(), ProductTransformer::class, 'products')->respond();
```

### Paginating Response Data

[](#paginating-response-data)

Sending a paginator to the `success` method will set pagination meta data and transform the data automatically, as well as append any query string parameters to the paginator links.

```
return responder()->success(Product::paginate())->respond();
```

Assuming there are no products and the default configuration is used, the JSON output would look like:

```
{
    "success": true,
    "status": 200,
    "data": [],
    "pagination": {
        "total": 0,
        "count": 0,
        "perPage": 15,
        "currentPage": 1,
        "totalPages": 1,
        "links": []
    }
}
```

#### Setting Paginator On Response

[](#setting-paginator-on-response)

Instead of sending a paginator as data, you may set the data and paginator seperately, like you traditionally would with Fractal. You can manually set a paginator using the `paginator` method, which expects an instance of `League\Fractal\Pagination\IlluminatePaginatorAdapter`:

```
$paginator = Product::paginate();
$adapter = new IlluminatePaginatorAdapter($paginator);

return responder()->success($paginator->getCollection())->paginator($adapter)->respond();
```

#### Setting Cursor On Response

[](#setting-cursor-on-response)

You can also set cursors using the `cursor` method, expecting an instance of `League\Fractal\Pagination\Cursor`:

```
if ($request->has('cursor')) {
    $products = Product::where('id', '>', request()->cursor)->take(request()->limit)->get();
} else {
    $products = Product::take(request()->limit)->get();
}

$cursor = new Cursor(request()->cursor, request()->previous, $products->last()->id ?? null, Product::count());

return responder()->success($products)->cursor($cursor)->respond();
```

### Including Relationships

[](#including-relationships)

If a transformer class is attached to the response, you can include relationships using the `with` method:

```
return responder()->success(Product::all())->with('shipments')->respond();
```

You can send multiple arguments and specify nested relations using dot notation:

```
return responder()->success(Product::all())->with('shipments', 'orders.customer')->respond();
```

All relationships will be automatically eager loaded, and just like you would when using `with` or `load` to eager load with Eloquent, you may use a callback to specify additional query constraints. Like in the example below, where we're only including related shipments that hasn't yet been shipped:

```
return responder()->success(Product::all())->with(['shipments' => function ($query) {
    $query->whereNull('shipped_at');
}])->respond();
```

#### Including From Query String

[](#including-from-query-string)

Relationships are loaded from a query string parameter if the `load_relations_parameter` configuration key is set to a string. By default, it's set to `with`, allowing you to automatically include relations from the query string:

```
GET /products?with=shipments,orders.customer

```

#### Excluding Default Relations

[](#excluding-default-relations)

In your transformer classes, you may specify relations to automatically load. You may disable any of these relations using the `without` method:

```
return responder()->success(Product::all())->without('comments')->respond();
```

### Filtering Transformed Data

[](#filtering-transformed-data)

The technique of filtering the transformed data to only return what we need is called sparse fieldsets and can be specified using the `only` method:

```
return responder()->success(Product::all())->only('id', 'name')->respond();
```

When including relationships, you may also want to filter fields on related resources as well. This can be done by instead specifying an array where each key represents the resource keys for the resources being filtered

```
return responder()->success(Product::all())->with('shipments')->only([
    'products' => ['id', 'name'],
    'shipments' => ['id']
])->respond();
```

#### Filtering From Query String

[](#filtering-from-query-string)

Fields will automatically be filtered if the `filter_fields_parameter` configuration key is set to a string. It defaults to `only`, allowing you to filter fields from the query string:

```
GET /products?only=id,name

```

You may automatically filter related resources by setting the parameter to a key-based array:

```
GET /products?with=shipments&only[products]=id,name&only[shipments]=id

```

### Adding Meta Data

[](#adding-meta-data)

You may want to attach additional meta data to your response. You can do this using the `meta` method:

```
return responder()->success(Product::all())->meta(['count' => Product::count()])->respond();
```

When using the default serializer, the meta data will simply be appended to the response array:

```
{
    "success": true,
    "status": 200,
    "data": [],
    "count": 0
}
```

### Serializing Response Data

[](#serializing-response-data)

After the data has been transformed, it will be serialized using the specified success serializer in the configuration file, which defaults to the package's own `Flugg\Responder\Serializers\SuccessSerializer`. You can overwrite this on your responses using the `serializer` method:

```
return responder()->success()->serializer(JsonApiSerializer::class)->respond();
```

```
return responder()->success()->serializer(new JsonApiSerializer())->respond();
```

Above we're using Fractal's `JsonApiSerializer` class. Fractal also ships with an `ArraySerializer` and `DataArraySerializer` class. If none of these suit your taste, feel free to create your own serializer by extending `League\Fractal\Serializer\SerializerAbstract`. You can read more about it in [Fractal's documentation](http://fractal.thephpleague.com/serializers/).

Creating Transformers
---------------------

[](#creating-transformers)

A dedicated transformer class gives you a convenient location to transform data and allows you to reuse the transformer at multiple places. It also allows you to include and transform relationships. You can create a transformer using the `make:transformer` Artisan command:

```
php artisan make:transformer ProductTransformer
```

The command will generate a new `ProductTransformer.php` file in the `app/Transformers` folder:

```
