Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best REST implemenation when using tornado RequestHandlers

I would like to define a REST API with a general pattern of:

mysite.com/OBJECT_ID/associations

For example:

  • mysite.com/USER_ID/vacations - manage a users vacation
  • mysite.com/USER_ID/music - manage music in the user's music library
  • mysite.com/PLAYLIST_ID/music - manage music in the context of the given playlist

I am using tornado on the server side and looking for suggestions about how to define the RequestHandlers for this API. For instance, I want to define a handler like: /([0-9,a-z,A-Z,-]+)/music",MusicHandler), but I'm stuck on the implementation of MusicHandler, which needs to know if the object specified by in the uri supports music in the first place i.e. how to guard against a call like

mysite.com/LOCATION_ID/music

Where locations have no associations with music.

Is the best fix to modify the api to include the type i.e.:

mysite.com/users/USER_ID/music or

mysite.com/playlists/PLAYLIST_ID/music

and then a separate handler for each:

/users/([0-9,a-z,A-Z,-]+)/music",UserMusicHandler),

/playlists/([0-9,a-z,A-Z,-]+)/music",PlaylistMusicHandler)

That doesn't seem right, but I don't really understand how to make this work. I'm sure this is a simple issue, I am new to python and tornado.

like image 426
eddie tromboni Avatar asked Oct 12 '22 09:10

eddie tromboni


2 Answers

First of all, to guard against mysite.com/LOCATION_ID/music I would create differences between all of your id's. For instance, have LOCATION_ID be a 32 character string, and PLAYLIST_ID 34, etc. This way you can check for the string length as soon as the handler is called.


Alternatively, you can use regular expression groups to catch it right in the URI and then define different handlers for each. (Also, your ID should probably be after all of the static text in the URI, just for good convention). For instance, if your PLAYLIST_ID is a UUID and you LOCATION_ID is a string:

(r"/music/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})", PlaylistMusicHandler), #playlistID
(r"/music/([A-Za-z0-9]+)", LocationHandler), #locationID
like image 168
Hunter Lang Avatar answered Oct 14 '22 21:10

Hunter Lang


if not self.db.get("SELECT 1 FROM objects WHERE music_id = %s", object_id):
    raise HTTPError(404, "Music object %s not found" % name)

FWIW a mysite.com/music/MUSIC_ID scheme makes more sense to me.

like image 33
Cole Maclean Avatar answered Oct 14 '22 20:10

Cole Maclean