使用Tornado RequestHandlers时,最好的REST实现是什么?

4 投票
2 回答
4585 浏览
提问于 2025-04-16 15:10

我想定义一个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 个回答

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 这样的方式更合理。

2

首先,为了防止像 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

撰写回答