如何构建采用ID数组作为资源的REST API


103

我正在为我的项目构建REST API。获取给定用户的INFO的API是:

api.com/users/[USER-ID]

我还希望允许客户端传递用户ID列表。如何构造API,使其具有RESTful并接受用户ID列表?


最通用的答案由@Shuja给出,因为邮递员的其他答案无效,并且依赖于数据库后端。但是,您可以有一个API端点来请求多个ID。
Eswar,

Answers:


97

如果要在URL上传递所有参数,那么最好用逗号分隔的值。然后,您将具有如下所示的URL模板:

api.com/users?id=id1,id2,id3,id4,id5

7
@ uclajatt,REST是一种体系结构模型,而不是协议,如果您研究当今可用的主要REST API,则会发现有多种实现方法。我建议的方法可能是最接近该概念的方法之一,因为它可以完成此处描述的所有约束:en.wikipedia.org/wiki/…。您只能使用CSV表示请求中的数组,而服务响应应使用XML或JSON进行序列化。有什么特殊原因导致您不认为我的方法是REST?
Florin Dumitrescu 2010年

10
为什么不呢?api.com/users?id=id1&id=id2&id=id3&id=id4&id=id5
SENFO 2013年

7
@senfo,我更喜欢id = id1,id2,id3,因为它使URI更短且更易于读取(例如,在调试操作期间,人为读取)。如果id之间有其他参数,则每个值的单独参数会使URI特别难于跟踪:api.com/users?id=id1&id=id2&joined
Florin Dumitrescu

12
但是,大多数Web服务器都支持大约2,000个字节的URL长度。如何使我的API最多支持5,000个ID?
nicky_zs

6
@senfo在类似的URL中…?id=1&id=2&id=3不能保证重复的查询参数将被组合到一个数组中。使用上面的查询字符串,PHP会告诉您idequals [1, 2, 3],但是Ruby on Rails会告诉您equals 3,其他框架的行为也可能不同,例如说idequals 1。像…?id=1,2,3这样的URL 避免了这种混淆的可能性。
罗里·奥肯

33
 api.com/users?id=id1,id2,id3,id4,id5
 api.com/users?ids[]=id1&ids[]=id2&ids[]=id3&ids[]=id4&ids[]=id5

IMO,上述调用看起来不是RESTful的,但是这些是快速有效的解决方法(y)。但是URL的长度受Web服务器(例如tomcat)的限制。

RESTful尝试:

POST http://example.com/api/batchtask

   [
    {
      method : "GET",
      headers : [..],
      url : "/users/id1"
    },
    {
      method : "GET",
      headers : [..],
      url : "/users/id2"
    }
   ]

服务器将回复新创建的批处理任务资源的URI 。

201 Created
Location: "http://example.com/api/batchtask/1254"

现在客户端可以通过轮询获取批处理响应或任务进度

GET http://example.com/api/batchtask/1254


这是其他人试图解决此问题的方法:


7
POST请求获取多个结果不是RESTful的。您的示例显示了在适合POST的位置创建资源,但与原始问题完全不同的情况
Anentropic

2
创建临时资源是RESTful的,不是吗?而且我正在使用GET(又是RESTful)获取资源。
Nilesh

是的,但是这都不是原始问题,它只是询问有关获取多个用户ID的信息
Anentropic

1
感谢@Anentropic指出。我再次阅读了这个问题,它询问如何构建一个使用ID数组作为资源的REST API?我同意,我的回答是不同的。抱歉,您的意思不对。
Nilesh

我喜欢这个答案,因为通过这种机制获得多个用户的RESTful方法。
Shane Courtrille

20

我发现使用可以做另一件事@PathParam。这是代码示例。

@GET
@Path("data/xml/{Ids}")
@Produces("application/xml")
public Object getData(@PathParam("zrssIds") String Ids)
{
  System.out.println("zrssIds = " + Ids);
  //Here you need to use String tokenizer to make the array from the string.
}

使用以下URL调用服务。

http://localhost:8080/MyServices/resources/cm/data/xml/12,13,56,76

哪里

http://localhost:8080/[War File Name]/[Servlet Mapping]/[Class Path]/data/xml/12,13,56,76

5
我喜欢这一点,因为GET是一致的。在此示例中,可以使用一个或多个。这并不是真正的搜索(参数),因为您将为后端提供所需的确切ID。
markthegrea 2012年

1
我看到投票率最高的答案不起作用,您的答案可能是最通用的答案。应该接受作为答案。
Eswar,


0

您可以使用ASP.NET MVC构建Rest API或Restful项目,并将数据作为JSON返回。控制器功能示例为:

        public JsonpResult GetUsers(string userIds)
        {
           var values = JsonConvert.DeserializeObject<List<int>>(userIds);

            var users = _userRepository.GetAllUsersByIds(userIds);

            var collection = users.Select(user => new { id = user.Id, fullname = user.FirstName +" "+ user.LastName });
            var result = new { users = collection };

            return this.Jsonp(result);
        }
        public IQueryable<User> GetAllUsersByIds(List<int> ids)
        {
            return _db.Users.Where(c=> ids.Contains(c.Id));
        }

然后您只需通过提供Ids数组的常规AJAX函数调用GetUsers函数(在这种情况下,我使用jQuery stringify将数组作为字符串发送并在控制器中取消实现,但是您可以发送int数组并接收它作为控制器中int的数组)。我使用ASP.NET MVC构建了一个完整的Restful API,该API以跨域json的形式返回数据,并且可以在任何应用程序中使用。如果可以使用ASP.NET MVC,那当然可以。

function GetUsers()
    {
           var link = '<%= ResolveUrl("~")%>users?callback=?';
           var userIds = [];
            $('#multiselect :selected').each(function (i, selected) {
                userIds[i] = $(selected).val();
            });

            $.ajax({
                url: link,
                traditional: true,
                data: { 'userIds': JSON.stringify(userIds) },
                dataType: "jsonp",
                jsonpCallback: "refreshUsers"
            });
    }

3
抱歉,我不是在问如何实现API。我只是在问如何构造API URI,以便客户端可以访问有关用户数组的信息。我可以通过查询参数传递ID,但我相信不会很烦。
uclajatt 2010年

@uclajatt为什么您认为这不是RESTful?
Darrel Miller 2010年

1
我相信通过查询参数传递id或任何其他值的确是一种与系统交互的宁静方法。您如何构造Uri取决于您。无论是用户/全部,用户/数组,数组/用户还是任何其他命名约定,您都认为是有意义的。考虑到MVC框架是如何工作的,很容易使用它来构建一个平稳的API,因为您可以根据需要组织和构建Uris。一旦有了Uris,就可以使用AJAX作为一个字符串传递参数,或作为多个值(如果您使用的是表单并发布到MVC操作中)。
Vasile Laur

1
@uclajatt多数民众赞成在这点上,您曾两次被问到为什么您认为在查询参数中传递逗号分隔的列表不是RESTful的,您甚至都不想回答它,更不用说接受任何这些非常合理的解决方案了! !不酷
samis 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.