Phoenix Context connection struct best practice

I would love to hear other opinions on this, but I think the key thing here would be that the contexts do not specifically know about %Plug.Conn.

You definitely don’t want this context function signature…

def create(%Plug.Conn{} = conn)

You could be less specific about it and grab things out of a struct that just happens to have the same structure as a conn if it really makes sense for your context API, but it almost surely does not…

def create(%{assigns: %{organization: organization, user: user, token: token}})

However, this is coupled to the structure of a conn and doesn’t seem like clean arguments for the context function.

You could pass just the assigns so as not to reach deeply into the struct…

def create(%{organization: organization, user: user, token: token})

But you are still reliant on how the conn is built up on the web side of your app and it is still arguable whether this is a clean way to take arguments in the context function.

Try to imagine you didn’t have a web interface for your app at all and were only designing the context function. How would you want the function signature to operate? Let that dictate what/how arguments are passed in.

For instance, maybe a function signature like this makes more sense in your app…

def create(%Organization{} = organization, %User{} = user, token})

This should be more resistant to breakage due to changes in the controller because you will have been explicit of the needs of the function at the boundaries.