Phoenix contexts

Phoenix 1.3 uses a domain based development system where the different parts of the app are grouped in contexts/domains. See contexts for documentation.

Using contexts

We group our functions into context modules based on which part of the app they are found.

defmodule App.Accounts do
  # All the functions pertaining to account management

  def create_user(params) do
    # code for creating users
  end
end

Resolvers

It is harder to maintain a context module because placing all the functions in one module can grow big very quickly.

To make code maintainance easier, we separate functions into resolvers based on the GraphQL structure. In the context module, we just delegate functions to the resolvers.

defmodule App.Accounts.Resolvers.UserResolver do
  def create_user(params) do
    # code for creating users
  end

  # other functions pertaining to user management and user helper functions
end
defmodule App.Accounts.Resolvers.ProfileResolver do
  def update_profile(user, params) do
    # code for updating a users profile
  end

  # other functions pertaining to profile management and profile helper functions
end
defmodule App.Accounts do
  alias App.Accounts.Resolvers.{
    UserResolver,
    ProfileResolver
  }

  # This group contains functions in the UserResolver module
  defdelegate create_user(params), to: UserResolver

  defdelegate update_profile(user, params), to: ProfileResolver
end

Suggested file structure

Put your contexts as lib/contextname/. In this example below, our Accounts context belongs in lib/accounts/.

App
|  lib
|    accounts/
|      resolvers/
|        user_resolver.ex
|        profile_resolver.ex
|      accounts.ex