Oh Dear is the all-in-one monitoring tool for your entire website. We monitor uptime, SSL certificates, broken links, scheduled tasks and more. You'll get a notifications for us when something's wrong. All that paired with a developer friendly API and kick-ass documentation. O, and you'll also be able to create a public status page under a minute. Start monitoring using our free trial now.

A package that adds resource links to your Laravel API resources

Original – by Freek Van der Herten – 3 minute read

At Spatie we have several projects where the UI is rendered using JavaScript (we're big fans of Inertia). The backend and routes are defined in the Laravel app. The backend sends information to the frontend using API 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 released a package, called laravel-resource-links 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.

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:

{
   "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.

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.

"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 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 to know more.

Thanks Ruben for the excellent work!

Be sure to also check out the other packages our team has created previously.

Stay up to date with all things Laravel, PHP, and JavaScript.

You can follow me on these platforms:

On all these platforms, regularly share programming tips, and what I myself have learned in ongoing projects.

Every month I send out a newsletter containing lots of interesting stuff for the modern PHP developer.

Expect quick tips & tricks, interesting tutorials, opinions and packages. Because I work with Laravel every day there is an emphasis on that framework.

Rest assured that I will only use your email address to send you the newsletter and will not use it for any other purposes.

Comments

What are your thoughts on "A package that adds resource links to your Laravel API resources"?

Comments powered by Laravel Comments
Want to join the conversation? Log in or create an account to post a comment.