Note that there are some explanatory texts on larger screens.

plurals
  1. PORESTful design of a social network
    text
    copied!<p>I'm trying to wrap my head around RESTful design, and I'd like to understand it in terms of a social network. I've read <a href="http://shop.oreilly.com/product/0636920021575.do">REST API Design Rulebook</a>, looked in some other books and read a lot of online resources. Still, when applying the rules to real-world problems I realize that I don't fully understand everything. I want to know if I have the correct understanding of REST by specifying some issues:</p> <h2>Hierarchy vs. flat design</h2> <p>Let's assume that I identify a particular user with</p> <pre><code>/users/42 </code></pre> <p>Now, the photos uploaded by that user would end up in</p> <pre><code>/users/42/photos </code></pre> <p>and if he/she tags his/her friends in the photo those tags would end up in</p> <pre><code>/users/42/photos/1337/tags </code></pre> <p>But this provides no way of finding all photos where a particular user is tagged. Should I come up with a different hierarchy for that? It seems a bit awkward. Am I allowed to completely disregard the hierarchy and provide photos in combination with queries like this?</p> <pre><code>/photos?owner=42 /photos?tagged=42 </code></pre> <h2>Caching when content differs for different users</h2> <p>A Web Service should be designed to provide cacheable data (so that the client could decide to use the local copy, if it thinks that nothing has been changed), but how does that affect the privacy settings for different users? Two users, both logged in, might have the rights to view different information about e.g. user 42. Does that mean that I somehow need to request different URIs for different users accessing the profile information of the same user, or will the caching not be an issue as long as the users provide different credentials?</p> <h2>Providing both HTML and JSON/XML from the same resource</h2> <p>The book I mentioned specifies the rule that an API should be accessible at a subdomain starting with <code>api</code>, in their example <code>http://api.soccer.restapi.org</code>. I had planned to use the same controller for both user access and machine access (for example a mobile app). The controller would decide on which view to provide (<code>text/html</code>, <code>application/json</code> or <code>application/xml</code>) through the <code>Accept</code> field in the HTTP request header. I take it that that would be a bad idea for some reason (since a user would expect to see the subdomain <code>www</code>, not <code>api</code>), but I don't understand why. Can <code>www</code> and <code>api</code> point to the same server, or should I really try to move the HTML view to a different virtual host? Why?</p> <p>I believe Ruby on Rails will (Convention over Configuration) provide both HTML and JSON from the same controller, thus sharing my idea that HTML and JSON are just different representations of the same data.</p> <p>In other words, my book says that a certain resource should have one and only one URI, and that different representations should be provided based on the <code>Accept</code> field. Redirecting the user between different subdomain would violate the rule about providing any representation from the same resource, and duplicating the information (i.e. pointing two subdomains to the same virtual host) violates the rule about not providing multiple URIs for the same resource. Not providing the <code>api</code> subdomain violates yet another design rule. How can I solve this without violating any rule?</p> <h2>Limiting the data sent back</h2> <p>The query component should be used for pagination, but am I allowed to refuse to honor listing requests lacking search criteria and limit the number of items, without violating REST? I want to both reduce the database load and avoid having someone map the entire directory of users. I want</p> <pre><code>/users </code></pre> <p>to be an illegal request, while</p> <pre><code>/users?name=leet+hacker </code></pre> <p>would be valid but only return e.g. 100 items.</p> <p>I also wonder if it's legal to return a subset of the database columns and more/all of them only if they're specifically requested using a query.</p> <h2>Controllers providing redundant data</h2> <p>I believe it's legal to provide a controller like</p> <pre><code>/users/me </code></pre> <p>but should it provide the exact same information as the document URI</p> <pre><code>/users/42 </code></pre> <p>or should it redirect to it?</p> <h2>Extended rights for some users</h2> <p>Which is the RESTful way to provide additional functionality, for example administration rights? I'm now assuming that an administrator (of a photo, of a group of users or of the entire site) will be able to see more information about a particular object than other users. Should that information be kept at exactly the same URI and be sent automatically to the administrator but not to anyone else, should it be stored at a different location, should it be requested using a certain administrator query or provided in some other way?</p> <h2>Localization and settings updates</h2> <p>Although the majority of strings visible to the user should be provided by the view, there are some design decisions that might involve the API. The most obvious are names. Social networks sometimes allow the user to enter different names that are to be displayed in different language contexts. Names in some languages, like Russian and Arabic, are not easily transcribed automatically. In other languages, like Chinese, the local and international names can be completely different, with no resemblance or connection at all. What would be the RESTful way of handling this? I have a feeling that the answer will be the <code>Accept-Language</code> field, but is anyone seriously considering that for switching languages on the social network they belong to? Should all this information be returned to the caller every time, or can I rely on the settings? Will that work with a cache?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload