Search code examples
perlendpointchainingcatalyst

Perl Catalyst Controller chains


I am having trouble creating a 'flexible' endpoints. Is something along these lines possible:

# 1) List all Microarrays for this species
/regulatory/species/:species/microarray
sub microarray_list: Chained('species') PathPart('microarray') ActionClass('REST') { }

# 2) Information about a specific array
/regulatory/species/:species/microarray/:microarray
sub microarray_single: Chained('species') PathPart('microarray') CaptureArgs(1) ActionClass('REST') { }

# 3) Information about a probe on the array
/regulatory/species/:species/microarray/:microarray/probe/:probe
sub microarray_probe: Chained('microarray_single') PathPart('probe') Args(1) ActionClass('REST')

At startup 1) is not registered:

| /regulatory/species/*/id/*          | /regulatory/species (1)              |
|                                     | => /regulatory/id (1)                |
| /regulatory/species/*/microarray    | /regulatory/species (1)              |
|                                     | => /regulatory/microarray_list (...) |
| /regulatory/species/*/microarray/*- | /regulatory/species (1)              |
| /probe/*                            | 

Any help should be greatly appreciated!


Solution

  • Yes, it's possible, your problem is just that you don't have an endpoint for microarray_single. You probably want

    sub microarray_list :Chained('species') PathPart('microarray')
                         ActionClass('REST') { }
    
    # this is the chain midpoint, it can load the microarray for the endpoints to use
    sub microarray :Chained('species') PathPart('microarray')
                    CaptureArgs(1) { }
    
    # this is an endpoint with the same path as the midpoint it chains off of
    sub microarray_single :Chained('microarray') PathPart('')
                           Args(0) ActionClass('REST') { }
    
    # and this is an endpoint that adds .../probe/*
    sub microarray_probe :Chained('microarray') PathPart('probe')
                          Args(1) ActionClass('REST') { }
    

    if there are other things that can come after .../microarray/*/probe/* then you would do likewise, changing microarray_probe from Args(1) ActionClass('REST') (endpoint) to CaptureArgs(1), and then adding an endpoint with :Chained('microarray_probe') PathPart('') Args(0) ActionClass('REST') to handle the case where there are no additional path parts.

    The important thing to keep in mind is that only chain endpoints (i.e. actions without CaptureArgs) correspond to valid URL paths.