Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rails: The Next Five Years

Rails: The Next Five Years

When Ruby on Rails burst onto the scene in 2004, it excited web developers by showing that you could build next generation apps quickly and efficiently. Rails was one of the first frameworks to embrace Ajax, giving everyone the power to do partial page updates and whiz-bang effects in a conventional, effortless way.

In 2007, the Rails team embraced RESTful conventions, making API development a no-brainer for new applications. Because RESTful JSON is so easy in Rails, Rails applications tend to implement APIs on balance.

Then it was time to polish. Both the 2.0 and 3.0 releases cleaned up the code-base and found ways to take emerging conventions and make them easier to use.

But now, like in 2004, another revolution is brewing. Increasingly, developers are moving their view layer from the server into the client, using RESTful JSON and client-side templating to increase responsiveness and bring applicable aspects of desktop applications to the web.

Like last time, not every application needs to jump head-first into this new world. But just as in 2004, Rails has an opportunity to embrace the future, and bring its ruthless insistence on convention over configuration to bear on this problem.

Rails already has the plumbing to be a fantastic conventional JSON server. The question is: will we take the challenge, or will we desperately cling to the past, hoping that the future will never come?

428167a3ec72235ba971162924492609?s=128

Yehuda Katz

April 30, 2012
Tweet

Transcript

  1. The Next Five Years RAILS

  2. THE LAST FIVE YEARS

  3. WHY DO WE LIKE RAILS?

  4. "CONVENTION OVER CONFIGURATION"

  5. TRIVIAL CHOICES. When we say "convention over configuration", we mostly

    mean eliminating trivial choices.
  6. ▪ Naming ▪ Asset compilation ▪ To test or not

    to test ▪ Routing HTTP to controllers ▪ File structure and architecture TRIVIAL CHOICES.
  7. MORE COMMON CONCERNS REQUIRE FEWER DECISIONS.

  8. Rails takes a very hard line on conventions, which forces

    us to solve problems very completely. There's little room for us to punt problems onto Rails users.
  9. CSRF PROTECTION

  10. 100% MANUAL.

  11. <form action="/cash_transfer"> {% csrf_token %} SEMIAUTOMATIC.

  12. <%= form_for @cash_transfer do |f| %> <%= f.text_field :from %>

    <%= f.text_field :to %> <%= f.text_field :amount %> <%= button "Transfer!" %> <% end %> Enter Text here AUTOMATIC.
  13. Cognitive Overhead Conventions Tools Hand-Rolled Conventions allow you to avoid

    thinking about the problem at all while working on features. Tools make the problem easier to solve, but still make you think about it. When we don't have a convention for something, we end up forcing the developer to learn about the problem and choose a solution, which is most of the cognitive overhead of solving it yourself.
  14. The common conventions of Rails applications provide a foundation for

    additional abstractions.
  15. COURSE CORRECTIONS No interest in cosmetic, no time for refactoring.

    Interested in figuring out why my clients don't want me to use Rails.
  16. MANY PEOPLE HAVE A PROBLEM. Criteria for course corrections

  17. MANY PARTS OF THE SOLUTION ARE TRIVIAL. REST: What HTTP

    structure should I use? What names should I give my methods? How should I generate URLs?
  18. THERE IS BENEFIT IN A SHARED SOLUTION. Asset pipeline: *

    Works out of the box * Reduces cost of entering a project * Concept of "Rails asset processor"
  19. LEARNING ABOUT THE PROBLEM IS HARD. Encodings, Security, ETags

  20. FAILURE TO SOLVE IN RAILS CORE. What are the problems

    for failing to provide solutions in Rails core. Flip side of what I just said.
  21. CRITICAL MASS. Having multiple competing solutions robs any one solution

    of the critical mass it needs to rapidly improve. No initial implementation is perfect, and Rails provides eyeballs and hands.
  22. USAGE. It's tempting to say "let this feature be a

    plugin, and we'll let our users flesh it out before we include it" This often results in several competing solutions, each languishing with few users, all of which have major issues. The lack of usage can also hide conceptual problems with an approach (heroku deployment?)
  23. INTEGRATION. When users pick a solution on their own, they

    are willing to put up with a lot of manual work. The process of integrating a feature into Rails to automate it often brings fundamental problems to light.
  24. ECHO CHAMBER. The people most likely to choose a plugin

    solution to a problem also understand it the most. This means that there is little impetus to provide completely transparent solutions that work without complete (or any) knowledge of the underlying problems. By making something a Rails concern, it immediately busts the echo chamber of those who already understand the problem.
  25. TECHNICAL DEBT. As Aaron said yesterday, when solving these larger

    issues, we have a larger tolerance for technical debt. That said, we shouldn't throw caution to the wind and take on unlimited debt. At this point, we're still paying back our last emergency loan, so let's be more prudent now.
  26. GOOD ARCHITECTURE ENABLES FUTURE FEATURES. Architecting well means that we

    can easily improve the feature in the future. Many of the good things in the Rails 3 architecture (notifications) have only come to fruition now.
  27. FEATURES NOW + FEATURES LATER COST NOW + MAINTENANCE ÷

  28. FEATURES NOW + FEATURES LATER COST NOW + MAINTENANCE ÷

    Building a feature right lets us extend it easily in the future with lower maintenance costs. This allows us to make necessary investments more easily in the future.
  29. BETS When we correct course, we are placing a bet

    about the future of our industry.
  30. BETTING ON REST.

  31. ▪ Early support for rich HTTP semantics ▪ Powerful router

    (request constraints, ...) ▪ Content negotiation (Accept, $.getJSON) ▪ Baked-in MIME types ▪ HTTP caching ("Conditional GET") ▪ JSON parameters ▪ Security (e.g. IP spoo ng) WINS OF REST.
  32. RAILS HAS A GREAT HTTP FOUNDATION.

  33. BUT...

  34. DATA TRANSPORT

  35. SQL DATABASE

  36. ▪ Primary key: chosen per table ▪ Table name: chosen

    per table ▪ Timestamps: chosen per timestamp ▪ Polymorphic tables: ad hoc setup ▪ Foreign keys: chosen per relationship ▪ Camel/Underscore: chosen per eld BEFORE RAILS.
  37. Because of all of these discrepancies, you end up needing

    to build a map of your database for your application.
  38. "DATABASES ARE TOO DIFFERENT" In the early days of Rails,

    we heard a lot of arguments that databases were simply too different for AR to be more than just a toy. We hear similar arguments today with APIs.
  39. JSON APIS.

  40. ▪ Should responses include a root? ▪ How to embed

    associations? ▪ Include the identi er? In what form? ▪ id or href? ▪ Include additional/associated resources? ▪ How to update in bulk? ▪ Primary key de ned on server or client? ▪ Moving a belongs_to record? JSON APIS. Just like there were questions in SQL, there are questions in JSON APIs.
  41. STANDARDIZED CLIENT CODE. Without standardization, we cannot easily build standardized

    code on the client.
  42. We're also back to making the same trivial decisions over

    and over again, if we even realize that we are making decisions.
  43. And because we're not taking on the problem, we're pushing

    the concerns onto every client.
  44. IS RAILS WORTH IT? Since Rails doesn't provide these conventions,

    people are asking "Is Rails the right tool for the job" Even though other tools don't provide conventions, Rails is all about CoC, so the lack of conventions makes *Rails* feel like the wrong tool for the job, even though much of Rails is still useful. Rails starts feeling more like a very polished library and less like a framework.
  45. ACTIVEMODEL SERIALIZERS.

  46. What to Serialize • Which attributes • Which associations How

    to Serialize • Include a root? • Associations? • Extra data? • Avoid duplication!
  47. class PostSerializer < ApplicationSerializer attributes :title, :body belongs_to :author has_many

    :comments end WHAT TO SERIALIZE.
  48. class PostSerializer < ApplicationSerializer attributes :title, :body belongs_to :author has_many

    :comments def comments comments = post.comments return comments if scope.admin? comments.where(hidden: false) end end CUSTOMIZE.
  49. class ApplicationController embed :ids, include: true end HOW TO SERIALIZE.

  50. { posts: [ { "id": 1, "title": "First", "person_id": 1

    }, { "id": 2, "title": "Next", "person_id": 1 }, { "id": 3, "title": "More!", "person_id": 1 } ], people: [ { "id": 1, "name": "Yehuda Katz" } ] } AVOID DUPLICATION.
  51. ANY CONVENTION IS BETTER THAN NO CONVENTION.

  52. DEMO.

  53. None
  54. None
  55. AVOID MIXING COMMON AND UNCOMMON. The advantage of serializers is

    that it avoids mixing the common (representation) with the unique (attributes, associations) This is in contrast with builders, which put the common and unique things in one place, so we have no place for conventions.
  56. CONFIGURABLE. Especially for authorization, there is a need to be

    able to poke under the declarative hood. It's not all documented, but it works.
  57. class PostSerializer < ApplicationSerializer attributes :title, :body has_many :comments has_many

    :troll_ratings # override just default association inclusion def include_associations! comments = post.comments unless scope.can(:see_hidden, post) comments = comments.where(visible: true) end # override default value, but not embedding rules, etc. include! :comments, value: comments # conditionally include an association include! :troll_ratings if scope.can(:troll_rate, post) end end AUTHORIZATION.
  58. WAS IN RAILS.

  59. REVERTED. WHY?

  60. EMBER-RAILS. ember-rails was trying to build a transparent data transport

    and it was hard for arbitrary Rails applications.
  61. GENERATE A MODEL, GET A SERIALIZER AND EMBER-DATA MODEL.

  62. REST ADAPTER.

  63. App.store = DS.Store.create({ revision: 4, adapter: "DS.RESTAdapter" }); REST ADAPTER.

  64. App.Post = DS.Model.extend({ title: DS.attr('string'), body: DS.attr('string'), comments: DS.hasMany(App.Comment) });

    App.Comment = DS.Model.extend({ body: DS.attr('string'), post: DS.belongsTo(App.Post) }); MODELS.
  65. var people = App.Person.all(); /* GET /people */ // later...

    var first = people.objectAt(0); first.set('firstName', "Brohuda"); App.store.commit(); /* POST /person/1 { ... } */ TRANSPARENT.
  66. Transport Client Side Serialization AMo::Serializers solve serialization, but I think

    we need a general solution for all three.
  67. BULK. Serializers doesn't solve this, but there is a need

    to define conventions around bulk updates. ember-data defines conventions that, if implemented in Rails, "just work"
  68. OTHER DATA FEATURES. Identity map; data binding to the view;

    associations (including create parent=>child=>persist)
  69. CONVENTIONS FOR APPLICATION STRUCTURE. Beyond "put your JS here"

  70. TRIVIAL CHOICES ARE THE ENEMY.

  71. NODE?

  72. Back in 1995, we knew something that I don't think

    our competitors understood, and few understand even now: when you're writing software that only has to run on your own servers, you can use any language you want. When you're writing desktop software, there's a strong bias toward writing applications in the same language as the operating system. But with Web-based software, you can use whatever language you want. “ PAUL GRAHAM
  73. This new freedom is a double-edged sword, however. Now that

    you can use any language, you have to think about which one to use. Companies that try to pretend nothing has changed risk nding that their competitors do not. “ PAUL GRAHAM
  74. TRANSPORT. Standards and Conventions • HTML • ActiveRecord Same Language

    Everywhere • JMS • DRb Thinking "I need to talk with JS, therefore I need to write JS on the server" is pretty lazy thinking. We can get seamlessness without insisting on the same language everywhere.
  75. TRANSPORT. Standards and Conventions • HTML • ActiveRecord Same Language

    Everywhere • JMS • DRb > Thinking "I need to talk with JS, therefore I need to write JS on the server" is pretty lazy thinking. We can get seamlessness without insisting on the same language everywhere.
  76. RECAP

  77. ▪ Good conventions save developers from having to agonize over

    common problems. ▪ Rails' bet on REST gave it a leg up in many areas that are relevant to rich client apps. ▪ There is still room for improvement: we can make APIs as transparent as ActiveRecord. ▪ ActiveModel::Serializers is one approach we are looking at to get us there. ▪ We can also make browser frameworks better through the same conventions. RECAP.
  78. THANKS! @WYCATS