This is going to be a web service that returns a JSON object. Currently, I'm using C# technology and simply using ASP.Net MVC to create the calls. This is not a web page, so SEO is not a concern.

I've come across a number of instances where I want to get the "next" or "previous" item in a list. For example, I've got a service that returns a featured photo. http://myservice.com/photos/123 which returns a JSON

{"name": "At_The_Concert", "id": "123", "src": "http://myservice.com/photostore/123.jpg"}

The client (Ajax, Mobile device, etc.) of this service wants to know what the “next” item is going to be. I’m struggling about what the url should be.

or maybe the id property should just be a parameter


Or maybe this is entirely wrong and it should be like


though with .Net's routing, it might be easier to write it as http://myservice.com/photos/method/getNextPhoto?photoId=123

I’m relatively new to web services and REST. I get the basic CRUD for REST, but I don’t know what is the best practice for creating more custom urls, in this case the “next” photo. Is there an accepted RESTful practice?

  • the last three are not RESTful they are RPC over HTTP
    – user7519
    Dec 28, 2011 at 21:39
  • That's interesting, because the 2nd to last (?method=) I based off Flickr's REST API.
    – John
    Dec 29, 2011 at 3:25
  • just because they call it REST doesn't mean they got it right
    – user7519
    Dec 29, 2011 at 3:59
  • That is very true.
    – John
    Dec 29, 2011 at 13:02

3 Answers 3


Do it this way:

{"name": "At_The_Concert", "id": "123", "src": "http://myservice.com/photostore/123.jpg",
"next": "http://myservice.com/photos/345/",
"prev": "http://myservice.com/photos/901/"}
  • 1
    +1 for the sane way to do it. Keeps the Prev/Next links 'clean' too. Dec 28, 2011 at 18:51
  • 4
    A cool URL never changes. "myservice.com/photos/123/next" might point to different pictures depending on filter settings or user authorizations or day of week or phase of moon.
    – S.Lott
    Dec 28, 2011 at 18:54
  • But it does change. If I remove photos or add new photos, there will be a different "next" photo.
    – John
    Dec 28, 2011 at 19:22
  • 3
    There will be a different value associated with "next" in the JSON reply. The URL for a given photo never changes. You don't want to have "myservice.com/photos/123/next" and ""myservice.com/photos/345" BOTH point to the same photo. You want "myservice.com/photos/345" to be the one, only and unchanging for photo 345. Since "myservice.com/photos/123/next" is always changing, you simply do not want to ever use it.
    – S.Lott
    Dec 28, 2011 at 19:39
  • I'm thinking that you're right. This was the original path that I went down. I was using a LinkedListNode<T> in the middle tier to generate the data. Everything was nice until I tried to serialize my LinkedListNode and . . . recursion blowup. /next seems like such a nice solution from the middle tier point of view, but alas, it does violate the Thou Shalt Have One Url And Only One Url Commandment.
    – John
    Dec 28, 2011 at 19:58

Having the next function be an operation server-side requires state information, particularly if you are involving filtering. This violates REST.

It seems more appropriate to provide a directory list at http://myservice.com/photos, and let the app call the appropriate http://myserivce.com/photos/id link when hitting next/previous. With this method, the filtering logic would be on the client, and it could be modified/reset without having to call the service again.

Alternatively, you could have request parameters into the http://myservice.com/photos that returns a filtered list. Naturally, this would require additional service calls if the filter changed, so you may wish to stick with the former suggestion.

The end result would be the same, however. Your state would reside where it should - in the client app as opposed to the server.


Another option is to look at OData and Service Operations it will guarantee RESTful style of your calls.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.