As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure, first class umbrella project support, and scaffolding that re-enforces phoenix as a web-interface to your greater Elixir application. We have also included a new action_fallback feature in Phoenix.Controller that allows you to translate common datastructures in your domain to valid responses. In practice, this cleans up your controller code and gives you a single plug to handle otherwise duplicated code paths. It is particularly nice for JSON API controllers.

For those interested in a detailed overview of the changes and design decisions, check out my LonestarElixir keynote that just went live: https://www.youtube.com/watch?v=tMO28ar0lW8

To use the new phx.new project generator, you can install the archive with the following command:

$ mix archive.install https://github.com/phoenixframework/archives/raw/master/phx_new.ez

As always, we have an upgrade guide with detailed instructions for migrating from 1.2.x projects: https://gist.github.com/chrismccord/71ab10d433c98b714b75c886eff17357

1.3.0 is a backwards compatible release, so upgrading can be as easy as bumping your :phoenix dep in mix.exs to “~> 1.3”. For those wanting to adopt the new conventions, the upgrade guides will take you step-by-step. Before you upgrade, it’s worth watching the keynote or exploring the design decisions outlined below.

Phoenix 1.3 – Design With Intent

The new project and code generators take the lessons learned from the last two years and push folks towards better design decisions as they’re learning. Changes to new projects include moving web inside lib to avoid any special directories, as well as the introduction of the new Web namespace convention to further signal that your Phoenix related web modules are the web interface into your greater Elixir application. Along with new project structure, comes new phx.gen.html and phx.html.json generators that adopt these goals of isolating your web interface from your domain.

Contexts

When you generate a HTML or JSON resource with phx.gen.html|json , Phoenix will generate code inside a Context, which is simply a well-named module, with well-named functions representing an API boundary to part of your application domain.

For example, to generate a “user” resource we’d run:

$ mix phx.gen.html Accounts User users email:string:unique

Notice how “Accounts” is a new required first parameter. This is the context module where your code will live that carries out the business logic of user accounts in your application. Here’s a peek at part of the code that’s generated:

# lib/my_app/web/controllers/user_controller.ex defmodule MyApp.Web.UserController do ... alias MyApp.Accounts def index(conn, _params) do users = Accounts.list_users() render(conn, "index.html", users: users) end def create(conn, %{"user" => user_params}) do case Accounts.create_user(user_params) do {:ok, user} -> conn |> put_flash(:info, "user created successfully.") |> redirect(to: user_path(conn, :show, user)) {:error, %Ecto.Changeset{} = changeset} -> render(conn, "new.html", changeset: changeset) end end ... end # lib/my_app/accounts/accounts.ex defmodule MyApp.Accounts do @moduledoc """ The boundary for the Accounts system. """ alias MyApp.Accounts.User def list_users do Repo.all(User) end def create_user(attrs \\ %{}) do %User{} |> user_changeset(attrs) |> Repo.insert() end ... end

You will also have an Ecto schema generated inside lib/my_app/accounts/user.ex . Notice how our controller calls into an API boundary to create or fetch users in the system. We are still using Ecto, but the database and application logic are separated. Our web-interface doesn’t need to know the details of the storage or DB representatin of our User. The Accounts module could internally store users in an agent, ETS, or elsewhere and our controller code remains untouched.

By asking users to think about the boundaries of their APIs, we end up with more maintainable, well structured code. Additionally, we can get a glimpse of what the application does and its feature-set just be exploring the application directory structure:

lib/my_app ├── accounts │ ├── user.ex │ └── accounts.ex ├── sales │ ├── ticket.ex │ ├── manager.ex │ └── sales.ex ├── repo.ex └── web ├── channels ├── controllers ├── templates └── views

With just a glance at the directory structure, we can see this application has a User Accounts system, as well as sales system. We can also infer that there is a natural boundary between these systems thru the sales.ex and accounts.ex modules. We can gain this insight without seeing a single line of code. Contrast that to the previous web/models , which did not reveal any relationship between files, and mostly reflected your database structure, providing no insight on how they actually related to your domain.

We are excited about these changes and their long-term payoff in maintainability. We also feel they’ll lead to sharable, isolated libraries that the whole community can take advantage of – inside and outside of Phoenix related projects.

If you have issues upgrading, please find us on #elixir-lang irc or slack and we’ll get things sorted out!

I would also like to give a special thank you to @wojtekmach for his help getting the new generators ready for prime-time. <3

Happy coding!

-Chris

Full changelog:

1.3.0-rc.0 (2017-03-01)