1

I am in the process of setting up my first apigility project and so far it is going well. I'm having some issues with the routing and how to set it up though.

Suppose I have songs, albums and artist (fictitious example for this question only). I want to do a structure like this:

/artists (GET, POST, PUT, PATCH, DELETE)
/albums (GET, POST, PUT, PATCH, DELETE)
/songs (GET, POST, PUT, PATCH, DELETE)

Pretty easy so far. I have filters on those end-points so I can say:

/artists/?style=jazz
/albums/?year=2012
etc...

Now, I also want to include child end-points like this:

/artist/12345/albums (GET) - get all albums for artists with id 12345
/artist/12345/songs (GET) - get all songs for artists with id 12345
/albums/98765/songs (GET) - get all songs for album with id 98765

How do I set this up in a proper way in apigility?

I started by creating a separate service ArtistAlbum, with route /artists/:artist_id/albums and then changing the entity from ArtistAlbumEntity to AlbumEntity (it is basically that) and the collection from ArtistAlbumCollection to AlbumCollection. The route identifier name is set to artist_album_id though, which I will never use. You cannot delete that though.

This ways feels a bit hacky to be honest.

In effect, the above route /artists/:artist_id/albums is actually an alias for /albums/?artist_id=:artist_id. It is a sort of filter.

How do I implement something like this in a proper way?

2 Answers2

0

You can distinguish different types of relationships between your (REST) classes/resources.

  • association
  • aggregation
  • composition

This is nicely explained here on this blogpost but those relationship types are also nicely defined on Wikipedia.

Understanding those types of relationships will help you on how to define (the hierarchy in) your model and it can also help in organizing your urls. I won't go into details here because you can already find a lot of information on relationship types, nested resources and and rest design on stackoverflow. I would only be repeating things. For example here, here, here, here or here but you can surely find more yourself.
Simply search for: "nested resources REST design"

There is not one commonly accepted solution for url design. People often have personal preferences on how to deal with this. Some people (I do not agree) even believe a proper rest model should not use nested (so no hierarchical) urls but a flat structure for all resources.

Community
  • 1
  • 1
Wilt
  • 41,477
  • 12
  • 152
  • 203
0

Consider the following Zend 2 router configuration in module.config.php

<?php
[
'router' => [
    'routes' => [
        'api.rest' => [
            'type' => 'Hostname',
            'options' => [
                'route' => 'api.site.dev'
            ],
            'may_terminate' => false,
            'child_routes' => [
                'homeRoute' => [
                    'type' => 'Literal',
                    'options' => [
                        'route'    => '/',
                        'defaults' => [
                            'controller' => 'Api\\V1\\Rest\\Welcome\\Controller',
                        ]
                    ],
                    'may_terminate' => true,
                    'child_routes' => [
                        'appRoute' => [
                            'type'    => 'Literal',
                            'options' => [
                                'route'    => 'app',
                            ],
                            'may_terminate' => false,
                            'child_routes' => [
                                'postsRoute' => [
                                    'type'    => 'Literal',
                                    'options' => [
                                        'route'    => '/posts',
                                        'defaults' => [
                                            'controller' => 'Api\\V1\\Rest\\Post\\Controller',
                                        ],
                                    ],
                                ]
                            ]
                        ]
                    ],
                ]
            ]
        ],
    ]
]
];

Then using Apigility, if you want the route name to run Post resource located at api.site.dev/app/posts, just call it with api.rest/homeRoute/appRoute/postsRoute

Eg: Use the URL Plugin like this $this->url('api.rest/homeRoute/appRoute/postsRoute');

Don't know if it works with older versions but actually I use Apigility 1.4.1 and it works like a charm

BoCyrill
  • 1,219
  • 16
  • 17