3

When I try to create the routes for a RESTful API with the following $url_handlers, it seems to create a conflict between two of the patterns.

class API extends Controller {

    ...

    private static $url_handlers = array(
        'GET object' => 'read',
        'POST object' => 'create',
        'PUT object/$ID' => 'update',
        'PUT object/$ID/$OtherID' => 'assign',
        'DELETE object/$ID' => 'delete',
        'DELETE object/$ID/$OtherID' => 'unassign',
    );

    ...
}

object/1 works fine, but object/1/1 is matching to the update action.

What extra detail do I add to make these patterns work?

jakxnz
  • 550
  • 5
  • 21

1 Answers1

4

I found the answer with the help of zippy and flamerohr on Silverstripe Users Slack


URL patterns should be defined in the order of most-specific to least-specific.

Option 1:

Re-order the patterns correctly, and add a static segment between variables, so that the added specificity avoids the pattern from matching when it shouldn't e.g

private static $url_handlers = array(
    'GET object' => 'read',
    'POST object' => 'create',
    'PUT object/$ID/static-segment/$OtherID' => 'assign',
    'PUT object/$ID' => 'update',
    'DELETE object/$ID/static-segment/$OtherID' => 'unassign',
    'DELETE object/$ID' => 'delete',
);

Option 2:

Re-order the patterns correctly, and use the ! convention to define that a URL parameter must be provided in order to match the pattern e.g

private static $url_handlers = array(
    'GET object' => 'read',
    'POST object' => 'create',
    'PUT object/$ID/$OtherID!' => 'assign',
    'PUT object/$ID' => 'update',
    'DELETE object/$ID/$OtherID!' => 'unassign',
    'DELETE object/$ID' => 'delete',
);

This convention can be found in Silverstripe's Routing documentation: https://docs.silverstripe.org/en/3.2/developer_guides/controllers/routing/#url-patterns

jakxnz
  • 550
  • 5
  • 21