★ A package that adds resource links to your Laravel API resources
Tags: laravel, php
Published: 2020-01-02 23:38:31

---
title: ★ A package that adds resource links to your Laravel API resources
published: true
date: 2019-10-01 19:57:47 UTC
tags: laravel, php
canonical_url: https://freek.dev/1470-a-package-that-adds-resource-links-to-your-laravel-api-resources
---

At [Spatie](https://spatie.be) we have several projects where the UI is rendered using JavaScript (we're big fans of [Inertia](https://inertiajs.com/)). The backend and routes are defined in the Laravel app. The backend sends information to the frontend using [API resources](https://laravel.com/docs/master/eloquent-resources).

We often add the available routes the frontend can use as `links` property on the resource. To avoid having to add all routes manually, my colleague [Ruben](https://twitter.com/rubenvanassche) released a package, called [laravel-resource-links](https://docs.spatie.be/laravel-resource-links/v1/introduction/) that can automatically add resource links to the API resource.

In this post, I'd like to introduce the package to you.

## A first example #

Imagine you have a `UsersController` with `index`, `show`, `create`, `edit`, `store`, `update` and `delete` methods. You want to add these routes to a `UserResource`.

This is how you do that using our package. You apply the `Spatie\ResourceLinks\HasLinks` trait use the `links` method.

```php
class UserResource extends JsonResource
{
    use Spatie\ResourceLinks\HasLinks;
    use Spatie\ResourceLinks\HasMeta;

    public function toArray($request): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'links' => $this->links(UsersController::class),
        ];
    }
}
```

When rendering that resource to json this will be the result:

```js
{
   "data":[
      {
         "id":1,
         "name": "Ruben Van Assche",
         "links": {
            "show": "https://laravel.app/users/1",
            "edit": "https://laravel.app/users/1/edit",
            "update": "https://laravel.app/users/1",
            "delete": "https://laravel.app/users/1"
         }
      }
   ],
}
```

That works fine for routes that revolve around an instance of your resource (in this example: a single user). But what about routes by a single instance, such as `index` and `create`?

You can take care of those routes by applying the `HasMeta` trait and adding a `meta` function to your resource.

```php
class UserResource extends JsonResource
{
    use Spatie\ResourceLinks\HasMeta;

    // ...
    
    public static function meta()
    {
        return [
            'links' => self::collectionLinks(UsersController::class),
        ];
    }
}
```

This is how that resource will be rendered:

```json
{
   "data":[
      {
         "id":1,
         "name": "Ruben Van Assche",
         "links": {
            "show": "https://laravel.app/users/1",
            "edit": "https://laravel.app/users/1/edit",
            "update": "https://laravel.app/users/1",
            "delete": "https://laravel.app/users/1"
         }
      }
   ],
   "meta": {
      "links": {
         "index": "https://laravel.app/users",
         "create": "https://laravel.app/users/create",
         "store": "https://laravel.app/users"
      }
   }
}
```

## Customizing the json structure #

You can change the structure of how things are rendered to json. In the config file of the package, you can specify the serializer class to be used. A serializer is responsible for building the output of the links of a resource.

The package ships with a few different serializers. In the example in the previous section, the `LinkSerializer` is used (that's the one that is used by default).

If you use `ExtendedLinkSerializer` the links will include the HTTP verb of a link.

```json
"links": {
    "index": {
        'method': 'get',
        'action': "https://laravel.app/users"
    },
    "update": {
        'method': 'put',
        'action': "https://laravel.app/users/1"     
    },
}
```

You can also [write your own serializer](LinkSerializer) to customize the behavior to your heart's content.

## Closing thoughts #

This package came in handy in several projects. It provides quite some more options. Read [the documention](https://docs.spatie.be/laravel-resource-links) to know more.

Thanks [Ruben](https://twitter.com/rubenvanassche) for the excellent work!

Be sure to also check out the [other packages](https://spatie.be/open-source/packages) [our team](https://spatie.Be) has created previously.