Nested REST Routing

2019-08-24 01:51发布

Simple situation: I have a server with thousands of pictures on it. I want to create a restful business layer which will allow me to add tags (categories) to each picture. That's simple. I also want to get lists of pictures that match a single tag. That's simple too. But now I also want to create a method that accepts a list of tags and which will return only pictures that match all these tags. That's a bit more complex, but I can still do that.
The problem is this, however. Say, my rest service is at pictures.example.com, I want to be able to make the following calls:

  • pictures.example.com/Image/{ID} - Should return a specific image
  • pictures.example.com/Images - Should return a list of image IDs.
  • pictures.example.com/Images/{TAG} - Should return a list of image IDs with this tag.
  • pictures.example.com/Images/{TAG}/{TAG} - Should return a list of image IDs with these tags.
  • pictures.example.com/Images/{TAG}/{TAG}/{TAG} - Should return a list of image IDs with these tags.
  • pictures.example.com/Images/{TAG}/{TAG}/{TAG}/{TAG}/{TAG} - Should return a list of image IDs with these tags.
  • etcetera...

So, how do I set up a RESTful web service projects that will allow me to nest tags like this and still be able to read them all? Without any limitations for the number of tags, although the URL length would be a limit. I might want to have up to 30 tags in a selection and I don't want to set up 30 different routing thingies to get it to work. I want one routing thingie that could technically allow unlimited tags.

Yes, I know there could be other ways to send such a list back and forth. Better even, but I want to know if this is possible. And if it's easy to create. So the URL cannot be different from above examples.
Must be simple, I think. Just can't come up with a good solution...

2条回答
你好瞎i
2楼-- · 2019-08-24 02:18

I assume you can figure out how to actually write the SQL or filesystem query to filter by multiple tags. In CherryPy, for example, hooking that up to a URL is as simple as:

class Images:
    @cherrypy.tools.json_out()
    def index(self):
        return [cherrypy.url("/images/" + x.id)
                for x in mylib.images()]
    index.exposed = True

    @cherrypy.tools.json_out()
    def default(self, *tags):
        return [cherrypy.url("/images/" + x.id)
                for x in mylib.images(*tags)]
    default.exposed = True

...where the *tags argument is a tuple of all the /{TAG} path segments the client sends. Other web frameworks will have similar options.

查看更多
爱情/是我丢掉的垃圾
3楼-- · 2019-08-24 02:42

The URL structure you choose should be based on whatever is easy to implement with your web framework. I would expect something like:

http://pictures.example.com/images?tags=tag1,tag2,tag3,tag4

Is going to be much easier to handle on the server, and I can see no advantage to the path segment approach that you are having trouble with.

查看更多
登录 后发表回答