PHPackages                             azaan/laravel-scene - 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. azaan/laravel-scene

ActiveLibrary[API Development](/categories/api)

azaan/laravel-scene
===================

Laravel API Transformer

v2.0.1(4y ago)3018.8k↑93.3%3MITPHPPHP &gt;=5.5.9CI failing

Since Dec 5Pushed 4y ago1 watchersCompare

[ Source](https://github.com/aznn/laravel-scene)[ Packagist](https://packagist.org/packages/azaan/laravel-scene)[ RSS](/packages/azaan-laravel-scene/feed)WikiDiscussions master Synced today

READMEChangelog (10)Dependencies (3)Versions (20)Used By (0)

Laravel Scene
=============

[](#laravel-scene)

Laravel library to convert your models into API responses.

### Why a transformation library?

[](#why-a-transformation-library)

By default you can use the default implementation which converts your models to json based on `toArray()`. This approach starts to get messy once you start having different responses for your models for different endpoints (Eg: based on user permissions, endpoint types, etc).

This library also allows you to seperate your object transformation logic from your Models. Your models do not need to concern themselves with how they get represented over the wire at different endpoints. The same way you can use the transformers to transform objects or arrays. They don't have to be eloquent models.

Note: Laravel API Resource is a great start if you're using &gt;= 5.5. In that case you should carefully evaluate your needs and how your complexity will grow before choosing this.

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

[](#installation)

Install using composer.

```
composer require azaan/laravel-scene

```

Usage
=====

[](#usage)

Create a transformer class to transform your model. You can use the same transform method to transform an array/collection of objects or a single object.

Example.

```
class PersonTransformer extends SceneTransformer {

    /**
     * Eloquent relations to preload
     *
     * Note: It will only get preloaded if it already isnt.
     */
    protected function getPreloadRelations()
    {
        return [
            // preload nested relations of posts defined in PostTransformer
            'posts'   => SceneTransformer::PRELOAD_RELATED,

            // load addresses if $this->showMin is truthy
            'address' => $this->showMin,

            // preload createdBy relation
            'createdBy',
        ];
    }

    /**
     * Structure transformations.
     *
     * @return array structure
     */
    protected function getStructure()
    {
        return [
            'id',
            'name',
            'email',
            'fullname',
            'actions',
            'address' => [
                'name',
                'street',
            ],
            'status' => new ArrayMapTransform([
                'active'        => 'Active',
                'blocked'       => 'Blocked',
                'temp-disabled' => 'Temporarily Disabled',
            ]),
            'posts' => PostTransformer::createMinTransformer(),

            // return the field 'joined_date' as 'date',
            'date' => 'joined_date',

            'created_at' => new DateFormatTransform('Y-m-d'),
        ];
    }

    /**
     * Structure to use when returning multiple objects
     *
     * @return array structure
     */
    protected function getMinStructure()
    {
        return [
            'id',
            'name',
            'email',

            // add extra key only when some condition meets
            'extra' => $this->when($this->someCondition, 'extra'),
        ];
    }

    protected function getFullname(Person $person)
    {
        return $person->first_name . ' ' . $person->last_name;
    }

    protected function getActions(Person $person)
    {
        // call service methods to figure out what actions the user can perform

        return ['can_edit', 'can_update'];
    }
}
```

Now in your controller method.

```
    public function all()
    {
        $people = $this->personService->getAllPeople();

        $transformer = PersonTransformer::createMinTransformer();
        return SceneResponse::respond($people, $transformer);
    }

    public function show($id)
    {
        $person = $this->personService->getPersonByIdOrFail($id);

        $transformer = new PersonTransformer();
        return SceneResponse::respond($person, $transformer);
    }
```

You can use the `SceneRespond::respond` method with either a collection of data or a single object. The transformer will handle it appropriately. It can also handle a `LengthAwarePaginator`.

In this example it is assumed your model (`Person`) has the attributes id, name, email and created\_at. For the field `fullname` the method `getFullname` is used to resolve the value.

Keys are resolved using the following steps:

1. If a getter method exists in the transformer it is called
2. Check if the key exists on the object
3. Check if a getter method for the key exists on the object
4. Returns `null`

### Nesting Transformers

[](#nesting-transformers)

You can nest transformers within another transformer. For example if you had a `Company` model with a relation called owner which resolves to a `Person` object your `Company` transformer can look like this.

```
class CompanyTransformer extends SceneTransformer {
    /**
     * Structure transformations.
     *
     * @return array structure
     */
    protected function getStructure()
    {
        return [
            'id',
            'name',
            'owner' => new PersonTransformer()
        ];
    }
}
```

This way your transform logic for every model is compartmentalised and can easily be reused.

Hooks
-----

[](#hooks)

Several hook methods are defined which you can override to get desired behaviour.

### Injecting from Laravel Container

[](#injecting-from-laravel-container)

If you need to inject classes from the laravel container you can override the method `inject`. All parameters of the `inject` method will be resolved from the Laravel Container.

### Minimum Structure

[](#minimum-structure)

When you're responding with a collection of objects (Eg: for a listing) you might want to respond with different fields. You can use this by overriding the method `getMinStructure()`. In this case when you're instantiating the transformer in the controller use the method `::createMinTransformer()`

### Preload Eloquent relations

[](#preload-eloquent-relations)

When responding with a collection of eloquent objects and accessing relations which haven't been loaded it will lead to the N+1 query problem. You can override the method `getPreloadRelations` and return an array of relations to be preloaded by the transformer. The transformer will take care of only loading the relations which haven't been loaded and will load them whenever appropriate. You can also use dot notation to preload nested relations. (Eg: `person.address`)

### Pre process

[](#pre-process)

Override the methods `preProcessSingle` and `preProcessCollection` to run any pre process logic before the transformer starts transforming the objects.

### Null State

[](#null-state)

Override the method `getNullState` to return the default state if the object is null. Default implementation returns `null`

### Ordering

[](#ordering)

Usually it is better to do your ordering before passing into the transformer. However in cases where you require to order by a field which is only present after the transformation you can override `getOrderBy` to provide ordering. You should return the field name as a string to order by. If you require direction return an array. (Eg: `['field_name', 'DESC']`)

### Post process hook.

[](#post-process-hook)

To do any changes **after** all transformations you can override the method `transformObject`. The transformed output array will be passed in as the first argument and original object as the second.

Licence
=======

[](#licence)

MIT

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity34

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity67

Established project with proven stability

 Bus Factor1

Top contributor holds 92.6% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~75 days

Recently: every ~222 days

Total

19

Last Release

1782d ago

Major Versions

v1.2.1 → v2.0.02019-12-18

### Community

Maintainers

![](https://www.gravatar.com/avatar/4a09fbc7b6c5dd2524270dfba192d953aa03b9fe2af41104710435d580620bdd?d=identicon)[azaan](/maintainers/azaan)

---

Top Contributors

[![aznn](https://avatars.githubusercontent.com/u/1500309?v=4)](https://github.com/aznn "aznn (25 commits)")[![vrajroham](https://avatars.githubusercontent.com/u/12662173?v=4)](https://github.com/vrajroham "vrajroham (2 commits)")

---

Tags

laraveltransformer

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/azaan-laravel-scene/health.svg)

```
[![Health](https://phpackages.com/badges/azaan-laravel-scene/health.svg)](https://phpackages.com/packages/azaan-laravel-scene)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[api-platform/laravel

API Platform support for Laravel

58171.6k14](/packages/api-platform-laravel)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5021.9k](/packages/simplestats-io-laravel-client)[pressbooks/pressbooks

Pressbooks is an open source book publishing tool built on a WordPress multisite platform. Pressbooks outputs books in multiple formats, including PDF, EPUB, web, and a variety of XML flavours, using a theming/templating system, driven by CSS.

45444.2k1](/packages/pressbooks-pressbooks)[rapidez/core

Rapidez Core

1823.5k72](/packages/rapidez-core)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
