使用Tornado RequestHandlers时,最好的REST实现是什么?
我想定义一个REST API,它的基本格式是:
mysite.com/OBJECT_ID/associations
举个例子:
mysite.com/USER_ID/vacations
- 管理用户的假期mysite.com/USER_ID/music
- 管理用户音乐库里的音乐mysite.com/PLAYLIST_ID/music
- 管理特定播放列表里的音乐
我在服务器端使用tornado,想要一些建议,关于如何为这个API定义请求处理器。例如,我想定义一个处理器像这样:
/([0-9,a-z,A-Z,-]+)/music",MusicHandler),
但我在实现MusicHandler时遇到了困难,因为它需要知道URI中指定的对象是否支持音乐,也就是说,如何防止像这样的请求:
mysite.com/LOCATION_ID/music
因为位置是和音乐没有关联的。
最好的解决办法是修改API,包含类型,比如:
mysite.com/users/USER_ID/music
或者
mysite.com/playlists/PLAYLIST_ID/music
然后为每个类型定义一个单独的处理器:
/users/([0-9,a-z,A-Z,-]+)/music",UserMusicHandler),
/playlists/([0-9,a-z,A-Z,-]+)/music",PlaylistMusicHandler)
这样似乎不太对,但我真的不太明白怎么才能做到。我知道这应该是个简单的问题,但我对python和tornado还很陌生。
2 个回答
if not self.db.get("SELECT 1 FROM objects WHERE music_id = %s", object_id):
raise HTTPError(404, "Music object %s not found" % name)
我觉得用 mysite.com/music/MUSIC_ID
这样的方式更合理。
首先,为了防止像 mysite.com/LOCATION_ID/music
这样的链接出现问题,我建议你给所有的 ID 设置不同的长度。例如,可以让 LOCATION_ID 是 32 个字符的字符串,而 PLAYLIST_ID 是 34 个字符的字符串,等等。这样一来,当处理请求时,你就可以通过检查字符串的长度来判断它是否有效。
另外,你也可以使用正则表达式来直接在链接中捕捉这些 ID,然后为每个 ID 定义不同的处理方式。(此外,建议把你的 ID 放在链接中所有静态文本之后,这样做是个好习惯)。比如,如果你的 PLAYLIST_ID 是一个 UUID,而 LOCATION_ID 是一个字符串:
(r"/music/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})", PlaylistMusicHandler), #playlistID
(r"/music/([A-Za-z0-9]+)", LocationHandler), #locationID