Blog

We write about Ember.js, Ruby on Rails as well as Elixir and Phoenix.

Back End Development

Phoenix for Rubyists

Phoenix Framework draws heavily upon important foundations in the opinionated web frameworks that came before it, like Ruby on Rails.

1
Module 1 Duration: 80 minutes

1 — The First Sip

Before we jump right into the framework, we need to at least know the basics of the programming language we’re working with.

Agenda
The First Sip Duration: 15 minutes
9:00
Welcome & Getting Started

We’ll go over our agenda, and set our sights on some goals for the day.

The First Sip Duration: 20 minutes
9:15
Origins, Foundations & Core Principles

Elixir is unique, in that it provides us the fantastic ergonomics of a modern programming language, while standing on the solid and battle-tested foundation of the Erlang ecosystem.

The First Sip Duration: 15 minutes
9:45
Interactive Elixir

Elixir’s interactive shell (IEx) is one of the most powerful tools in your toolbox. We’ll outline some of the most useful features for beginners, including

  • Running scripts
  • Getting metadata about a value
  • Accessing embedded documentation
  • Inspecting the state of a particular process
The First Sip Duration: 30 minutes
10:15
IO & Files

As with most programming languages, it’s useful to know how to interact with files and humans. We’ll take care of this early on, and notice a few things that foreshadow some interesting aspects of Elixir’s concurrency model.

2
Module 2 Duration: 360 minutes

2 — Types, Operators & Control Flow

One must crawl before one walks, and it all starts with basic types and procedural logic. Even if you’re experienced in a wide range of programming languages, there’s going to be a lot of stuff – even at this basic level – that may change the way you look at writing code forever.

Agenda
Types, Operators & Control Flow Duration: 30 minutes
10:45
Math & Strings

There’s no getting away from these kinds of things. Eventually you’re going to need to work with numbers and text, so we’ll start with a crash course in some core APIs (including a dip in the erlang pool) that will make life easy.

There’s a lot of capability here, but we’ll stay close to the commonly-useful and pragmatic path.

Types, Operators & Control Flow Duration: 30 minutes
11:15
EXERCISE: Projectile Motion

We’ll create a simple program that calculates and object’s projectile motion, given a launch angle and initial velocity

Types, Operators & Control Flow Duration: 25 minutes
11:45
EXERCISE: String Acrobatics

We’ve got a bunch of functions that do various things to strings, but our tests are failing.

Types, Operators & Control Flow Duration: 35 minutes
12:10
Functions

It stands to reason that functions are really important in a functional programming language. We’ll build and work with named an anonymous functions, combine functions together to form pipelines, and even map out some higher-order functions of our own.

Types, Operators & Control Flow Duration: 45 minutes
12:45
Lunch

Break for Lunch

Types, Operators & Control Flow Duration: 30 minutes
13:30
Tuples and Lists

Often times we find ourselves needing to work with several objects in a “collection”, and will need to choose between Elixir’s List and Tuple types. We’ll compare and contrast tuples and lists, and write a few programs highlighting the benefits of each

Types, Operators & Control Flow Duration: 30 minutes
14:00
Associative Data Structures

We have two main associative data structures in Elixir: keyword lists and maps. Let’s learn more about them!

Types, Operators & Control Flow Duration: 30 minutes
14:30
EXERCISE: Building up a List

Assembling a bunch of items in a list is really fast, as long as we do it in a way that doesn’t involve moving existing items around in memory. We’ll write two programs, one which assembles a bunch of dictionary words into a tuple, and another that uses a list instead.

Types, Operators & Control Flow Duration: 30 minutes
15:00
Pattern Matching & Guards

This modern language feature allows destructed assignment, and is often used in order to define several variants of a function, each to handle a specific scenario. This application of pattern matching reduces what would otherwise be a lot of internal function complexity by huge amounts.

Types, Operators & Control Flow Duration: 30 minutes
15:30
EXERCISE: Function Refactoring

We’ve got an elixir module that involves some code that could benefit from some pattern matching magic. Refactor the monolith function so all use of if/else are replaced by creating new functions oriented toward handling that specific pattern of arguments.

Types, Operators & Control Flow Duration: 30 minutes
16:00
Conditionals & Guards

It’s unusual to use if/else in Elixir, because we have some far more powerful approaches to deciding among different branches of code to use. We’ll look at the case control flow structure, where pattern matching really starts to shine. We’ll also take a look at how guards can be added to case clauses (and other control flow structures) to form even more specific and targeted patterns.

Types, Operators & Control Flow Duration: 30 minutes
16:30
EXERCISE: More Refactoring

We’ll refactor some more code to leverage the power of pattern matching and functional control flow tools.

Types, Operators & Control Flow Duration: 15 minutes
17:00
Wrap Up

Wrap up for the day

3
Module 3 Duration: 90 minutes

3 — Writing Modular Programs

Elixirs module system allows us to define layers of related functions. In this part of the course, we’ll explore the concepts of modules, and the ability to reference code in one module from another.

Agenda
Writing Modular Programs Duration: 15 minutes
9:00
Modules & Three Important Directives

