Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best design for a RESTful URI with multiple mandatory parameters?

I'm looking to see if more of the seasoned web service veterans can comment on the best way to design a RESTful URI in where I need mandatory parameters. Case in point, I'd like to design an URI that requests data:

example.com/request/distribution

However, from my understanding is that the approach is that more data should return at the higher levels while more detailed data would be returned if applying more specific URI keywords but in my case, I need at least 3 values for that to happen. Those 3 values would be a date value, an account value and proprietary distribution code values. For example:

example.com/request/distribution?acct=123&date=20030102&distcode=1A;1B;1C

Is that considered an "RESTful" URL or is there a better approach that would make more sense? Any input is greatly appreciated.

BTW, Python is the language of choice. Thanks!

like image 720
Carlos Avatar asked Jul 08 '12 20:07

Carlos


2 Answers

URI's cannot, by definition, be "unRESTful" of themselves because the URI specification was guided by the REST architectural style. How you use a URI can violate the REST style by:

  1. Not following the "client-server" constraint; for example, by using WebSockets to implement server push.
  2. Not following the "identification of resources" constraint; for example, using a portion of the URI to specify control data or resource metadata rather than stick to identifying a resource, or by identifying resource via some mechanism other than the URI (like session state or other out-of-band mechanisms).
  3. Not following the "manipulation of resources through representations" constraint; for example, by using the querystring portion of a URI to transfer state.
  4. Not following the "self-descriptive messages" constraint; for example, using HTTP GET to modify state, or transferring JSON with a Content-Type of "text/html".
  5. Not following the "hypermedia as the engine of application state" constraint; for example, not providing the user agent hyperlinks to follow, but instead assuming it will construct them using out-of-band knowledge.
  6. Not following the "layered system" constraint, by requiring the client to know details about the innards of how the server works (especially requiring the client to provide them in a request).

None of the above are necessarily bad choices. They might be the best choice for your system because they foster certain architectural properties (such as efficiency or security) . They're just not part of the REST style.

The fact that your resource is identified by multiple mandatory segments is part and parcel of the design of URI's. As Anton points out, the choice between example.com/request/distribution?acct=123&date=20030102&distcode=1A;1B;1C and, say, example.com/accounts/123/distributions/20030102/1A;1B;1C is purely one of data design, and not a concern at the URI layer itself. There is nothing wrong, for example, with responding to a PUT, POST, or DELETE request to the former. A client which failed to follow a link to either one would be considered broken. A system which expected either one to be made available to the client by some means other than a hypermedia response would be considered "unRESTful".

like image 111
fumanchu Avatar answered Nov 03 '22 04:11

fumanchu


It's better to go about creating RESTful API in terms of resources first, not URIs. It has more to do with your data design than, say, with your language of choice.

E.g., you have a Distribution resource. You want to represent it in your web-based API, so it needs to have an appropriate unique resource identifier (URI). It should be simple, readable, and unlikely to change. This would be a decent example:

http://example.com/api/distribution/<some_unique_id>

Think twice before putting more things and hierarchy into your URIs.

You don't want to change your URIs as your data model or authentication scheme evolve. Changing URIs is uncool and pain for you and developers that use your API. So, if you need to pass authentication to the back-end, you probably should use GET parameters or HTTP headers (AWS S3 API, for example, allows both).

Putting too much into GET parameters (e.g., http://example.com/api/distribution/?id=<some_unique_id>) may seem like a bad idea, but IMO it doesn't really matter[0]—as long as you keep your API documentation accessible and up-to-date.

[0] Update: For read-only APIs, at least. For CRUD APIs, as @daniel has pointed out, it's more convenient when you have endpoints like in the first example above. That way you can nicely use HTTP methods by enabling GET, PUT, DELETE for individual resources at /api/distribution/<id>, and POST to /api/distribution to create new distributions.

While researching the answer, found a nice presentation about RESTful APIs: Designing HTTP Interfaces and RESTful Web Services.

like image 22
Anton Strogonoff Avatar answered Nov 03 '22 04:11

Anton Strogonoff