Download the PHP package gbradley/laravel-api-resource without Composer

On this page you can find all versions of the php package gbradley/laravel-api-resource. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-api-resource

This package expands on Laravel's base classes to provide a more succinct yet powerful way to control your API resources.

Goals

Requirements

Installation

$ composer require gbradley/laravel-api-resource

Usage

Extending the new resource class

In your resource, instead of extending Laravel's Resource, change this to extend GBradley\ApiResource\Resource instead:

namespace App\Http\Resources;

use GBradley\ApiResource\Resource;

class PostResource extends Resource
{
    ...
}

That's it! You can now use this resource as you would any normal resource. A main goal of this package is not to change resources' existing behaviour.

Quicker attribute definitions

In our example resource, lets define some attributes. Normally you would have to do this individually, which can be quite verbose with a lot of repetition. Instead, you can now use mergeAtrributes() to quickly define the attributes you wish to use from your underlying model. This reduces something like:

class PostResource extends Resource
{

    public function toArray($request)
    {
        return [
            'id'        => $this->id,
            'title'     => $this->title,
            ...
        ];
    }

to this:

class PostResource extends Resource
{

    public function toArray($request)
    {
        return [
            $this->mergeAttributes('id', 'title', ...),
        ];
    }

This has the additional benefit of retaining date formats in casted date or datetime attributes. Normally you would have to specify the format again in your resource, but this will now be handled for you.

Of course, you can mix both the new and old styles if needed:

class PostResource extends Resource
{

    public function toArray($request)
    {
        return [
            $this->mergeAttributes('id', 'title', ...),
            'dated'     => $this->dated->format('d/m/Y'),
        ];
    }

Relation handling

Laravel's resources have two strategies for adding relations:

Direct loading - this always loads relations, often resulting in non-eager loaded queries being executed to generate data which the front-end may not need.

Conditional loading - this returns relations only when they are already loaded, deffering loading to the controller. However, your business logic may also load relations (for example inside an event handler), meaning your response structure can be affected by internal side-effects.

Instead, this package allows controllers to explicitly define which relations the resource can expose, with the resource determining which relations it will expose. These can either be required relations, which will always be exposed, or optional relations, which will be exposed if specified in the current request. The result is a flexible system which also utilises eager-loading.

To start, open your controller. Instead of instantiating a resource, or using the collection() method, use the static build method which can accept a model, a collection or a paginator instance:

return PostResource::build($model);

This exposes a fluid interface for specifying the relations. To specify relations which should always be exposed, pass an array of names to withRelations():

return PostResource::build($model)
    ->withRelations('blog', 'author');

Use withOptionalRelations() in the same manner to define relations which will only be exposed if found in the load parameter of the current request:

return PostResource::build($model)
    ->withRelations('blog', 'author')
    ->withOptionalRelations('comments.author');

As you can see from the above example, these methods also accept nested relations.

Now the controller has defined what it allows the resource to expose, you can configure the resource to do so using mergeWhenExplicitlyLoaded(). This method accepts the array of relation names that the resource can expose:

class PostResource extends Resource
{

    public function toArray($request)
    {
        return [
            $this->mergeAttributes('id', 'title'),
            $this->mergeWhenExplicitlyLoaded([
                'blog', 'author', 'comments'
            ]),
        ];
    }

Transforming relations

When passing items sequentially, they will be exposed using the related object's toArray method. If you would like to transform them into other resources, pass the relation as the key and the desired resource class as the value. These techniques can be combined:

class PostResource extends Resource
{

    public function toArray($request)
    {
        return [
            $this->mergeAttributes('id', 'title'),
            $this->mergeWhenExplicitlyLoaded([
                'blog',
                'author',
                'comments' => CommentResource::class,
            ]),
        ];
    }

In this case, we can now also define CommentResource to expose its author relation when explicitly loaded.

class CommentResource extends Resource
{

    public function toArray($request)
    {
        return [
            $this->mergeAttributes('id', 'content'),
            $this->mergeWhenExplicitlyLoaded([
                'author',
            ]),
        ];
    }

This results in a request like this:

`GET /post/1?load[]=comments.author`

returning something like this:

{
    'id' : 1,
    'name' : 'Blog post 1',
    'blog'  : {
        'id' => 123,
        'title' => 'My Blog',
    },
    'author' : {
        'id' : 456,
        'name' : 'Graham',
    },
    'comments' : [
        {
            'id' : 789,
            'content' : 'Nice post!',
            'author' : {
                'id' : 987,
                'name' : 'Taylor Otwell'
            }
        }
    ]
}

Polymorphic relations

For polymirphic relations, first add a {relation}_type property to your resource. Then, specify a map of the possible classes and their relations inside mergeWhenExplicitlyLoaded():

class CommentResource extends Resource
{

    public function toArray($request)
    {
        return [
            $this->mergeAttributes('id', 'content', 'commentable_type'),
            $this->mergeWhenExplicitlyLoaded([
                'author',
                'commentable' => [
                    Post::class => PostResource::class,
                    Page::class => PageResource::class,
                ]
            ]),
        ];
    }

Contextual data

Sometimes you may want to modify your resource's transformation based on information that isn't found in the request or the model being transformed.

To make arbitary data available to your resource, call withContext() on the resource builder returned from build():

$context = [
    'foo' => [
        'bar' => 1
    ]
];

return PostResource::build($model)
    ->withRelations('blog')
    ->withContext($context);

Your context data can be accessed inside the resource with getContext(). You can also use dot notation to retrive a subset of the data:

$data = $this->getContext('foo.bar');

You may use mergeContext() to merge all or part of the context into your representation:

class PostResource extends Resource
{

    public function toArray($request)
    {
        return [
            $this->mergeAttributes('id', 'title'),
            $this->mergeWhenExplicitlyLoaded([
                'blog' => BlogResource::class,
            ]),
            $this->mergeContext('foo.bar')
        ];
    }

Any context data provided to a resource will be passed down to any other resources loaded via relations. In the above example, the context data will be available on the instances of BlogResource.

Data wrapping

Laravel's resources allow you to disable data wrapping, however this does so for both models and collections. Although the security risks of returning top-level JSON arrays appear to have been resolved in all browers, some may prefer to avoid wrapping single models but retain wrapping for collections.

Do to this, call withoutWrapping() on the new Resource class, followed by wrapCollection():

public function boot()
{
    Resource::withoutWrapping();
    Resource::wrapCollection('data');
}

All versions of laravel-api-resource with dependencies

PHP Build Version
Package Version
Requires php Version >=7.1.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package gbradley/laravel-api-resource contains the following files

Loading the files please wait ....