Modules are just a group of several functions, some of which may be private and some of which may be public. Modules give us the ability to define named functions using the def macro, which offer a few other features that were unavailable in the world of anonymous functions

Writing Modular Programs Duration: 20 minutes
9:15
EXERCISE: Mission Control

We’ve got a set of tests for a couple of Elixir modules that are used to control a space ship. Alter the code to make the unit tests pass, and ensure that you’ve kept as much of each module’s internal functionality private as possible.

Writing Modular Programs Duration: 25 minutes
9:35
Basic Metaprogramming

While the use macro is not strictly a directive, it’s of particular importance when considering “mixins” for common functionaliy across multiple modules.

Writing Modular Programs Duration: 30 minutes
10:00
EXERCISE: Extending a module

The use macro can essentially be used to decorate a module with some code from another

4
Module 4 Duration: 135 minutes

4 — Working With Data Structures

Earlier we outlined and worked with several different types of data structures. Let’s take a closer look at some ways

Agenda
Working With Data Structures Duration: 30 minutes
10:30
EXERCISE: Map, Filter, Reduce

We have a program that starts with a list of objects read from a file. Using the built-in functions available in the Enum and Map modules, filter out “inactive” items (objects where the “active” attribute is not true), and then log a list of object names to the console.

Working With Data Structures Duration: 30 minutes
11:00
Taming List Enumeration with Comprehensions

Often we find ourselves looping over something enumerable, mapping values into another list, and potentially filtering out some unwanted items. Comprehensions use a generator and a filter to provide some excellent syntactic sugar for this kind of task.

Working With Data Structures Duration: 30 minutes
11:30
EXERCISE: Comprehensions

Take another pass at the previous exercise, and use a comprehension to devise a concise solution.

Working With Data Structures Duration: 45 minutes
12:00
Lunch

Break for Lunch

5
Module 5 Duration: 195 minutes

5 — Request, Response

A Phoenix app can basically be boiled down to a function that receives a HTTP request, and returns a response. We’ll begin with this premise, and start to understand the important parts involved in this process.

Agenda
Request, Response Duration: 25 minutes
12:45
Endpoint & Routing

Requests enter your app through an Endpoint, and your app usually will have only one. We’ll look at this chain of Elixir Plugs, which ends at the Router, the module ultimately responsible for delegating request-handling to an appropriate Controller.

Request, Response Duration: 30 minutes
13:10
Plugs & Pipelines

Plugs are at the core of Phoenix, and they’re a relatively simple and approachable concept: things that accept a connection as an argument, and return a slightly-modified connection.

Chain a few plugs together, and it’s easy to see how basic building blocks start to assemble into a complete application.

Request, Response Duration: 20 minutes
13:40
EXERCISE: Routing to the Pages controller

Add a new page to your app, following the existing example set up in your PageController

Request, Response Duration: 30 minutes
14:00
EXERCISE: Hating on a Content-Type

Build a Plug that interrupts the pipeline (returning a HTTP error for an incoming request) if we ever request a SOAP XML document (Content-Type: application/soap+xml)

Request, Response Duration: 30 minutes
14:30
The Controller Responds

Now that we understand how to leverage Phoenix’s routing layer, let’s take a closer look at Controllers: the modules ultimately responsible for responding to a request.

Request, Response Duration: 30 minutes
15:00
Views & Templates

In a welcome contrast to other web frameworks, Phoenix’s view layer is exceedingly easy to understand and use.

Judging by how easy it is to keep views simple, performant, and easy to manage, It’s clear that the hard-learned lessons from older frameworks have paid off.

Request, Response Duration: 30 minutes
15:30
EXERCISE: Assigns & Functional Views

We’ll pass some data from the Phoenix controller layer to the view layer, and leverage view functions to do some light formatting & massaging.

6
Module 6 Duration: 60 minutes

6 — Testing

Testing ergonomics is perhaps the most impactful factor in determining whether writing tests is an enjoyable part of day-to-day development, or an annoying slog that’s neglected until problems arise.

In this area, Phoenix does not disappoint. We’ll focus on several useful patterns for unit and acceptance testing, with the aim of making tests quick, easy, maintainable and intuitive.

Agenda
Testing Duration: 30 minutes
16:00
Controller and View Tests

Sometimes we use Phoenix to render HTML, so we’ll look at how we can verify that both our controller and view layers (individually) are doing their job.

Testing Duration: 30 minutes
16:30
JSON API Tests

Often we use Phoenix Controllers to render JSON. We’ll explore some built-in helpers that are well-suited for helping us write tests verifying that the JSON contains what we expect, and touch on a few libraries that make this even easier!

7
Module 7 Duration: 225 minutes

7 — Managing Data

Data is an integral part of virtually any web application, and a great persistence library make a huge difference in performance and maintainability.

Thankfully, the Elixir ecosystem has us covered in spades. Ecto is a thin layer of functions that allow us to build composable queries, validate fields, and seamlessly transform records between our DB and application representations.

Agenda
Managing Data Duration: 20 minutes
9:00
Intro to Ecto

