REST:通过多个ID访问集合的成员

时间:2013-06-23 11:40:03

标签: api rest servicestack

我有一个处理网络上视频服务器的REST服务。

每个视频服务器都可以通过多种方式识别:通过序列号, 按名称或机器编号。

用于返回网络上可用的所有服务器的集合 非常简单:我已经定义了以下路线:

[Route("/servers", "GET")]

以及以下请求类:

public class ServerCollection : IReturn<List<ServerDto>>
{
    ...
}

现在,我想从我的收藏中返回一个特定的服务器,进行识别 它可以是序列号,机器名称,也可以是机器编号。

为此,我定义了以下路线:

[Route("/servers/{SerialNumber}", "GET")]
[Route("/servers/machinenumbers/{MachineNumber}", "GET")]
[Route("/servers/machinenames/{MachineName}", "GET")]

以及以下请求类:

public class Server : IReturn<ServerDto>
{
    public uint SerialNumber { get; set; }
    public uint MachineNumber { get; set; }
    public string MachineName { get; set; }
}

所以,我可以通过以下方式访问我的服务器集合:

GET /servers

使用以下任一项获取特定服务器:

GET /servers/3
GET /servers/machinenumbers/42
GET /servers/machinenames/supercalifragilisticexpialidocious

这是正确的方法吗?我觉得这不是很好 REST风格。我应该将此视为我的收藏中的搜索,而不是使用“人工” 资源?

3 个答案:

答案 0 :(得分:2)

我会以一种始终唯一的方式表示服务(序列号可能是正确的)。

对于查询,我会执行类似/servers/?name=[name]/server/?id=[id]/servers/[serial]的操作(如果您想直接使用序列号)。在请求名称或ID时,您应该将请求中的网址更改为servers/[serial]以保持网址唯一。

答案 1 :(得分:2)

我相信这是ServiceStack方式。只需使两个uint字段都可以为空,这样在服务实现中你就可以确定搜索的参数是什么。

答案 2 :(得分:1)

没关系,只要你将两个URI重定向(3xx)到另一个,而不是在所有三个都返回相同的表示(2xx)。否则,您将有一段时间让副本在缓存中保持同步。在您的情况下,将machinenumbers和machinenames资源重定向到servers / {id}资源似乎是合乎逻辑的。

如果有的话,它是使用与REST对立的k = v参数的通用搜索。请记住,URI标识资源,而查询字符串是URI的一部分:不同的查询字符串标识不同的资源。由于表单样式查询字符串中的术语集通常较大(为了方便起见),并且术语可以按任何顺序出现,这会导致潜在资源的爆炸(如果您不打算依赖于缓存效率,那么你有很多其他的选择,但那不是REST)。