27,59 €
Elixir's functional nature and metaprogramming capabilities make it an ideal language for building web frameworks, with Phoenix being the most ubiquitous framework in the Elixir ecosystem and a popular choice for companies seeking scalable web-based products. With an ever-increasing demand for Elixir engineers, developers can accelerate their careers by learning Elixir and the Phoenix web framework. With Build Your Own Web Framework in Elixir, you’ll start by exploring the fundamental concepts of web development using Elixir. You'll learn how to build a robust web server and create a router to direct incoming requests to the correct controller. Then, you'll learn to dispatch requests to controllers to respond with clean, semantic HTML, and explore the power of Domain-Specific Languages (DSL) and metaprogramming in Elixir. You'll develop a deep understanding of Elixir's unique syntax and semantics, allowing you to optimize your code for performance and maintainability. Finally, you'll discover how to effectively test each component of your application for accuracy and performance. By the end of this book, you'll have a thorough understanding of how Elixir components are implemented within Phoenix, and how to leverage its powerful features to build robust web applications
Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:
Seitenzahl: 254
Veröffentlichungsjahr: 2023
Develop lightning-fast web applications using Phoenix and metaprogramming
Aditya Iyengar
BIRMINGHAM—MUMBAI
Copyright © 2023 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
Group Product Manager: Rohit Rajkumar
Publishing Product Manager: Aaron Tanna
Senior Editor: Mark D’Souza
Senior Content Development Editor: Feza Shaikh
Technical Editor: Saurabh Kadave
Copy Editor: Safis Editing
Project Coordinator: Manthan Patel
Proofreader: Safis Editing
Indexer: Pratik Shirodkar
Production Designer: Jyoti Chauhan
Marketing Coordinator: Anamika Singh, Namita Velgekar, and Nivedita Pandey
First published: June 2023
Production reference: 1170523
Published by Packt Publishing Ltd.
Livery Place
35 Livery Street
Birmingham
B3 2PB, UK.
ISBN 978-1-80181-254-2
www.packtpub.com
To my wife, Susan Walker, and my parents, Nirmal and Madhu Iyengar, without whose encouragement and support I wouldn’t have even thought of writing a book.
– Aditya Iyengar
I first met Adi when he applied to work at Annkissam in 2015. I was the Chief Technology Officer (CTO) at the time, but I wasn’t involved in his formal interview process. It was fortunate that I saw him between interviews and we chatted about error correction code (ECC) memory and Hamming codes. I came away excited and had strong opinions that I needed to share with the hiring team. Thankfully, they agreed, and soon after, I had the opportunity to manage and mentor a brilliant developer.
At that time, our organization was running into concurrency issues with Ruby. I had looked into several technologies, but the Phoenix framework was the most impressive. It had just reached its 1.0 release, and with it came the benefits of Elixir and Open Telecom Platform (OTPs). We trained Adi on Rails for his first few weeks, but within a month, he helped me build a Phoenix clone of a Rails app, and its speed was impressive. We launched our first Phoenix application into production that same year.
Coming from Ruby on Rails (RoR), we lost a lot of convenient gems. Elixir was a newer ecosystem, but we were tech evangelists. The solution was to build everything we needed and open source as much as possible. No pagination module? Adi built Rummage. Our deployment strategy needed updating. Adi built Akd. DevOps? I used his tool to configure my last several laptops. My guidance during that time was to write tests, predict where other developers would have difficulty, and always read the code you’re using.
It’s that foundation that I see in this book and why I was so humbled that Adi asked me to write this foreword. While Phoenix is ubiquitous today, most guides focus on how to use it. In this book, you’ll learn how it is built. You’ll cover not just the fundamentals of web development but also how they’re implemented. You’ll learn how the framework has such elegant syntax and how you can use metaprogramming to do the same in your code. You’ll also be shown plenty of examples to put it into context and ensure you can incorporate them into your own work.
The attention to detail you’ll find in this book extends to its very publishing. Adi wanted to ensure the code samples were accurate, so he wrote unit-tested code, annotated that code, and then wrote a library to extract that code and combine it with the text to produce the final copy. He’s always talking about 100% code coverage, so it’s fitting he’s extended that to printed work. It’s that level of care which makes him a great mentor, and you’ll find it throughout this book.
What I’m most excited about is that this book reminds us to continue asking how. Going deeper than the README.md file and hexdocs will make you a better developer. With Adi’s guidance, this book does that for one of the most significant libraries in Elixir.
Eric Sullivan
Senior Software Engineer at PepsiCo, Ex-CTO, Ex-Founder
Adi Iyengar is a staff software engineer who has worked with Elixir since 2015. Over those years, he has worked across a wide array of applications and authored/contributed to several open source projects, including Elixir itself. Adi has also advised and continues to advise several start-ups on engineering and product, and helps them adopt Elixir and Phoenix to build functional and scalable minimal viable products (MVPs) from the ground up. He is passionate about mentoring and sharing his knowledge with others, which is why he actively mentors other engineers. He loves Elixir, functional programming, and test-driven development (TDD). Adi is also the co-host of the Elixir Mix podcast. When not coding, Adi can be seen playing billiards, playing the guitar, or breakdancing. Adi also spends a good amount of his time keeping up with new developments in particle physics.
Adi is also the co-host of the Elixir Mix podcast which is a weekly Elixir podcast where the panel discusses Functional Programming, the Elixir ecosystem and building real-world applications using Elixir based tools and frameworks.
I have been extremely lucky in getting a lot of opportunities to learn and grow as an engineer, and I’d like to thank everyone who has contributed to my career, including my family, friends, mentors, and mentees. Thanks to every engineer who has contributed to this book in one way or another (in no particular order): Susan Walker, Eric Sullivan, Jeffrey Matthias, Josh Scott Adams, Sophie Debenedetto, Tuomo Hopia, Bruce Tate, Evan Kaplan, Andrea Leopardi, Sascha Wolf, Allen Wyma, and Charles Max Wood. Lastly, special thanks to a special company, Annkissam, because of whom I started walking the path to learning this amazing language.
Henry Clinton is a versatile engineer with extensive experience in electronics and communication. He has honed his skills as a senior Elixir developer, delivering end-to-end execution of several pivotal projects at Iteron Technologies. Henry’s passion for technology is infectious, and his insatiable curiosity drives him to explore and master a wide range of topics. He combines his technical expertise with a creative mindset to come up with innovative solutions to complex problems. His attention to detail and commitment to excellence is unparalleled, making him a valuable asset and instrumental in bringing his work to fruition.
Lubien is a software developer who specializes in Elixir and JavaScript languages. Previously focused on frontend work with JavaScript frameworks, he’s now looking forward to technologies that handle the frontend on the backend, such as LiveView and LiveWire. He is passionate about teaching the latest trends in the industry. He enjoys working with Devs Norte to build a developer community in his hometown of Belém do Pará. He also posts content on his YouTube channel in Portuguese, @lubiendev, to help newcomers to Phoenix LiveView and writes English content under Fly.io Phoenix Files.
Nikhil More is a senior software developer with over nine years of experience. He has working experience in the domains of banking and finance, defense, logistics, mobility, and internet of things (IoT). Prior to working on Elixir since 2016, he also worked on C++, .Net, PHP, JSP, and so on. His current interests include the Semantic Web, IoT, project management, Agile, and artificial intelligence (deep learning and genetic algorithms). Nikhil has taught deep learning at Usha Mittal Institute of Technology, Mumbai. He is currently working on his own software consultancy called Infoquarry Technologies Pvt. Ltd. Some of his previous notable employers are Electronics and Radar Development Establishment, Bengaluru, which is a premier laboratory of the Ministry of Defence, India, Western Railway, under the Ministry of Railways, India, Central Bank of India, BlockFi Inc., Volansys Technologies Pvt. Ltd, and Ahmedabad. Other mentions of the projects he has worked on are for a car-sharing application owned by a large Japanese automobile manufacturer and a Wi-Fi mesh device for a large US entity. He is also an active member of various technical meetup communities in Ahmedabad, Bengaluru, Mumbai, and Pune. He also conducts training sessions on functional programming and Elixir development.
Parvatham Raghuchander is an experienced enterprise cloud solutions architect with expertise in messaging and voice-over IP (VoIP). She has developed, designed, re-engineered, and integrated enterprise solutions for a wide range of organizations. Her programming experience is mostly in Erlang, Elixir, and Golang, with specializations in Phoenix, the Cowboy framework, AWS, Azure, Docker, Kubernetes, NoSQL, and SQL databases.
There’s an old story about the person who wished his computer were as easy to use as his telephone. That wish has come true since I no longer know how to use my telephone.
– Bjarne Stroustrup
The preceding quote from Stroustrup shows just how fast technology is evolving. We’re building more complex software day by day while also building it at an ever-increasing rate. However, as the complexity of software increases, so do abstractions around its fundamentals. As a result, it is easier to build software using those abstractions but harder to completely understand how a piece of software works the way it does. This is true for programming languages, deployment tools, and several other types of tools we use. Another one of those tools is a web framework.
A web framework is a tool or a set of tools that assists in building and releasing a web application. This is accomplished through the process of standardization and building abstractions around those standardized models. Web frameworks usually include tools for server management, data management, templating, and so on. From the 1990s to 2021, we have seen the evolution of web frameworks from Java Servlets and ASP.NET to Rails and Elixir’s Phoenix. Over the course of this period, we have significantly decreased the average amount of effort required to build a web application. However, since Phoenix facilitates productive web development, I frequently come across developers being bewildered by its “magic.” That “magic” is often one obstacle that stands in the way of an Elixir web developer to cross the seemingly never-ending bridge of mid-level to senior-level. It is also one of the key factors that determines how confident they feel as a developer.
This book aims to help developers overcome that obstacle by building a web framework from scratch using Elixir. The goal is to demystify the aforementioned Phoenix magic by breaking it down into components and designing/building them from the ground up while testing their expected behaviors. I expect developers to feel more confident in their web development skills and Elixir knowledge after reading this book. Maybe, some will even go on to make contributions to the Elixir open source community.
This book is for web developers looking to understand how Elixir components are used in the Phoenix framework. Basic knowledge of Elixir will be useful to understand the concepts covered in the book more effectively.
Chapter 1, Introducing the Cowboy Web Server, covers how an HTTP server is designed and the details of Cowboy, the most used web server in the Elixir ecosystem. It also covers how to use Cowboy to build a simple web application that serves HTML. Finally, it details how to test the web application built using Cowboy.
Chapter 2, Building an HTTP Server in Elixir, uses the conclusions from Chapter 1 and extends them to build a brand new HTTP server in Elixir. It covers setting up a TCP socket using :gen_tcp, and wrapping it in an idiomatic interface. This chapter also covers how to test a web application built using the new web server, as well as how to test the web server itself. Finally, it covers how to add concurrency to the new web server. This HTTP server will finally be used in the web framework that’s being built in this book, Goldcrest.
Chapter 3, Defining Web Application Specifications Using Plug, covers the Plug package and the Plug.Conn construct, which together act as building blocks of a Phoenix HTTP request. This chapter covers the components of the Plug package and the philosophy of using it. It takes a deeper dive into Plug.Router and covers how to use it to build a routing layer to a web application. It then covers how to build a Plug adapter for a web server by taking a look at Cowboy’s Plug adapter. Finally, it uses all this knowledge to build a new Plug adapter for the web server built in Chapter 2. This will allow us to use Plug with the new web server.
Chapter 4, Working with Controllers, leverages what we learned in Chapter 3 about Plug and uses it to build a controller interface for the web framework, Goldcrest. It covers the basics of a controller in Phoenix and building a controller interface that follows a similar pattern. It also details how redirection works in Phoenix and how to add that functionality to the new controller interface. Finally, it uses the Plug.Test module to test the newly built controller.
Chapter 5, Adding Controller Plugs and Action Fallback, extends the controller interface built in Chapter 4 by adding the ability to intercept a request at the controller level before letting the controller handlers handle it. This chapter covers how Phoenix handles such use cases and how we can simply use Plug to handle this. It details the Plug.Builder module that comes with the Plug package and the different approaches to test it. Finally, this chapter covers adding the ability to provide a fallback option to the controller, which handles any failed responses from all the handlers.
Chapter 6, Working with HTML and Embedded Elixir, explains how HTML is rendered on the server side by Phoenix. It introduces the EEx module, which allows us to embed Elixir between non-Elixir text, and it covers how we can use EEx to respond with dynamic server-side rendered HTML. Finally, it covers how to test the dynamically generated HTML.
Chapter 7, Working with Views, covers how to build the View interface for the web framework, Goldcrest. It goes over some of the key functionalities that can be extracted from the HTML rendering aspect of the controller and leverages the EEx module’s ability to pass helper functions at the time of evaluation. Like all the other chapters, it ends by covering strategies to test the changes explained in the chapter.
Chapter 8, Metaprogramming – Code That Writes Code, covers metaprogramming in Elixir. It covers the constructs such as quote, code injection, abstract syntax trees, and so on that allow Phoenix to have such a simple interface and breaks them down in a digestible manner. It also covers macros and compile-time hooks while using these constructs to build a new domain-specific language (DSL) to produce music in Elixir, as an example. Finally, it covers several ways to test the meta code to make it more deterministic.
Chapter 9, Controller and View DSL, uses the concepts covered in the previous chapter to build a DSL around the controller and view built in Chapter 3 to Chapter 7. This chapter also covers ways of making the interface easier to work with by making it easier to test and more introspective. Finally, it covers ways of testing the new Controller and View interfaces.
sw, Building the Router DSL, uses the metaprogramming concepts from Chapter 8 to build a new DSL. This DSL will be for the router functionality, and this chapter covers ways to mimic Phoenix’s router DSL. Like the previous chapter, it covers ways of making the DSL easier to use and test. Finally, it updates the example app built in the first part of the book to use the Router, Controller, and View interfaces built in the last two chapters.
This book is very code-heavy, and in order to maximize what you learn from this book, it is recommended to code along with every code snippet. Make sure you’re using the correct Elixir and Erlang versions (as recommended at the beginning of the chapters). If you are new to Elixir or haven’t used it in a while, doing some practice exercises to shake off the dust before you dig into this book is also recommended.
This book relies on Elixir 1.11.x and Erlang 23.2.x. Ensure you have asdf or some other package manager installed on your system. This will allow you to easily switch back and forth between Elixir and Erlang versions. This book was tested on macOS and Linux, so you may experience some inconsistencies when using Windows.
If you are using the digital version of this book, we advise you to type the code yourself or access the code from the book’s GitHub repository (a link is available in the next section). Doing so will help you avoid any potential errors related to the copying and pasting of code.
You can download the example code files for this book from GitHub at https://github.com/PacktPublishing/Build-Your-Own-Web-Framework-in-Elixir. If there’s an update to the code, it will be updated in the GitHub repository.
We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
We also provide a PDF file that has color images of the screenshots and diagrams used in this book. You can download it here: https://packt.link/jQVwi.
There are a number of text conventions used throughout this book.
Code in text: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: “In the preceding code snippet, we added a start/1 function, which listens using the default listener_options variable and creates a listening socket to accept incoming connections.”
A block of code is set as follows:
defmodule ExperimentServer do # .. defp recv(connection_sock, messages \\ []) do case :gen_tcp.recv(connection_sock, 0) do {:ok, message} -> IO.puts """ Got message: #{inspect(message)} """ recv(connection_sock, [message | messages]) {:error, :closed} -> IO.puts "Socket closed" {:ok, messages} end end end ExperimentServer.start(4040)When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold.
Any command-line input or output is written as follows:
$ elixir experiment_server.exs Listening on port 4040Bold: Indicates a new term, an important word, or words that you see onscreen. For instance, words in menus or dialog boxes appear in bold.
Tips or important notes
Appear like this.
Feedback from our readers is always welcome.
General feedback: If you have questions about any aspect of this book, email us at [email protected] and mention the book title in the subject of your message.
Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packtpub.com/support/errata and fill in the form.
Piracy: If you come across any illegal copies of our works in any form on the internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected] with a link to the material.
If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.
Once you’ve read Build Your Own Web Framework in Elixir, we’d love to hear your thoughts! Please click here to go straight to the Amazon review pagefor this book and share your feedback.
Your review is important to us and the tech community and will help us make sure we’re delivering excellent quality content..
Thanks for purchasing this book!
Do you like to read on the go but are unable to carry your print books everywhere?
Is your eBook purchase not compatible with the device of your choice?
Don’t worry, now with every Packt book you get a DRM-free PDF version of that book at no cost.
Read anywhere, any place, on any device. Search, copy, and paste code from your favorite technical books directly into your application.
The perks don’t stop there, you can get exclusive access to discounts, newsletters, and great free content in your inbox daily
Follow these simple steps to get the benefits:
Scan the QR code or visit the link belowhttps://packt.link/free-ebook/9781801812542
Submit your proof of purchaseThat’s it! We’ll send your free PDF and other benefits to your email directlyIn this part, you will learn what this book is about, the basics of web development, and how to build a web server in Elixir.
This part includes the following chapters:
Chapter 1, Introducing the Cowboy Web ServerChapter 2, Building an HTTP Server in Elixir“Web servers are written in C, and if they’re not, they’re written in Java or C++, which are C derivatives, or Python or Ruby, which are implemented in C.”
– Rob Pike, co-creator of Go
The web server is a key component of any modern-day web framework. Expanding on the point made in the preceding quote by Rob Pike, the Cowboy web server, written in Erlang, is also in a way implemented in C. Cowboy is the default web server used by Phoenix, the ubiquitous web framework in Elixir.
In this chapter, we will not be learning C, unfortunately, but we will take a closer look at how a web server is designed. We will provide some background on how a web server is built and set up to communicate with a client using HyperText Markup Language (HTML).
We will also learn the fundamentals of how HTTP requests and responses work, including their anatomy. We will then learn how to construct an HTTP response and send it using a web server. Moreover, we will learn the fundamentals of web server architecture by examining the components of Cowboy. Lastly, we will learn ways to test a web server and measure its performance. Doing this will put us in a better position to build our own web server in the next chapter.
The following are the topics we will cover in this chapter:
What is a web server?Fundamentals of client-server architectureFundamentals of HTTPHow an HTTP server worksUsing Cowboy to build a web serverUsing dynamic routes with CowboyServing HTMLTesting the web serverGoing through these topics and looking at Cowboy will allow us to build our own HTTP server in Chapter 2.
The best way to work through this chapter is by following along with the code on your computer. So, having a computer with Elixir and Erlang ready to go would be ideal. I recommend using a version manager such as asdf to install Elixir 1.11.x and Erlang 23.2.x, to get similar results as the code written in the book. We will also be using an HTTP client such as cURL or Wget to make HTTP requests to our server, and a web browser to render HTML responses.
Although most of the code in this chapter is relatively simple, basic knowledge of Elixir and/or Erlang would also come in handy. It will allow you to get more out of this chapter while setting the foundation for other chapters.
Since most of this chapter isn’t coding, you can also choose to read without coding, but the same doesn’t apply to other chapters.
The code examples for this chapter can be found at https://github.com/PacktPublishing/Build-Your-Own-Web-Framework-in-Elixir/tree/main/chapter_01
A web server is an entity that delivers the content of a site to the end user. A web server is typically a long-running process, listening for requests on a port, and upon receiving a request, the web server responds with a document. This way of communication is standardized by the Transmission Control Protocol/Internet Protocol (TCP/IP) model, which provides a set of communication protocols used by any communication network. There are other layers of standardization, such as the HyperText Transfer Protocol (HTTP) and File Transfer Protocol (FTP), which dictate standards of communication at the application layer based on different applications such as web applications in the case of HTTP, and file transfer applications in the case of FTP, while still using TCP/IP at the network layer. In this book, we will be primarily focusing on a web server using HTTP at the application layer.
Example HTTP server
If you have Python 3 installed on your machine (you likely do), you can quickly spin up a web server that serves a static HTML document by creating an index.html file in a new directory and running a simple HTTP Python server. Here are the commands:
$ mkdir test-server && cd test-server && touch index.html
$ echo "<h1>Hello World</h1>" > index.html
$ python -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) . . .
If you are on Python 2, replace http.serverwith SimpleHTTPServer.
Now, once you navigate to http://localhost:8080/ on your web browser, you should see "Hello World" as the response. You should also be able to see the server logs when you navigate back to the terminal.
To stop the HTTP server, press Ctrl + C.
The primary goal of web servers is to respond to a client’s request with documents in the form of HTML or JSON. These days, however, web servers do much more than that. Some have analytical features, such as an Admin UI, and some have the ability to generate dynamic documents. For example, Phoenix’s web server has both of those features. Now that we know what a web server is, let’s learn about how it is used with the client-server architecture.
In the context of HTTP servers, clients generally mean the web browsers that enable end users to read the information being served, whereas servers mean long-running processes that serve information in the form of documents to those clients. These documents are most commonly written in HTML and are used as a means of communication between the client and the server. Clients are responsible for enabling the end user to send a request to the server and display the response from the server. Browsers allow the users to retrieve and display information without requiring any knowledge of HTML or web servers, by just providing an address (the URL).
