|
Hi Dan, Sounds like we are making good progress and you've done lost of great work. I've divided my response in sections to make it easier to follow. ==== Syntax ========== The currently proposed syntax is: resource :collection do |r|
r.post do end end Where 'r' is an instance of a Resource class. At first I preferred a simpler syntax, like this: resource :collection do method.post do end end Where method represents the HTTP verb (GET, POST, PUT)? Or maybe even: resource :collection do request.post? do end end However, do you have to have an instance of the resource class to achieve the 4 points you brought up (more details in original email): 1. Handling OPTIONS requests. 2. Returning 405 when appropriate 3. Return 501 when appropriate 4. Checking If-* request These all would be good features to have. If they require having a resource class passed as "r" then I can agree to this approach. ==== Templates ========== You mentioned that you'd expect these responses for different methods: GET - 200 OK - Response Body POST - 303 See Other - No Response Body, Location header to newly created resource PUT - 303 See Other - No Response Body, Location header to resource DELETE - 303 See Other - No Response Body, Location header to collection resource Using regular HTML forms I'd agree. However, this breaks down when using XmlHttpRequest. For example, if I do a post and it fails and I want to return an error message. Doing a redirect is a bit silly since the URL in the browser address bar isn't going to change anyway - its easier to just return the result from the POST. Same is true for a PUT, whether an update is successful or not. Thus, I think we must provide a system where you can provide a response body regardless of the method. One approach is Peter's proposal of just using a standardized directory structure: view my_controller resource1 get put resource2 post delete I like this concept. However, maybe it would be confusing since Rails uses directories for nested classes (MyNamespace::MySubNamespace::MyController). Thus, we could go use the name mangling I currently do now, i.e., get_resource1, or resource1_get (which I like better because it groups the templates for a resource together a bit more clearly). ==== Editors ========== We seem to be in complete agreement. I.E: /book/1 - Viewable representation of book #1 retrieved by GET /book/1/editor - Editable representation of book #1, will PUT to /book/1 /book/creator - Form to create a new book, will POST to /book ==== Top Level Resources ========== Here is something Peter and I disagree about. Do you prefer this style: def MyController resource :collection do |r| ... end resource :member do |r| ... end resource :editor do |r| ... end end Or this: def MyController r.get ... end r.post ... end resource :member do |r| ... end resource :editor do |r| ... end end The difference being in the first case you insist every resource must be defined via "resource" while in the second you say that the controller is the top level resource. When I first did my RestController I went with option #1 because it seemed more elegant. However, I quickly changed my mind when actually writing code because it turned out to be annoying having to add the extra syntax. This was particularly true for controllers that are just single resources. For example, say you have geocoding functionality so you have a GeocoderController. It does just one thing, GETs geocoding results so there is no concept of collection/member. Thus I favor option #2 as a syntax shortcut. ==== Caching ========== Sounds like we've agreed that caching is important, but is not part of the Rest Controller. Thus, you'll split that off the caching functionality into another plugin that can work with a Rest Controller. ==== Implementation ========== I see that your implementation is significantly different than mine. I map :resource to a Ruby module, which gets included in a controller. In contrast, you map :resource to a Ruby method. Within that method you create an instance of a Ruby class called Resource and then execute the provided block in its context. This disadvantage of my approach is that there is method renaming that goes on under the scenes, which you have to know about in order to get filters to work correctly. The disadvantage I see to your implementation is that all the methods for a resource get mapped under a single Ruby method. It seems that would make it hard to apply filters to specific methods. I.E., how could I apply a filter to a GET method of the resource Member but not to the POST? It would be great if we could use the existing filter syntax without change, but I'm guessing that might not be reasonable because now we are dealing with Resources and Methods as opposed to Actions. Anyway, this is something I think is important to solve. Also, how does your Rest controller interact with the base ActionController? I'm not seeing it being include anywhere...could you point me to the appropriate code. Last, it would be good to have an example controller for people to play with. Something simple, like a ProductController or mabye copying one of the examples from the Agile Web Development book. Thanks, Charlie |
smime.p7s
Description: S/MIME Cryptographic Signature
_______________________________________________ microformats-rest mailing list [email protected] http://microformats.org/mailman/listinfo/microformats-rest
