Rocky Mountain Ruby 2011

CRUD is not REST - Hypermedia for Y'All!

CRUD is not REST - Hypermedia for Y'All!

by Nick Sutterer

The video titled "CRUD is not REST - Hypermedia for Y'All!" features Nick Sutterer discussing the fundamental aspects of REST architecture, particularly the importance of hypermedia in creating truly RESTful systems. Sutterer emphasizes that many implementations irresponsibly equate CRUD operations with REST by merely mapping them to HTTP verbs in monolithic applications, which overlooks the true distributed nature of REST. Instead, he advocates for a hypermedia approach to achieve a genuinely distributed architecture.

Key points discussed in the video include:

- Understanding REST: Sutterer defines REST (Representational State Transfer) as an architectural style for distributed hypermedia systems and critiques common misconceptions surrounding it.

- The role of hypermedia: He stresses that hypermedia is crucial for enabling machines to navigate resources seamlessly, akin to how humans interact with them.

- Roar gem: Sutterer introduces his gem, Roar, which aids in creating RESTful APIs by managing representations and hypermedia links.

- Distinction between CRUD and REST: While CRUD operations translate to REST actions, Sutterer argues that CRUD does not encompass the full essence of REST, as it lacks the distributed aspect inherent in RESTful architectures.

- Real-world examples: He illustrates the concept with an imaginary beer ordering system named 'Burp,' where users can select beers, create orders, and navigate through hypermedia links embedded in JSON representations. By separating the frontend and backend and utilizing hypermedia, the application avoids manual URL computations, simplifying interactions.

- HATEOAS: Hypermedia as the Engine of Application State (HATEOAS) is introduced as a key principle, allowing for enriched navigation and interaction with resources via hypermedia links.

- Framework independence: Roar is presented as a framework-agnostic solution for handling hypermedia links and representations, working seamlessly with Ruby and Rails.

The talk concludes with the notion that integrating hypermedia in RESTful systems not only helps avoid bugs caused by manual URL calculations but also streamlines API design, ultimately leading to more robust and maintainable code. Sutterer's engaging style interspersed with humor makes the discussion accessible, focusing on real-world applications and the importance of understanding hypermedia in the context of REST.

In summary, the video presents a compelling case for recognizing hypermedia's importance in RESTful applications, urging developers to move beyond simplistic CRUD-centric approaches to embrace the true essence of distributed architectures.

