Talks

The Illusion of Stable APIs

EuRuKo 2016

00:00:05.420 So for our last talk, we have the creator of Trailbreaker, a high-level web application framework for Ruby apps. You might have noticed him yesterday, being the soul of the party. He's the least German German I've ever known, and I've been living in Germany for three years now—Munich, to be precise. So please welcome on stage Mr. Nick Sutterer.
00:00:42.079 They told me everyone is leaving today. Who is leaving today? It’s like five people. Okay, I'm sorry—I mean I'm happy that you could actually party last night. I think you partied hard because you didn't have to give the closing presentation on the second day. But I also hear rumors about an official after-party tonight. So maybe you want to rebook your flight and stay for a couple more days.
00:01:00.520 Okay, to make this less confusing, my name is actually not Rafael; my name is Nick. I'm also not from Bulgaria; I'm from Germany. This does not mean I cannot drink as much rakia here as you guys can drink. Speaking of which, this lovely guy over here, I never know how to pronounce his name, but I love him to the bottom of my heart. We’ve been partying at many conferences and having deep, profound debates.
00:01:20.600 It's a bit awkward when you know someone for a couple of years and, in summer, you think to yourself, 'Hey, it was nice the last three years with you, but how do I actually pronounce your name?'.
00:01:30.000 Anyway, he’s usually a party animal, and I'm nothing compared to him. He parties like a maniac. Unfortunately, he is a bit sick today; I think he's in the hospital. It's not the coolest thing to do on the weekend, but on the other hand, it's a cool story. Like I said, 'Hey, how was Friday?' Oh, 'Appendix surgery? Nothing special.'
00:02:43.130 When I wrote this presentation 17 years ago, I titled it 'The End of Rails?' It was a very controversial and aggressive title. People said, 'Hey, Nick, you’re always talking about Rails, and you’re being so aggressive. You’re not contributing enough to be so weird.' So I agreed; I am a little bit of an ass, and I renamed it to 'The Illusion of Stable APIs.' The great thing about this title is that it could mean anything. And it is some random stuff, but the problem is, people started asking me, 'So actually, what's your talk about?' They liked the title but wanted more details.
00:04:47.110 I couldn't summarize my talk without mentioning Rails, so I decided to completely rewrite my talk and focus on real content now. Also, I want to be just a functional hipster, giving you a little bit of context. So, what I learned about rakia is that it’s pretty strong and good for healing inflammation. It makes people tweet weird photos at the strangest hours of the day, often involving toothbrushes rather than cute animals.
00:05:31.880 And it does not make you blind; that’s a rumor that’s not true. Right, Rafael? Can you still see me? Yes? Good. What’s also awesome about rakia is that I don’t tend to get hangovers from it. So I could manage to party yesterday on the first night of the conference—not the second—before I give my closing talk. And I could actually manage to wake up early enough to attend the first talk.
00:06:08.870 I woke up at 9:00 AM and managed to take selfies to prove that I was attending an amazing Elixir talk. Every time I hear someone talk about Elixir, I feel compelled to stop using Ruby and start using Elixir! But anyway, let's talk about APIs. Many people in this room might think I'm going to talk about document APIs—how cool JSON documents are or how Rails API and ActiveModel work.
00:07:42.890 Absolutely not! I’m going to talk about APIs in the context of what we use as programmers. As a programmer, you interact with APIs on a daily basis while writing code. APIs can include constants, methods, and the signatures of method arguments. The structure of objects, functions, and workflows you use are also parts of an API. The cool thing about APIs is that they make our lives easier because we can utilize code written by others without needing to understand everything going on inside.
00:09:03.750 APIs essentially provide abstractions that help programmers achieve their tasks without full knowledge of the internal workings. The fantastic aspect is when people start to extend APIs and think, 'This is kind of cool, but I’d love to add more functionality on top of that.' For example, think of a login form as an abstraction for authentication, where you provide your username and password.
00:09:51.570 At some point, people said, 'I’ve had too much rakia and always forget my password,' so they insisted on allowing login via Facebook or GitHub. Since every person on this planet seems to have a GitHub account, they began adding buttons like, 'Log me in with my GitHub handle.' That’s an excellent example of how APIs can be extended effectively.
00:10:24.290 APIs don’t have to remain static; they are meant to evolve when it makes sense. This is my favorite part of the talk: Ruby on Rails APIs come in the form of Ruby internals and also as part of the Rails framework.
00:10:39.790 You might be apprehensive hearing about Rails and its MVC structure. The MVC pattern is essentially the architectural abstraction designed to help you write web applications. The controller manages the view, and the model presents data to the view. Rails makes this flow very seamless, allowing even newcomers to grasp how applications work relatively quickly.
00:11:24.510 People who have never written code before can learn to create dynamic pages in roughly an hour. However, the challenge lies in our strong adherence to the MVC paradigm. We have the so-called 'Rails Doctrine' crafted by DHH himself, which basically states, 'MVC the way we do it, or else!' Everyone is expected to follow this doctrine, treating MVC as the perfect way to write software.
00:12:45.970 The issue arises when some Ruby developers don’t even realize they are writing Ruby—they think they are just writing Rails. You can spend years figuring out where the boundaries of the language lie with the framework, and whether there are alternative layers you could use besides MVC.
00:13:39.800 Our dependence on the MVC pattern leads to convoluted code—dare I say, messy code. If I call it messy, that might be perceived negatively, which I want to avoid at the end of this talk. Sometimes, using the standard Rails view structure results in very large views overloaded with authentication and authorization logic, rendering numerous partials.
00:14:32.370 The controller gets similarly cluttered—the authentication logic and various validations all mixed in. It becomes extremely difficult to grasp what the actual Rails developer is doing within a controller action. The same can be said for models, which tend to bloat as well. This complexity isn’t merely a result of individuals being bad programmers; it complicates things for even the smartest developers.
00:15:34.680 When you realize your abstractions are insufficient, it's time to reconsider your structure and APIs. In my opinion, Rails has been slow in acknowledging that its strong focus on MVC might not always be the best direction. If you prefer extensive controllers and models, that's fine, but it can lead to a lot of challenges.
00:16:26.680 To illustrate this, I want to show you an example of working with Active Record, which I genuinely love. A common task involves implementing user models with validations—a user's name must typically be no longer than twenty characters. But suppose I'm an admin and I want to create a user with a name exceeding that limit; that should be permissible.
00:17:36.410 In Rails, this scenario is nearly impossible to navigate because we pigeonhole all validations into the model structure. The workaround often ends up cluttering the model with conditional statements. This trend of adding 'if-else' logic can lead to polymorphic behavior.
00:18:01.270 Adding 'if' statements within a method, particularly in a declarative API or DSL, often indicates a structural error. It’s much simpler to define different contexts within systems, just as other frameworks like Elixir handle it efficiently.
00:18:40.760 In Elixir's Phoenix framework, user management allows for schema definitions, change sets, and distinct functions for admin and normal users. The model avoids the mess of having multiple if-statement combinations for validations. Instead, it ensures that each context functions independently, promoting better coding practices.
00:19:56.240 Similarly, in the Ruby framework Trello, we also distinguish once again between the operations for different user contexts. Instead of cramming functionality together, every user action has its own class, enabling expanded maintenability and readability. Each operation can share validations while being distinct in their roles.
00:20:29.110 The prevailing mindset in Rails has been to consolidate functionality under one class due to the MVC doctrine. Unfortunately, not only does this complicate the code structure, but it also imposes limitations on the potential for productive changes and improvements.
00:21:39.200 Another feature that surfaced due to these constraints is the idea of accessible parameters. Instead of combining all logic into the model, Rails could adopt a third layer to validate access control. This approach is already practiced in modern frameworks such as Phoenix and Trello.
00:22:29.120 In the presented example, we see that validations and access managers can remain separate, lending structure and clarity to the code without buried logic. Rails can benefit from embracing this paradigm to reduce code redundancy.
00:23:28.080 As we address these emerging issues, it becomes clear that streamlining processes via effective abstraction is paramount for developer success. Additionally, acknowledging patterns found in other programming languages—like the introduction of the safe navigation operator in Ruby—brings enhancements to debugging and object management.
00:24:20.590 This operator allows us to simplify checks for nil objects, promoting cleaner code and making it easier to handle nested attributes. While this feature is less about a primary objective than an innovative solution, it highlights the ongoing iterative changes developers should embrace.
00:25:42.370 The ability to adapt APIs and promote clarity within your code structure is a sign of good programming practices. Programmers should remain open to changing their architectures to suit new demands. The objective should always be about improving structures to foresee potential challenges.
00:26:18.100 It's vital to understand that changing code does not equate to poor programming but signifies adaptability. When facing evolving needs, whether a login form expecting GitHub integration, developers should always opt to progress and innovate. This inquiry is intrinsic to optimizing code and enhancing user experiences.
00:27:14.240 In summary, I believe simplifying our APIs while embracing change will encourage better coding practices that will pay dividends down the road. Let your design thinking be innovative, helping your development speak.
00:27:47.170 As we head to the after-party, let us keep in mind how we love sunsets and appreciate, as an audience, your participation. Let’s head for some drinks!