Dealing with the HATEOAS constraint

HATEOAS - Hypermedia As The Engine Of State requires that we add links to each Endpoint which will describe what actions can be taken on each resource at any given point in time. There are a number of different standards for this format which, at the time of writing, are competing to become the dominant format. For the purposes of this post, we will use the HAL (Hypermedia Application Language) format.

To add available links to each Member entity edit the file \app\Models\Member.php and add the following code. In line with Hypertext Application Language, this will add _links attributes to the JSON for each member. For each member, there will be a link to that individual member's endpoint - there will also be a link to this list of bookings made by that member. These represent the actions that can be taken on this resource.

    protected $appends = ['_links'];
    
    public function getLinksAttribute()
    {
        return [
            ['self' => app()->make('url')->to("api/members/{$this->attributes['id']}")],
            ['bookings' => app()->make('url')->to("api/member/{$this->attributes['id']}/bookings")]
        ];
    }

To make the bookings link work we need to add a bookings dynamic attribute to the Member model - add the following function to the member model

public function bookings()
{
    return $this->hasMany(\App\Models\Booking::class, 'memberid');
}

Now we need to add a function to the MemberController which will produce the list of bookings that each Member had made.

public function showMemberBookings($id)
{
    $bookings = Booking::all()->where('memberid',$id);
    return response()->json($bookings);
}

To make the showMemberBookings($id) function work we need to add a corresponding route edit routes\web.php and add the following route inside the api group

$router->get('member/{id}/bookings', ['uses' => 'App\Http\Controllers\MemberController@showMemberBookings']);

Now when you test the members endpoint you will see a list of links for each resource and each one will show a link to the member itself and a list of bookings for that member.

This will make the JSON we produce a lot more verbose and hard to read. We need to "pretty-print" the json output. Jq is a small footprint easy to use tool which will pretty-print JSON.

To install A Windows binary can be downloaded here. If you download the program and rename it jq.exe you can use it by "piping" the results of our curl command to jq as follows

curl -v http://localhost:8000/api/members | jq

Now your results including links will be pretty-printed as follows

Leave a Reply