Restful API 和 web.py

Restful API with web.py

在 PHPs Slim 中我可以这样做:

$app->get('/table/{table}', function (Request $request, Response $response, $args) {
    $table = $args['table'];
    $mapper = new TableMapper($this, $table);
    $res = $mapper->getTable();
    return $response->withJson($res);
}
$app->get('/table/{table}/{id}', function (Request $request, Response $response, $args) {
    $table = $args['table'];
    $id = (int)$args['id'];
    $mapper = new TableMapper($this, $table);
    $res = $mapper->getTableById($id);
    return $response->withJson($res);
}

现在我正在尝试 web.py。我可以这样做:

urls = (
    '/table/(.+)', 'table',
)
class table:
    def GET( self, table ):
        rows = db.select( table )
        web.header('Content-Type', 'application/json')
        return json.dumps( [dict(row) for row in rows], default=decimal_default )

但是如果我尝试通过这样做来扩展它,例如:

urls = (
    '/table/(.+)', 'table',
    '/table/(.+)/(\d+)', 'table_by_id'
)

处理永远不会到达 url 中的第二个。相反,代码在 table 名称 "table/id" 上执行 db.select,这当然是错误的。

我如何开发它来解析添加了 id 的 url?

试试这个:

urls = (
    '^/table/(.+)/$', 'table',
    '^/table/(.+)/(\d+)/$', 'table_by_id'
)

web.py 与 urls 中列出的 顺序 匹配,因此切换顺序是解决问题的一种方法:

urls = (
    '/table/(.+)/(\d+)', 'table_by_id',
    '/table/(.+)', 'table'
)

另一条建议:收紧正则表达式,以便更准确地匹配您要查找的内容。您会更快发现错误。

例如,您会注意到您的 /table/(.+) 确实匹配 "/table/foo/1",因为正则表达式 .+ 也匹配 /,因此您可以考虑像这样的模式([^/]+) 匹配 "everything" 除了斜杠。

最后,您的 URL 中不需要前导“^”或尾随“$”,web.py 总是 看起来与完整模式匹配。 (在内部,它添加了“^”和“$”)。