Heavy persistence libraries like ActiveRecord offer convenience, but often become performance bottlenecks. We could make every DB query explicitly, but then we’re trading in all of our ergonomics for performance.

Ecto manages to strike an enjoyable balance, where we are asked to be deliberate about the records we fetch from a database but (most of the time) aren’t dragged into the world of writing SQL queries explicitly.

You’ll be amazed at how much we can do with just simple functions, and will never look at other persistence frameworks quite the same way again.

Managing Data Duration: 25 minutes
9:20
Managing Migrations

If you’ve never used code to manage changes to your database schema, you’re missing out. Migrations allow us to change our schema in (ideally) reversible steps, so we can apply and un-apply a set of changes while building features. Even if you’ve seen migrations before, there are some useful things to know about how they work with Ecto, and in particular, Postgres. We’ll look, specifically at:

  • Postgres array and jsonb column types
  • Changing column types, while remaining backwards compatible
Managing Data Duration: 30 minutes
9:45
Cracking Changesets

This is one of my favorite parts about Ecto, and one of the parts you’ll be most often working with. In contrast to other persistence libraries, the concept of the shape of a record (schema) and the logic for checking the validity of values (validations) are decoupled. There are some incredibly exciting consequences of this design decision.

Ecto ships with a bunch of validations, and because it’s so quick and easy, we’ll write a few of our own.

Managing Data Duration: 30 minutes
10:15
EXERCISE: Models & Validation

Create models and appropriate validations for a blog post/comment app.

Managing Data Duration: 30 minutes
10:45
Quick Queries

While we could use SQL syntax to retrieve records from our database, doing so would open us up to a world of pain. Ecto provides an approachable and composable way of building queries, while stopping short of doing us any “automatic favors” (i.e., N+1 queries) that so often degrade performance.

Managing Data Duration: 45 minutes
11:15
EXERCISE: Query Olympics

You’ll be given a list of database queries for you and your classmates to make using Ecto. Each query is worth a certain number of points. Highest number of points after the exercise is done, wins!

Managing Data Duration: 45 minutes
12:00
Lunch

Break for Lunch

8
Module 8 Duration: 105 minutes

8 — Real Time

One of the places where Elixir and Phoenix leave the competition in the dust is support for soft real time programming. The ability to keep a lightweight Elixir process running for the duration of a user’s time in our app, and holding some small amount of state, makes things far simpler for certain things than it otherwise would be.

Agenda
Real Time Duration: 45 minutes
12:45
Channel Basics

Phoenix Channels are a first class citizen in the framework, on equal footing with Controllers. It shows! You’ll be amazed at how easy it is to start adding real-time features to your apps, where we push data from server to client.

Development best practices are increasingly moving in a functional and “stateless” direction, but Elixir Processes are a place where small pieces of state can be safely held and used. We’ll explore how powerful this idea is, in the context of Phoenix channels.

Real Time Duration: 30 minutes
13:30
EXERCISE: My First Channel

Build your first channel, so that you can notify client-side apps of new comments being posted to articles.

Real Time Duration: 30 minutes
14:00
Managing Channel Complexity

While you may have contributed to a REST API project that had 10 endpoints (each handling 1-4 HTTP verbs), it’s less likely that you have experience working with a long-lived web socket connection operating on the same scale of complexity. It’s important to remember that this is API surface, and because it’s often stateful instead of stateless, keeping organized is even more important.

9
Module 9 Duration: 150 minutes

9 — Users & Authentication

Nearly every app we build these days requires some sort of authentication, and probably a user account to go along with it. Even if your app is an oddball and doesn’t need this, user accounts provide us with a well-understood set of use cases that will serve as an excellent case study.

Let’s put some of our newfound Phoenix knowledge into practice as we implement a secure user account feature set. The goal will be to reduce explicit management of authorization & authentication on a per-resource basis as much as possible.

Agenda
Users & Authentication Duration: 45 minutes
14:30
EXERCISE: Registration

Creating new users will serve to highlight a few concepts at the model layer

  • Server-side validation, including writing our own validator
  • Safely handling passwords
  • Keeping slightly different changeset-generating functions organized

We’ll also have an opportunity to start defining routes that require a user to be authenticated, and routes that don’t.

Users & Authentication Duration: 45 minutes
15:15
EXERCISE: Login & Logout

For our purposes, we’ll use a JSON Web Token (JWT) and the OAuth 2 password grant standard, as a mechanism and vehicle for authentication. You will be provided with a client-side app that will talk to our Phoenix, via JSON.

We’ll validate a user’s credentials in a way that’s not incredibly sensitive to timing or brute force attacks, and then assemble our little piece of session state (the JWT) before encrypting it and handing it back to the client.

Users & Authentication Duration: 45 minutes
16:00
EXERCISE: Roles

We often have a concept of roles (or an equivalent concept masquerading as other flags/fields) built on top of our authentication. We’ll add roles to our JWT, and design a plug that will raise an error if a user attempts to access a controller action without having the required roles.

Users & Authentication Duration: 15 minutes
16:45
Wrap Up & Goodbye

We’ll recap everything we’ve learned

Do you Have a Project in Mind?