Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider following plug conventions and implementing pipeline/pipe macros #30

Open
sitch opened this issue Aug 18, 2017 · 3 comments
Open

Comments

@sitch
Copy link

sitch commented Aug 18, 2017

Consider following plug conventions:init/1 and call/2. Also would be more natural to have pipeline/pipe macros. I.e.:

defmodule MyApp.MyEvent do
  use Ravenx.Pipeline
  use MyApp.PhoenixSlackPipe, view: MyApp.SlackView, template: "new_slack_event.text"
  use MyApp.PhoenixEmailPipe, view: MyApp.EmailView, template: "new_email_event.text"

  pipe :slack, channel: "events", async: true
  pipe :email, contact: & &1.assigns.user.email, subject: &"Welcome #{&1.assigns.user.name}"

  def call(pipeline, _opts, payload) do
    user = MyApp.Repo.preload(payload, :friends)
    pipeline.assign(:user, user)
  end
end

and for a pipe:

defmodule MyApp.PhoenixSlackPipe do
  use Ravenx.Pipe
  use MyApp.PhoenixSlack # `channel/2`, `render_title/2`, `render_body/3`, `send/1`

  def init(_pipeline, options) do
    options
  end

  def call(pipeline, options) do
    pipeline
    |> channel(options[:channel])
    |> render_title(options[:title])    
    |> render_body(options[:view], options[:template]) # renders with `pipeline.assigns`
    |> send
  end
end

This type of design would make it so you don't have to load strategies in your config (which doesn't seem necessary), instead you just use them in your Pipe files.

@odarriba
Copy link
Member

Hi @sitch !

First of all, thanks a lot for sharing the idea. We think it's amazing and it's definitively the way we should focus the next major release of Ravenx.

This change alongside with #28 to reduce unnecessary dependencies are two improvements that can make this library a better one.

If you feel comfortable to participate in the development, you are more than welcome. Otherwise don't worry, the fact of giving us the idea is more than enough.

Thanks! ❤️

@sitch
Copy link
Author

sitch commented Aug 21, 2017

Thanks :) Take a look at https://github.com/appunite/piper

@odarriba
Copy link
Member

odarriba commented Sep 2, 2017

Thinking about the approach we can take on this, these are the ideas that came up to my mind (are a version of what was firstly exposed by @sitch)

defmodule MyApp.Notifications.NewEvent do
  use Ravenx.Pipeline

  @slack_config [
    view: MyApp.NotificationsView, 
    template: "slack_event.text", 
    channel: "events", 
    async: true
  ]

  @email_config [
    view: MyApp.NotificationsView, 
    template: "email_event.text",
    subject: &("Welcome #{&1.assigns.user.name}")
  ]

  pipe MyApp.SlackStrategy, @slack_config
  pipe MyApp.EmailStrategy, @email_config

  def init do
    []
  end

  def call(instance, _opts, payload) do
    user = MyApp.Repo.preload(payload, :friends)
    instance.assign(:user, user)
  end
end
defmodule MyApp.SlackStrategy do
  use Ravenx.Pipe
  use Ravenx.Strategies.Slack # `channel/2`, `render_title/2`, `render_body/3`, `send/1`

  def init(opts) do
    options
  end

  def call(instance, opts) do
    instance
    |> channel(opts[:channel])
    |> render_title(opts[:title])    
    |> render_body(opts[:view], opts[:template])
    |> deliver
  end
end

The app's strategies are intended to be a custom configuration (and use) of the integration itself, specifying how a (for example, Slack) integration is built in the app itself.

And the Ravenx.Strategies.Slack should integrate the helper functions used to fill the instance data and the deliver function.

The Ravenx.Pipeline macro will inject the deliver and deliver_async methods in the notification modules.

Also, the init methods will be evaluated on compile time, so they can be used, like in Plug library, to pre-calculate configurations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants