Tornado URL regex for REST API: how to not define the item ID argument for the POST action?

4.4k Views Asked by At

I'm writing a REST API with Tornado. I'm aiming at having only one handler definition per handler class in my application configuration.

Here is the Regex I got:

url(r"/items/?([?P<item_id>\w])?", ItemHandler)

to match the following verbs/actions:

  • GET /items
  • GET /items/
  • GET /items/[ID]
  • POST /items
  • PUT /items/[ID]
  • DELETE /items/[ID]

My concern is that the POST action never requires an ID BUT the ID is required by Tornado in the method definition to match the Regex pattern:

def post(self, item_id=None):
    # item_id should be None; it is here to match the URL Regex 

Do you know if a different Regex pattern would allow me to not define the item_id argument in the method definition?

1

There are 1 best solutions below

1
On BEST ANSWER

It is not possible to use different regexes for different http methods. You'll need to either define a dummy argument in your post() method (and raise an error if it is present) or use two different handler classes for the with-id and without-id forms.

Don't try to be clever with regexes, just make multiple rules even if they all point to the same handler class. For example, your regex will match /itemfoo since the / is optional, but that's presumably not what you want. It would be cleaner to split this up:

url(r"/items/?", ItemHandler), # no id, optional slash
url(r"/items/(?P<item_id>\w+)", ItemHandler), # slash and id required