Talks

Return To Simplicity: Architect Hypermedia REST applications using Hanami + HTMX

Return To Simplicity: Architect Hypermedia REST applications using Hanami + HTMX

by Brooke Kuhlmann

In the presentation "Return To Simplicity: Architect Hypermedia REST applications using Hanami + HTMX" at Rocky Mountain Ruby 2023, Brooke Kuhlmann advocates for a simplified approach to web application development employing the frameworks Hanami and HTMX. The talk critiques the current complexity prevalent in web development stacks, particularly in JavaScript environments, where large teams manage extensive frontend and backend processes. Kuhlmann emphasizes that a streamlined team of Ruby engineers can effectively build applications using a Hypermedia RESTful design without unnecessary intricacies.

Key points discussed include:
- Complexity of Current Stacks: Kuhlmann highlights the convoluted nature of modern web applications, where the use of frameworks like React leads to heavy dependency management and inefficiencies, urging a return to simpler, more direct approaches.
- Conway's Law: The organization of teams often mirrors the complexity of the software, complicating communication and efficiency. Simplifying team structures can lead to more straightforward development.
- Hanami and HTMX Intro: The combination of Hanami, a web framework, and HTMX, which allows for hypermedia interactions without excess JavaScript, enables developers to create clean, maintainable code.
- Demonstration Application: Kuhlmann presents a live demo illustrating how HTMX can manage standard HTTP requests with simpler interactions, fostering better user experience without relying heavily on frontend JavaScript.
- Hanami Framework Overview: She explains the organizational structure of Hanami, modeled after principles like DRY (Don't Repeat Yourself) and SOLID, allowing for clear separation of concerns and efficient dependency management.
- Use of Slices: Slices can help break down applications for better manageability, potentially evolving into microservices in the future.
- Advantages of HTMX: By using HTMX, developers benefit from self-describing responses in a hypermedia REST architecture, simplifying data handling by leveraging standard HTML.
- Conclusion: Kuhlmann calls for a rekindling of focus on simplicity in engineering, promoting Hanami and HTMX as powerful tools to achieve this in web development. She encourages the audience to engage with the communities around these technologies for support and learning opportunities.

Ultimately, Kuhlmann's message revolves around the need to simplify the development process, championing a return to fundamental design principles to enhance both application construction and team dynamics.

00:00:14 Today, I'm going to talk about Hanami and HTMX. These slides are power-packed and will be available for you to download later. I'll be moving quickly to keep you engaged, but please feel free to stop me at any time to ask questions. I'll do my best to facilitate the discussion.
00:00:26 The frameworks and libraries I will discuss emphasize a return to simplicity. You might wonder why this is important. There are some key issues to address, notably our software stack. For instance, let's take a look at the JavaScript stack, which, while popular, is not my favorite.
00:00:46 This stack consists of a mix of various frameworks, starting from the frontend. Then you introduce Node, which leads to complex package management and dependency management. Depending on the complexity of your stack, this can consume several megabytes to even a couple of gigabytes.
00:01:11 You may have post-processing steps in your build process, and you'll need to optimize your packages before deployment, sometimes wrapping everything up with Docker and managing a complicated Kubernetes configuration.
00:01:29 I'm not claiming that Docker is inherently bad; however, mixing it with Kubernetes can complicate things quickly. This complexity reinforces the need to simplify our development stacks.
00:01:51 There's a popular quote that suggests the software industry's trends often follow a popularity contest rather than sound reasoning. In this context, everyone wants to hire React developers, not necessarily because it's the best path but because it's the most well-known.
00:02:03 Conway's Law is another significant issue we need to consider. Essentially, the way teams are organized usually parallels the structure of the software they create. In collaboration with large clients, I've observed that teams can become overly complicated, resulting in excessive management, specialized roles, and a convoluted structure.
00:02:25 This complexity breeds communication challenges that can stifle efficiency. When organizational changes occur, and team structures shift repeatedly, it attaches a heavy burden of legacy through inefficient communication.
00:02:40 Henry Rollins' sentiments resonate with the idea of simplifying and honing our focus as engineers. We should be able to work top-down, comprehensively, without convoluted communication paths.
00:02:55 The ecosystem I'm going to talk about today is based on DRY-RB, which gives us a functional core. As we know, Ruby is a beautiful object-oriented language with robust functional capabilities. Dry RB enhances this, while ROM serves as our persistence layer. Hanami provides the web framework, and HTMX offers the hypermedia REST frontend.
00:03:11 I'll provide a sneak peek of a demonstration application later, so I encourage you to pay attention as I navigate through it. It's not the fanciest UI, but it remains functional. You will notice how I use keyboard events, mouse clicks, and other methods to dynamically interact with this application.
00:03:39 The backend is powered by HTMX; I'm sending standard HTTP requests and receiving hypermedia REST responses back. Running this locally makes everything very responsive, especially since my database is relatively small.
00:04:01 In this demonstration, I want you to pay particular attention to the network tab, as I aim to demonstrate that there's no hidden magic happening. All requests revolve around standard HTTP verbs: PATCH, PUT, GET, DELETE—all are HTMX requests sent across the wire.
00:04:18 Notably, no JavaScript calls are made here; HTMX is incorporated into the UI as a library. The rest of the logic is enabled via attributes within the DOM elements. Now, let's dive into the Hanami framework to provide some structural insights.
00:04:37 To kick things off, grabbing Hanami, installing it, and getting it operational is an excellent starting point. However, it may feel rather primitive. That's why I developed a gem called Hanami Smith, designed to give you all the power tools necessary for professional development.
00:05:03 Furthermore, Hanami Smith integrates Overmind, which enhances the development experience. Using Hanami Smith, you'll find a convenient CLI that allows for a variety of build options, catering to your specific development needs.
00:05:24 Additionally, it employs the XDG gem, which I maintain, permitting both global and local configurations. This means you can store your flags and other important settings in a configuration file rather than cluttering the command line. When you boot up your application or generate new ones, Hanami Smith will utilize this stored configuration.
00:06:07 When you get everything up and running, you'll be greeted with a splash screen featuring the Hanami Smith logo. You will also find links to the Hanami documentation and system stats, ensuring you know which versions you're running.
00:06:24 With that foundational understanding, let’s delve deeper into the Hanami framework. Now, there’s a lot to cover in this segment, so I'll touch on broad strokes while leaving some additional details for you to explore independently.
00:06:44 To build on this, you're receiving powerful tools right out of the box. The folder structure in the app directory will feel reminiscent of other frameworks like Rails.
00:07:01 Within the app folder, you will find separate folders for actions, repositories, and views. In Hanami, the single responsibility principle is strongly adhered to, whereby each action is defined distinctly, mapping directly to an HTTP verb.
00:07:25 Next, we have our repository, utilizing ROM for data management, allowing for clean separation between application logic and data access.
00:07:38 The Hanami view defines the view layer and its components, ensuring that each aspect of the architecture serves a clear purpose.
00:07:52 Within the configuration settings, you'll find provider settings and route definitions. For example, your database URL is pulled in from the environment and rigorously type-checked, ensuring it meets expectations.
00:08:05 Moreover, in routes, you can set up slices for specific routes, such as health checks or the home splash page that we previously referred to.
00:08:22 Providers enable you to manage the lifecycle of various service components. One example is a Redis provider, where you can prepare and initialize the client for later use.
00:08:41 This modular design ensures efficiency, as components are only activated when needed, resulting in quicker cold boot times. It's noteworthy that Hanami is built on the DRY system, which seamlessly integrates with state management.
00:09:02 In terms of structure, your database seeds and persistence layers are managed efficiently. In the lib directory, you can find refinements for your type structures, which ties back into the DRY types gem.
00:09:27 At this moment, Hanami 2.0 does not yet include an asset layer, but one is on the horizon. You may leverage rack static to serve static assets in the meantime.
00:09:43 I want to briefly touch upon slices, an integral aspect of Hanami that relates closely to Mark's discussion yesterday regarding microservices. Slices condense your business logic into manageable pieces without the overhead seen in traditional Rails engines.
00:10:07 With slices, you can create 'mini' Hanami applications that can later be transformed into microservices if that becomes necessary.
00:10:23 Inside your slices, you will have a similar organizational structure: actions, repositories, and views, maintaining a clean flow of logic and ensuring every action corresponds to an HTTP verb.
00:10:43 Let me now pivot to discuss dependency injection, which is an essential feature of Hanami worth emphasizing.
00:11:05 This fits into the design principles we've been exploring, particularly SOLID principles, which advocate for clear single responsibilities and clean separation of concerns.
00:11:21 When using dependency injection within Hanami, you can define a container to manage dependencies. This allows you to inject your persistent ROM container based on defined keys.
00:11:38 What makes this efficient is that the key-value pairs in your dependency definitions can be stripped of prefixes for clarity, making your implementation cleaner and more understandable.
00:11:56 The Dry Container employed here allows for easy definition and registration of services, leading to a flexible architecture.
00:12:10 I also want to critique the public accessibility of dependencies as a potential downside when using dry auto-inject.
00:12:23 It’s essential to encapsulate your objects by controlling what interfaces are made public. I've developed an alternative gem, Infusible, to deal with this by making dependencies private by default.
00:12:34 The contrast is that with Hanami, your dependencies are carefully defined and, through a designated import mechanism, can be injected where necessary.
00:12:51 Moving on from Hanami, I want to shift gears and explore HTMX. Understanding its function requires a bit of historical context to appreciate its utility fully.
00:13:12 Tim Berners-Lee developed HTML and hypermedia in 1990. A decade later, Roy Fielding established the REST protocol, followed by the advent of HTMX twenty years afterward.
00:13:30 This timeline spans thirty years of technological evolution, and it seems we've diverged significantly from original design philosophies to some extent.
00:13:52 HTMX stands apart from many modern frameworks as it allows for a decoupled implementation, usable across various stacks, rather than being tied to one specific technology like Elixir with Phoenix LiveView or Rails with Hotwire.
00:14:06 HTML alone is not our only option. Other specifications like JSON-LD exist which encapsulate metadata to provide context for structured data.
00:14:24 However, I choose to focus on HTML since it is universally understood by browsers and reduces the need for additional complexities, thus serving our purpose efficiently.
00:14:40 In practice, using hypermedia REST with HTML means that you gain a self-describing language in which each tag delineates its purpose within the DOM.
00:15:05 Let's analyze this by looking at a straightforward use case: making a GET request to a resource like Wikipedia. The standard process simplifies the return of web pages.
00:15:20 In modern applications, however, the architecture has grown complicated.
00:15:31 Developers often rely on data APIs alongside rich JavaScript stacks on the frontend. When creating new content on platforms like Wikipedia, the process can become convoluted.
00:15:58 Requests and responses may come back in JSON format, requiring complex translation for browsers to interpret this data accurately.
00:16:11 In contrast, with hypermedia REST, one gains the benefit of self-describing responses, reducing the need for intricate logic to interpret returned data.
00:16:27 As we familiarize ourselves with HTMX, the installation could not be simpler. You could load it directly from a Content Delivery Network (CDN) as a quick start.
00:16:39 HTMX applies special prefixes, allowing you to enable your DOM interactions seamlessly. For example, by creating a simple button that dictates the behavior of requests made.
00:16:54 Returning to the demonstration application, relying on HTMX means that clicking a button can automatically trigger a request and update the corresponding DOM elements with the response.
00:17:11 As you inspect the code, you will observe that each action corresponds directly to an HTTP request, underpinning the concept of hypermedia interactions.
00:17:28 To give you additional context, I have made a demonstration application available for download. It follows a Git rebase workflow, leading you through each step of architecting the application.
00:17:43 Briefly reviewing HTTP DELETE actions, the key points involve careful handling of injected dependencies, followed by the construction of relevant action handlers.
00:18:02 The main responsibility of these handlers focuses on managing parameters and ensuring that incoming requests adhere to the expected format, relying on validation techniques.
00:18:18 In terms of user experience, HTMX facilitates building partials that help render pieces of views dynamically, maintaining a streamlined flow of information.
00:18:34 The underlying design benefits from a defined set of helpers, which allow for a concise relationship between actions and their associated views.
00:18:47 Moreover, implementing loading indicators offers users feedback during operations or when performing searches, significantly contributing to an improved user experience.
00:19:05 The capability to handle input dynamically ensures fluid interactions between users and the application as various triggers facilitate request submissions.
00:19:25 With these fundamental principles in place, your application can efficiently manage dependencies while fostering clean designs that yield effective solutions.
00:19:36 In conclusion, returning to simplicity is paramount. Leveraging both Hanami and HTMX allows you to deepen your grasp of full-stack applications without overwhelming complexity.
00:19:50 I highly recommend exploring the communities and resources surrounding these technologies, as they offer valuable learning opportunities. Thank you for your participation.
00:20:08 If you’d like to connect or have further inquiries, I’m readily available for discussions and collaboration opportunities.
00:20:20 If anyone has questions or needs clarification, I would be happy to engage further. Thank you!