Skip to content

Instantly share code, notes, and snippets.

@mmmries mmmries/A.md
Created Jun 7, 2018

Embed
What would you like to do?
A "Plug-ish" approach to flexible shared behavior

The main idea here is compose shared functionality into a pipeline of functions that all implement some shared behaviour.

defmodule Notification.Event do
  # The event (probably a bad name) is where you would put the structified JSON event you got from RabbitMQ
  defstruct [:sent_at, :user, :event]
end

defmodule Notification.Plug do
  @callback init(opts) :: opts
  @callback call(Notification.Event.t) ::
    :skip # halts processing early if we should not send anything
    | Notification.Event.t # continue processing with an updated Notification.Event.t
    | {:send_email, Notifications.Email.t, Notification.Event.t} # deliver an email to the user and continue processing with the new Notifiction.Event.t
    | {:send_sms, Notifications.SMS.t, Notification.Event.t} # deliver an sms to the user and continue processing with the new Notifiction.Event.t
end

defmodule Notifications.MattressShipped do
  plug CheckIfUserUnsubscribed
  plug CheckIfUserOptedIn, default: true
  plug SendMattressShippedEmail
  plug SendMattressShippedSMS
end

This lets us compose a different set of functionality for each type of event and it makes it easy for the team supporting this code to answer questions like, "is this notification opt-in or opt-out? Does it check for unsubscribed users?".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.