00:00:09 All right, thank you for coming in.
00:00:10 My name is Nick, and I'm from Germany.
00:00:14 I came all the way just to talk to you guys about hypermedia and REST.
00:00:18 I'm a Ruby guy, so there's nothing special to tell about me.
00:00:22 I have a couple of gems and projects.
00:00:26 If people ask me what I'm working on, I usually say I'm a self-employed scientist.
00:00:33 That sounds cool, and usually, companies hire me to improve their software architecture.
00:00:39 I usually go to write ten frameworks, and then they kick me out because I didn't write any application code.
00:00:45 But then I publish the frameworks on GitHub, get famous, and can do talks in the Rocky Mountains.
00:00:50 That's cool! Now, I'll stop talking about myself.
00:00:54 I think you guys came here to learn about REST.
00:01:01 So we have about 27.8 minutes to go.
00:01:08 I'll talk a little bit about REST and my view on its main constraints.
00:01:15 Who here is working on a REST project? Who has created a REST API?
00:01:25 Come on, guys! Who's using Rails? Who's using Facebook?
00:01:32 This is impressive—only three people!
00:01:37 All right, I will talk about representations and documents, which is the same as hypermedia.
00:01:43 I want to introduce you to my own gem called Roar.
00:01:49 REST is representational state transfer—interesting!
00:01:57 I took Roy Fielding's thesis; he is the author of REST.
00:02:03 Who has read the thesis? This is impressive, like 10 people.
00:02:09 Did you learn anything about REST from this thesis? Because I didn't.
00:02:15 Sorry, Roy, if this is on video.
00:02:21 The main point about REST is in Chapter 5, which is about REST in line.
00:02:28 REST is an architectural style for distributed hypermedia systems.
00:02:37 So keep in mind it's an architectural style, and it's about distributed systems.
00:02:43 The problem with architectural styles is that you cannot simply write a gem.
00:02:50 You can't just include it in your Rails application and consider it RESTful.
00:02:56 You have to consider how to introduce REST into your application.
00:03:02 As an architect or developer, you need to make your application truly RESTful.
00:03:09 I'm here to help you get on the right path regarding REST.
00:03:16 What Rails does is not really RESTful—I'm sorry.
00:03:23 REST is essentially about machines talking to each other.
00:03:30 They ask questions, and they respond with machine-readable answers.
00:03:36 The center of REST is the resource, which can be anything.
00:03:42 For example, it could be a beer representation, a news feed, or the current user.
00:03:50 Every resource in the REST system has a unique URL.
00:03:56 You can manipulate that resource using the uniform interface.
00:04:02 This includes GET, POST, PUT, and DELETE operations.
00:04:09 REST is basically about sending and retrieving documents.
00:04:15 Remember, representations are documents.
00:04:20 The REST approach, particularly in Rails, often results in a monolithic application.
00:04:27 You have pretty URLs, and they call it RESTful.
00:04:34 You use GET to retrieve representations of models, maybe in JSON or XML.
00:04:41 You also use GET to serve HTML for the user interface.
00:04:48 Basically, you use POST to create or update models.
00:04:55 They sometimes fake PUT requests in such systems.
00:05:01 The REST approach I'm presenting today is about componentized applications.
00:05:08 This is the distributed part, where you don't have one monolithic application.
00:05:15 Instead, you may have several separate applications.
00:05:22 And you can still have pretty URLs—how cool is that?
00:05:28 I will discuss real REST services where you use GET, PUT, POST, and DELETE.
00:05:35 These operations allow you to manipulate resources.
00:05:40 Usually, a REST service is not supposed to provide HTML.
00:05:46 That's my impression of REST.
00:05:52 A crucial point about REST is the use of hypermedia to link services.
00:05:59 This is something Rails didn't teach us.
00:06:06 To illustrate hypermedia, I have an imaginary system called Burp.
00:06:12 It's a beer ordering service.
00:06:19 Let’s say we can browse beers, add them to our order, and then have them delivered.
00:06:24 By the way, Burp stands for Beer Shop System using RESTful backend services.
00:06:30 The separation of presentation and backend is essential.
00:06:37 Let's see a typical REST session.
00:06:44 On one side, we have the REST service, and on the other, the REST client.
00:06:50 For example, if I do a GET request to a REST service, my request might include some document.
00:06:57 The request to retrieve beers might return a JSON representation.
00:07:04 I’m using a simplified JSON version for presentation.
00:07:09 The Rails approach is about allowing GET requests to get resource representations.
00:07:16 You can also perform POST requests to create resources.
00:07:23 So, for example, I could post a new beer to the Burp system.
00:07:30 After posting, you would get a redirect saying a new beer was created.
00:07:36 It might be located at beers/java.
00:07:43 Java is a good beer from Germany; you should try it.
00:07:48 In the Rails view, REST maps GET, POST, PUT, and DELETE to create, show, and update.
00:07:55 So, CRUD translates to REST.
00:08:02 But I say CRUD is not REST—REST is more than that.
00:08:09 Let’s look at a hypermedia-driven REST session in Burp.
00:08:17 The first step in a hypermedia system is separating the frontend from the backend.
00:08:24 On the left side, we have the graphical user interface as a REST client.
00:08:31 On the right, we have our REST services.
00:08:37 Another essential step is that multiple applications can interconnect using hypermedia.
00:08:44 Now I’ll get my order.
00:08:50 I do a GET request to orders/1 and get back a JSON response.
00:08:57 This response contains some hypermedia links.
00:09:02 For example, to proceed with my order, I’d use orders/1/pay for a PUT request.
00:09:10 This is where the hypermedia aspect comes in.
00:09:16 In REST, we have HATEOAS—Hypermedia as the Engine of Application State.
00:09:24 It's about embedding actions or links in your representations.
00:09:30 Thus, proceeding with my order makes sense in this context.
00:09:35 Hypermedia can come in many forms.
00:09:42 A typical way is to have a links key in your two-dimensional representation.
00:09:48 A hypermedia link consists of a rel attribute and an href attribute.
00:09:54 This means it tells you what to do and provides a URL.
00:10:00 Languages like XML can also provide representations.
00:10:06 But for this presentation, I’m focusing on JSON.
00:10:12 Every hypermedia link in a RESTful representation has a rel attribute.
00:10:19 The rel describes the link’s semantic meaning.
00:10:25 The href is the URL we're requesting or sending a request to.
00:10:31 To create a new order, you would POST to the orders endpoint.
00:10:37 You may include some additional data, like the client ID.
00:10:44 In response, you receive an enriched document confirming your order was created.
00:10:51 In a true hypermedia-driven system, your frontend knows only one entry point URL.
00:10:58 For example, it might just be http://orders.
00:11:05 No need for complex URL computations.
00:11:13 In my system, I have a self-link, which points to the resource itself.
00:11:19 And then there's the beers link, pointing to orders/1/beers.
00:11:24 This allows me to see all the items placed in my order.
00:11:31 To check my order status, I do a GET to orders/1.
00:11:38 This will give me the representation of my order.
00:11:44 Following the beers link, I do orders/1/beers and get back what's there.
00:11:51 If I have not ordered anything, the beers array will be empty.
00:11:56 Following this process helps to avoid URL computation.
00:12:03 Integrating hypermedia lets you easily navigate the orders.
00:12:10 I do this by adding a beer to my order using POST to orders/1/beers.
00:12:18 I just send a beer name in the JSON document body.
00:12:25 When I post, the system should redirect me to the newly created resource.
00:12:32 Now I want to check my order again using orders/1.
00:12:39 If I check again, I see the beer's array will now have an item.
00:12:46 I added an Anchor Steam beer to my order.
00:12:53 I remember having it in San Francisco; it’s pretty good.
00:13:00 After placing the beer, my order representation grows.
00:13:06 But we won’t study all of that in detail.
00:13:13 I want to emphasize the self-link pointing to the order.
00:13:19 That link helps refer back to the order and its beers.
00:13:27 Now, what if I want to remove that Anchor Steam beer?
00:13:33 I would use DELETE on orders/1/beers/anchor-steam.
00:13:41 This action takes that beer out of my order.
00:13:48 It’s better if I want local IPA stuff instead.
00:13:56 Boulder has so many breweries, like 10 or 11!
00:14:01 After removing the beer, I check my order again using orders/1.
00:14:08 Now my beers array should be empty.
00:14:14 This demonstration involved many HTTP requests.
00:14:20 It's okay if you couldn't follow every single detail.
00:14:27 The main takeaway is that I posted to a single entry URL, orders.
00:14:36 After creating an order, I use a GET request to retrieve it.
00:14:45 The link to beers is embedded in my representation.
00:14:53 At each step, I avoided computing URLs manually.
00:15:00 I just extracted the URLs I needed.
00:15:06 This concept of hypermedia is essential in REST systems.
00:15:12 It defines how to expose your API.
00:15:18 It avoids potential bugs caused by URL computation.
00:15:25 I also want to touch on updating an order.
00:15:32 I could send a PUT request to orders/1 to update.
00:15:39 This is only a conceptual overview of how it works.
00:15:45 Now, let's look at how this can be done in Ruby.
00:15:52 I have a small gem called Roar.
00:15:58 It stands for Resource Oriented Architectures in Ruby.
00:16:03 Roar allows you to create an abstraction layer called representers.
00:16:08 You can define documents or representations using this layer.
00:16:15 Link methods help you embed hypermedia in your document.
00:16:22 Roar works not only with Rails but with Ruby in general.
00:16:30 In Rails, you can use URL helpers to compute hypermedia links.
00:16:35 The new simplify method called `represents` makes this easier.
00:16:41 You can render documents with my representer.
00:16:48 You can also parse incoming documents using representations.
00:16:54 The main point is that representers are framework agnostic.
00:17:00 Roar is bi-directional: it handles both rendering and parsing.
00:17:06 You can use representers in your client layer and your service layer.
00:17:14 You can extend your object dynamically to perform HTTP requests.
00:17:21 With representers, you can extract hypermedia links from documents.
00:17:28 On the GitHub page, there's a complete example of how to use it.
00:17:34 I recommend some books for further reading about hypermedia.
00:17:40 One is "REST in Practice." Have you read it?
00:17:46 Only two people, right? It’s a good read!
00:17:54 Another is "REST for Web Services Cookbook," which is very enlightening.
00:18:01 Roy Fielding wrote a blog post titled "Hypermedia APIs Must Be Hypertext Driven."
00:18:09 He argues against URL computation in REST clients—only hypermedia extraction.
00:18:17 It's an interesting read, filled with many perspectives.
00:18:23 Let me conclude by asking if anyone is hiring.
00:18:31 I’m a handsome German programmer looking for opportunities.
00:18:36 If anyone has a tent or cooking equipment for my hiking—that would be great.
00:18:47 This has been my talk about REST and hypermedia.
00:19:04 I hope you gained some insights.
00:19:11 I think we don’t have time for questions.
00:19:17 Maybe there are no questions?
00:19:24 Oh, there's one question in the front.
00:19:30 The audience member asks about handling long POST requests.
00:19:37 When creating a resource that takes a long time, how do I manage that?
00:19:42 I repeat the question for clarity.
00:19:48 There are a few approaches, but this talk is focused on hypermedia.
00:19:55 I don't have a magic rule for that.
00:20:01 Anything else?
00:20:06 Another audience member asks about authentication.
00:20:12 How do you handle authentication in RESTful systems?
00:20:18 I dislike the overhead of constantly sending authentication headers.
00:20:24 Are there any approaches to avoid such complexities?
00:20:31 The audience member continues to discuss their thoughts.
00:20:37 I would be interested to hear how you've managed authentication.
00:20:43 The audience member makes a final comment about drinks.
00:20:49 The resource may represent a tangible drink—like beer!
00:20:53 But technically, you receive a representation of that item.
00:21:00 Thank you all! You've been a wonderful audience.
00:21:07 Don't forget the humor in the examples!
00:21:15 Take care!