Oh Dear! monitors your entire website, not just the homepage. You'll get a notification as soon as your website is down, a monthly uptime report, a warning a few days before your SSL certificate expires and much more! Start your free 10 day 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.

Follow me on Twitter. I regularly tweet out programming tips, and what I myself have learned in ongoing projects.

Every two weeks 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

You can comment on this post by replying to this tweet.
Chris SFR liked on 9th October 2019
Thore Sünert liked on 9th October 2019
NAbeel Yousaf liked on 9th October 2019
Glen liked on 9th October 2019
Zé da recaída liked on 9th October 2019
Roy Shay liked on 9th October 2019
Spatie retweeted on 9th October 2019
Tony Messias liked on 9th October 2019
Cyril de Wit liked on 8th October 2019
Guus liked on 8th October 2019
Elie Andraos liked on 8th October 2019
mahmod liked on 8th October 2019
Stefan Zweifel liked on 8th October 2019
Grant Williams liked on 8th October 2019
Chumang liked on 8th October 2019
Jimmy Lipham liked on 8th October 2019
Ryan Kilfedder retweeted on 8th October 2019
oluwajubelo loves VueJS 🚨 liked on 8th October 2019
Sam Snelling liked on 8th October 2019
Rias Van der Veken liked on 4th October 2019
themoon liked on 4th October 2019
Swapnil Bhavsar liked on 3rd October 2019
Zaher Ghaibeh liked on 3rd October 2019
Spatie retweeted on 3rd October 2019
Camilo Caquimbo liked on 3rd October 2019
bernard kssy retweeted on 2nd October 2019
Chris Blackwell liked on 2nd October 2019
Ashish K. Poudel liked on 2nd October 2019
Gianmarco Nalin liked on 2nd October 2019
Mithicher Baro liked on 2nd October 2019
Mithicher Baro retweeted on 2nd October 2019
Niels liked on 2nd October 2019
Mark Myers liked on 2nd October 2019
hjtshort retweeted on 2nd October 2019
ali ali liked on 2nd October 2019
Amro O liked on 2nd October 2019
Rama Patel liked on 2nd October 2019
Arputharaj liked on 2nd October 2019
Ihor Vorotnov • 25% liked on 2nd October 2019
Chin Leung liked on 2nd October 2019
Matt Allan liked on 2nd October 2019
jake whiteley liked on 2nd October 2019
Mark Topper liked on 2nd October 2019
Wyatt liked on 2nd October 2019
Tiagosimoes liked on 1st October 2019
Logan H. Craft liked on 1st October 2019
Jimmy Lipham liked on 1st October 2019
PHP Synopsis retweeted on 1st October 2019
Loki liked on 1st October 2019
Ruben Van Assche retweeted on 1st October 2019
Bill Rex liked on 1st October 2019
oluwajubelo loves VueJS 🚨 liked on 1st October 2019
Florian Voutzinos ⚡ liked on 1st October 2019
Ryan Chandler liked on 1st October 2019