39

Possible Duplicate:
Rails 3 Custom Route that takes multiple ids as a parameter

From what I understand, a good REST URL for getting a resource would look like this:

/resource/{id}

The problem I have is, that I often need to get a large number of resources at the same time and do not want to make a separate HTTP call for each one of them.

Is there a neat URL design that would cater for that or is this just not suitable for a REST API?

Community
  • 1
  • 1
George
  • 3,433
  • 4
  • 27
  • 25
  • Can I ask why you want to get a large number of resources at the same time? Is it because you want to render a set of resources to the user, or you want to perform some process on those all of those resources? – Darrel Miller Jun 09 '09 at 12:51
  • Yes, I need a number of things to show to the user. Say, their last thirty purchases, or anything along those lines, each one of them identifiable by its own URI. – George Jun 09 '09 at 14:36
  • 6
    -1. REST has nothing to do with URL naming conventions. A "good REST URL" is nonsense and suggests that you misunderstand REST architecture. – aehlke Jul 22 '09 at 19:57
  • 12
    Not a dupe. This is about designing URL naming conventions. Other is about how to implement one in Rails. – Mechanical snail Aug 06 '12 at 05:05
  • 5
    @aehlke Though the REST architecture as presented by Fielding does not talk about URL naming conventions, I do not think that "good REST URL" is nonsense. It definitely makes sense to design URLs that are clean and convey the intent. – Suhas Oct 04 '12 at 09:38
  • 1
    @Suhas you're right, and I was too harsh, but the question reveals a fundamental misunderstanding about REST. – aehlke Oct 04 '12 at 18:02
  • 8
    @aehlke Even if it does reveal a misunderstanding of REST, that makes it a good opportunity to post an answer that explains why REST is agnostic to identifier syntax, which is valuable to the asker and to anyone who finds this page. Far from a reason to reprimand someone for asking it. – Jordan Apr 30 '13 at 03:29
  • @Jordan Indeed, I'm far less hostile about REST these days ;) – aehlke May 06 '13 at 16:50
  • Related: https://stackoverflow.com/questions/9371195/rest-api-requesting-multiple-resources-in-a-single-get – dskrvk Oct 18 '16 at 15:55

4 Answers4

33

Based on your response, the answer to your question is to create a new resource that contains that single set of information. e.g.

GET /Customer/1212/RecentPurchases

Creating composite urls that have many identifiers in a single url limits the benefits of caches and adds unnecessary complexity to the server and client. When you load a web page that has a bunch of graphics, you don't see

GET /MyPage/image1.jpg;image2.jpg;image3.jpg

It just isn't worth the hassle.

Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
  • This is the way to go. You could use the query string along with a collection, but in this case it would be better to specify some meta-data than a list of ids for example: /Customer/1212/Purchases?limit=30&order=date_desc – rojoca Jun 09 '09 at 21:37
  • 1
    This seems to be the way to go.... However, it kind of raises the same question in a different form. What happens when I get all the product ids for the recent purchases back and need to get more information about them (name, picture) from somewhere else that only knows about products? How do I design the api for that? – George Jun 10 '09 at 10:04
  • 4
    You give a link to that resource, not an id. So in your RecentPurchases resource, you return And you let the client follow the links – SerialSeb Jun 10 '09 at 15:44
3

I'd say /resources/foo,bar,baz (separator may vary depending on IDs' nature and your aesthetic preferences, "foo+bar+baz", "foo:bar:baz", etc.). Looks a bit "semantically" neater than foo/bar/baz ("baz of bar of foo"?)

If resource IDs are numeric, maybe, even with a range shortcut like /resources/1,3,5-9,12

Or, if you need to query not exactly on resources with specifical IDs, but on group of resources having specific properties, maybe something like /resources/state=complete/size>1GiB/!active/...

drdaeman
  • 11,159
  • 7
  • 59
  • 104
  • 2
    feels very unrestful to me, to do it this way. At the very least define a new resource name scope, eg "range" that supports this. – Cheeso Jun 09 '09 at 15:36
1

I ahve used in the past something like this.

/resources/a/d/

and that would return between x and Y a list.

something like

<resources>
  <resource>a</resource>
  <resource>b</resource>
  <resource>c</resource>
  <resource>d</resource>
</resources>

you could also put more advanced searches into the URL dpending on what resource actuall is.

Bluephlame
  • 3,901
  • 4
  • 35
  • 51
0

maybe you could try with

[GET]/purchases/user:123;limit:30;sort_date:DESC