Loading ...
Sorry, an error occurred while loading the content.

Rails RESTful?

Expand Messages
  • Stefan Tilkov
    The current edge (SVN) version of the Ruby on Rails framework contains support for RESTful controllers (or so it claims). I d be very interested in opinions
    Message 1 of 14 , Nov 13, 2006
    • 0 Attachment
      The current "edge" (SVN) version of the Ruby on Rails framework
      contains support for RESTful controllers (or so it claims).
      I'd be very interested in opinions about how RESTful this is in the
      group's opinion.

      Without going into detail, this means that if you set up a default
      route like this

      map.resources :employees

      the result is a set of routing rules like this

      GET /employees/
      {:action=>"index", :controller=>"employees"}
      GET /employees.:format/
      {:action=>"index", :controller=>"employees"}
      POST /employees/
      {:action=>"create", :controller=>"employees"}
      POST /employees.:format/
      {:action=>"create", :controller=>"employees"}
      GET /employees/new/
      {:action=>"new", :controller=>"employees"}
      GET /employees/new.:format/
      {:action=>"new", :controller=>"employees"}
      GET /employees/:id;edit/
      {:action=>"edit", :controller=>"employees"}
      GET /employees/:id.:format;edit/
      {:action=>"edit", :controller=>"employees"}
      GET /employees/:id/
      {:action=>"show", :controller=>"employees"}
      GET /employees/:id.:format/
      {:action=>"show", :controller=>"employees"}
      PUT /employees/:id/
      {:action=>"update", :controller=>"employees"}
      PUT /employees/:id.:format/
      {:action=>"update", :controller=>"employees"}
      DELETE /employees/:id/
      {:action=>"destroy", :controller=>"employees"}
      DELETE /employees/:id.:format/
      {:action=>"destroy", :controller=>"employees"}

      In other words, replacing :id, :format with values of your choice,
      this yields

      (1) GET /employees/
      returns a list of employees in the default "format" (i.e., in HTML)

      (2) GET /employees.:format/
      (for example, GET /employees.xml) gets an XML representation (an HTTP
      Accept header can be used instead)

      (3) POST /employees/
      POSTs form-encoded values, creates a new employee and returns its URL

      (4) POST /employees.:format/
      similar to (3), with another format

      (5) GET /employees/new/
      returns an HTML form for creating a new employee, with the action URL
      set to /employees and the method set to POST

      (6) GET /employees/new.:format/
      by default, does nothing

      (7) GET /employees/:id;edit/
      returns an HTML form for editing the employee at /employees/...,
      action URL set to the /employees/... URI, with a hidden field _method
      set to PUT (the server routes a submit to the same method as (11)

      (8) GET /employees/:id.:format;edit/
      by default, does nothing

      (9) GET /employees/:id/
      returns the HTML representation of the employee

      (10) GET /employees/:id.:format/
      returns the :format representation of the employee

      (11) PUT /employees/:id/
      {:action=>"update", :controller=>"employees"}
      updates the employee using HTML form encoded data

      (12) PUT /employees/:id.:format/
      {:action=>"update", :controller=>"employees"}
      updates the employee using another format

      (13) DELETE /employees/:id/
      {:action=>"destroy", :controller=>"employees"}

      (14) DELETE /employees/:id.:format/
      {:action=>"destroy", :controller=>"employees"}
      maps to the same action as (13)

      IMHO, both the hidden _method field (to get around the missing PUT
      and DELETE support and browsers), as well as the .format URL suffix
      are pretty ugly, but I can perfectly understand why they are there
      and don't see any obvious improvement. I'm not sure at all about the
      "new" URL (5) and the ";edit" suffix (8).

      Thanks,
      Stefan
      --
      Stefan Tilkov, http://www.innoq.com/blog/st/
    • Nic James Ferrier
      ... Seems like a good convention. ... Very reasonable. I couldn t persuade the mod_python people that they needed to support PUT for FORM data. All in all it
      Message 2 of 14 , Nov 13, 2006
      • 0 Attachment
        Stefan Tilkov <stefan.tilkov@...> writes:

        > (5) GET /employees/new/
        > returns an HTML form for creating a new employee, with the action URL
        > set to /employees and the method set to POST

        Seems like a good convention.

        > (11) PUT /employees/:id/
        > {:action=>"update", :controller=>"employees"}
        > updates the employee using HTML form encoded data
        >
        > (12) PUT /employees/:id.:format/
        > {:action=>"update", :controller=>"employees"}
        > updates the employee using another format

        Very reasonable. I couldn't persuade the mod_python people that they
        needed to support PUT for FORM data.


        All in all it looks good. Better than it was anyway.

        --
        Nic Ferrier
        http://www.tapsellferrier.co.uk for all your tapsell ferrier needs
      • Bill de hOra
        ... It looks way better than it used to be. This would be cool: (5) GET /employees/{key} Fwiw, I don t like the way rails exposes pks in URLs, so {key}
        Message 3 of 14 , Nov 13, 2006
        • 0 Attachment
          Stefan Tilkov wrote:
          > The current "edge" (SVN) version of the Ruby on Rails framework contains
          > support for RESTful controllers (or so it claims).
          > I'd be very interested in opinions about how RESTful this is in the
          > group's opinion.

          It looks way better than it used to be. This would be cool:

          (5) GET /employees/{key}

          Fwiw, I don't like the way rails exposes pks in URLs, so {key} above
          would be any identifier that can survives a db wreck. If you don't use
          the db pk generator, it means you don't need to create an employee
          object speculatively while providing a unique URL - for example,
          premature object creation is a problem with Plone's portal_factory that
          means you can't sanely use GET to serve the creation form. Above idiom
          can also help deal with double posting.

          cheers
          Bill
        • Mike Schinkel
          ... STRONGLY AGREE!!! I like the way WordPress uses slugs instead (but I hate the name slug! ) -Mike Schinkel http://www.mikeschinkel.com/blogs/
          Message 4 of 14 , Nov 13, 2006
          • 0 Attachment
            Bill de hOra wrote:
            >> Fwiw, I
            don't like the way rails exposes pks in URLs, so {key} 
            >> above would be any identifier that can survives a db wreck.
             
            STRONGLY AGREE!!!  I like the way WordPress uses "slugs" instead (but I hate the name "slug!")
             
             
          • Ryan Tomayko
            ... I m running quite a bit on edge rails but haven t had a chance to take a deep look into the enhancements. I m encouraged by what I have seen. The routing
            Message 5 of 14 , Nov 13, 2006
            • 0 Attachment
              Stefan Tilkov wrote:
              > The current "edge" (SVN) version of the Ruby on Rails framework
              > contains support for RESTful controllers (or so it claims).
              > I'd be very interested in opinions about how RESTful this is in the
              > group's opinion.

              I'm running quite a bit on edge rails but haven't had a chance to take a deep
              look into the enhancements. I'm encouraged by what I have seen. The routing
              DSL is now oriented toward creating multi-verb resources, there seems to be good
              support for content negotiation, and I believe they're experimenting with
              best-practices for making forms more RESTful using XmlHttpRequest with
              fall-backs for legacy browsers.

              I was able to hack Rails' front-end stuff to be RESTful enough for my needs a
              long time ago and just haven't had a chance to migrate to the new stuff on
              edge. The 1.2 release is nearing and I expect we'll see the first real
              wave of documentation on REST related enhancements included; it seems to be
              one of the major additions for this release.

              I've also been planning on putting an article together on how well Rails,
              Django, and TurboGears support concepts that ought to be provided by a modern
              high-level HTTP framework. For an idea of what I'd like to look at
              specifically, see the section "To Hell With Bad Web Frameworks" in:

              http://naeblis.cx/articles/2005/04/22/on-http-abuse

              I'd like to elaborate on each of the bullets and try to evaluate how well
              each of the aforementioned frameworks stack up.

              I've had good conversations specifically related to REST and HTTP with both
              David Hansson (Rails) and Adrian Holovaty (Django). In general, I feel pretty
              good about the direction and leadership behind each of these environments, even
              if the current state of these implementations aren't quite up to snuff.

              --
              Ryan Tomayko
              http://naeblis.cx/
            • Ryan Tomayko
              ... You can use slugs just as easily as you can use surrogate integer keys in Rails. The integer PK is used by default when new models and controllers are
              Message 6 of 14 , Nov 13, 2006
              • 0 Attachment
                Mike Schinkel wrote:
                > Bill de hOra wrote:
                > >> Fwiw, I don't like the way rails exposes pks in URLs, so {key}
                > >> above would be any identifier that can survives a db wreck.
                >
                > STRONGLY AGREE!!! I like the way WordPress uses "slugs" instead (but I hate
                > the name "slug!")

                You can use slugs just as easily as you can use surrogate integer keys in
                Rails. The integer PK is used by default when new models and controllers are
                generated because the integer PK is the only unique identifier we can make
                assumptions about. But if your model has a slug attribute, using it instead
                of the PK for generated URLs and routing is usually as easy as overriding
                ActiveRecord::Base##to_param:

                class Foo < ActiveRecord::Base
                def to_param
                slug
                end
                end

                You may also have to tweak your controller:

                class FoosController < ActionController::Base
                def show
                # the following resembles what is generated by default:
                @foo = Foo.find(params[:id])
                # change it to this:
                @foo = Foo.find_by_slug(params[:id])
                end
                end

                Most everything else should be taken care of. Using the `url_for` and
                `link_to` helper methods should automatically use the slug instead of the
                integer PK and routing should Just Work as well.

                It's swell.

                I've had more trouble trying to create sane slugs for my models than I have
                getting Rails to use them. In fact, I tend to just use the integer PK in all
                but the most highly trafficked areas of an applications because slugification
                can be a bit of a PITA. It can help URIs stay cool, though, so I try to use
                them when that's important.

                --
                Ryan Tomayko
                http://naeblis.cx/
              • Mike Schinkel
                ... Actually, it is no where near as easy. The default generates code that you have to manually modify and maintain which is a lot of work for a large system.
                Message 7 of 14 , Nov 13, 2006
                • 0 Attachment
                  Ryan Tomayko said:
                   
                  >> You can use
                  slugs just as easily as you can use surrogate
                  >> integer keys in
                  Rails. You can use slugs just as easily as
                  >> you can use
                  surrogate integer keys in Rails. The integer PK
                  >> is used by
                  default when new models and controllers are
                  >> generated because the
                  integer PK is the only unique identifier
                  >> we can make
                  assumptions about. But if your model has a
                  >> slug attribute,
                  using it instead of the PK for generated URLs
                  >> and routing is
                  usually as easy as overriding
                  >>
                  ActiveRecord: :Base##to_ param:
                   
                  Actually, it is no where near as easy.  The default generates code that you have to manually modify and maintain which is a lot of work for a large system. If I could configure how it generated the code (which, btw, I see code generation as a real downside to the RoR architecture[1]) then I'd agree it would be (almost) as easy; you still have to custom configure the routing.
                   
                  Additionally, I tried for several days to get a system working with URLs modeled like I wanted using Rails, and I finally put it aside rather frustrated with a plan to one day get back to it. 
                   
                  BTW, RoR *could* make assumptions about a "slug" fields if chosen to do so.
                   
                  -Mike Schinkel

                  http://www.mikeschinkel.com/blogs/
                  http://www.welldesignedurls.org/
                  P.S. If it really is that easy, maybe you'll want to help me with it off-list? If so, then maybe I'll come back here and beg for mea cupla. ;-)
                   
                  [1] I can explain this off list if you care.
                • Ryan Tomayko
                  ... I m not sure what you re referring to here. The alternative to generating that code is hand-coding the exact same code, which is a fine option too. The
                  Message 8 of 14 , Nov 14, 2006
                  • 0 Attachment
                    Mike Schinkel wrote:
                    > Actually, it is no where near as easy. The default generates code that you
                    > have to manually modify and maintain which is a lot of work for a large
                    > system.

                    I'm not sure what you're referring to here. The alternative to generating
                    that code is hand-coding the exact same code, which is a fine option too. The
                    code is generated once when you create the controller or model and then you
                    own it. How does this code generation cause any harm? I did my time back in
                    the day writing Windows apps with MFC and ATL so I know what bad code
                    generation looks like :)

                    > P.S. If it really is that easy, maybe you'll want to help me with it
                    > off-list? If so, then maybe I'll come back here and beg for mea cupla. ;-)

                    Feel free.

                    --
                    Ryan Tomayko
                    http://naeblis.cx/
                  • Bill de hOra
                    ... Django has a SlugField type that can be autopopulated from other fields on creation. It wouldn t be so hard to clone for Rails... cheers Bill
                    Message 9 of 14 , Nov 14, 2006
                    • 0 Attachment
                      Ryan Tomayko wrote:

                      >
                      > I've had more trouble trying to create sane slugs for my models than I have
                      > getting Rails to use them. In fact, I tend to just use the integer PK in all
                      > but the most highly trafficked areas of an applications because
                      > slugification
                      > can be a bit of a PITA. It can help URIs stay cool, though, so I try to use
                      > them when that's important.

                      Django has a SlugField type that can be autopopulated from other fields
                      on creation. It wouldn't be so hard to clone for Rails...

                      cheers
                      Bill
                    • Stefan Tilkov
                      Point taken, but that doesn t seem to be related to REST, more towards got (or bad) implementation practice. (I don t really mind, as long as the framework
                      Message 10 of 14 , Nov 14, 2006
                      • 0 Attachment
                        Point taken, but that doesn't seem to be related to REST, more
                        towards got (or bad) implementation practice.

                        (I don't really mind, as long as the framework does not force me to
                        accept this as the only possible convention, just as the default one.)

                        Stefan
                        --
                        Stefan Tilkov, http://www.innoq.com/blog/st/


                        On Nov 14, 2006, at 2:12 AM, Bill de hOra wrote:

                        > Stefan Tilkov wrote:
                        > > The current "edge" (SVN) version of the Ruby on Rails framework
                        > contains
                        > > support for RESTful controllers (or so it claims).
                        > > I'd be very interested in opinions about how RESTful this is in the
                        > > group's opinion.
                        >
                        > It looks way better than it used to be. This would be cool:
                        >
                        > (5) GET /employees/{key}
                        >
                        > Fwiw, I don't like the way rails exposes pks in URLs, so {key} above
                        > would be any identifier that can survives a db wreck. If you don't use
                        > the db pk generator, it means you don't need to create an employee
                        > object speculatively while providing a unique URL - for example,
                        > premature object creation is a problem with Plone's portal_factory
                        > that
                        > means you can't sanely use GET to serve the creation form. Above idiom
                        > can also help deal with double posting.
                        >
                        > cheers
                        > Bill
                        >
                        >
                        >
                      • Mike Schinkel
                        ... that code is hand-coding the exact same code, which is a fine option too. Not true. There are at least two other alternates (one of which is code
                        Message 11 of 14 , Nov 15, 2006
                        • 0 Attachment
                          >> I'm not sure what you're referring to here. The alternative to generating
                          that code is hand-coding the exact same code, which is a fine option too.

                          Not true. There are at least two other alternates (one of which is code
                          generation, but in a confined context):

                          1.) But the logic into the object and process metadata. Slower and coding
                          is more abstract, but the code is in the framework. Also, not as flexible
                          as code that is generated which can then be hand modified. Good for certain
                          types of functionality.

                          2.) Do "behind the scenes" code generation. Don't require developer to
                          generate standard code. Instead, generate it on demand behind the scenes.
                          This approach forces a discipline to architecture that I think is
                          preferrable.

                          >> The code is generated once when you create the controller or model and
                          then you own it.

                          Unless I start refactoring...

                          >> How does this code generation cause any harm?

                          You can't round-trip the generated code during refactoring and if you regen,
                          you can loose modifications.

                          >> Feel free.

                          Thanks. I'll email offline.

                          -Mike Schinkel
                          http://www.mikeschinkel.com/blogs/
                          http://www.welldesignedurls.org/



                          -----Original Message-----
                          From: Ryan Tomayko [mailto:rtomayko@...]
                          Sent: Tuesday, November 14, 2006 11:16 AM
                          To: Mike Schinkel
                          Cc: rest-discuss@yahoogroups.com
                          Subject: Re: [rest-discuss] Rails RESTful?

                          Mike Schinkel wrote:
                          > Actually, it is no where near as easy. The default generates code
                          > that you have to manually modify and maintain which is a lot of work
                          > for a large system.

                          I'm not sure what you're referring to here. The alternative to generating
                          that code is hand-coding the exact same code, which is a fine option too.
                          The code is generated once when you create the controller or model and then
                          you own it. How does this code generation cause any harm? I did my time back
                          in the day writing Windows apps with MFC and ATL so I know what bad code
                          generation looks like :)

                          > P.S. If it really is that easy, maybe you'll want to help me with it
                          > off-list? If so, then maybe I'll come back here and beg for mea cupla.
                          > ;-)

                          Feel free.

                          --
                          Ryan Tomayko
                          http://naeblis.cx/
                        • Ryan Tomayko
                          Looks like the first round of information on Rails s enhancements are coming out: http://weblog.rubyonrails.com/2006/11/23/rails-1-2-release-candidate-1 I
                          Message 12 of 14 , Nov 23, 2006
                          • 0 Attachment
                            Looks like the first round of information on Rails's enhancements are
                            coming out:

                            http://weblog.rubyonrails.com/2006/11/23/rails-1-2-release-candidate-1

                            I still haven't had a chance to look into any of this but I'm starting
                            to get excited :)

                            --
                            Ryan Tomayko
                            http://naeblis.cx/
                          • David Heinemeier Hansson
                            ... Thanks, Ryan. We ve definitely drunk the kool-aid at this point. Building resource-oriented applications will be the Rails default before too long. By
                            Message 13 of 14 , Nov 27, 2006
                            • 0 Attachment
                              > Looks like the first round of information on Rails's enhancements are
                              > coming out:
                              >
                              > http://weblog.rubyonrails.com/2006/11/23/rails-1-2-release-candidate-1
                              >
                              > I still haven't had a chance to look into any of this but I'm starting
                              > to get excited :)

                              Thanks, Ryan. We've definitely drunk the kool-aid at this point.
                              Building resource-oriented applications will be the Rails default
                              before too long. By Rails 2.0, we'll have the new scaffold_resource be
                              the default scaffolder. Indoctrinate good RESTful practices to people
                              even before they know or care as to why it matters.

                              So I'm eager to hear more from you guys here on what we could do
                              better. Another neat short-cut we recently added is the head command,
                              used like this:

                              respond_to do |format|
                              format.html { redirect_to post_url(post) }
                              format.xml { head :created, :location => post_url(post) }
                              end

                              When making a XML request, you'll get a 201 Created with the URL for
                              the new resource in the Location header. And of course no content is
                              being returned.
                              --
                              David Heinemeier Hansson
                              http://www.loudthinking.com -- Broadcasting Brain
                              http://www.basecamphq.com -- Online project management
                              http://www.backpackit.com -- Personal information manager
                              http://www.rubyonrails.com -- Web-application framework
                            • Mike Schinkel
                              ... Have you considered supporting the new URI Template[1] format for URL configuration? -Mike Schinkel http://www.mikeschinkel.com/blogs/
                              Message 14 of 14 , Nov 30, 2006
                              • 0 Attachment
                                David:

                                >> Thanks, Ryan. We've definitely drunk the kool-aid at this point.
                                >> Building resource-oriented applications will be the Rails default
                                >> before too long. By Rails 2.0, we'll have the new scaffold_resource be
                                >> the default scaffolder. Indoctrinate good RESTful practices to people
                                >> even before they know or care as to why it matters.

                                Have you considered supporting the new URI Template[1] format for URL
                                configuration?


                                -Mike Schinkel
                                http://www.mikeschinkel.com/blogs/
                                http://www.welldesignedurls.org/

                                [1] http://www.ietf.org/internet-drafts/draft-gregorio-uritemplate-00.txt
                              Your message has been successfully submitted and would be delivered to recipients shortly.