mjml-remote-rails
Based on mjml-rails, this gem offloads
the actual MJML processing to a microservice (e.g a lambda function). If the
microservice returns an error, Mjml::Remote::Template::ParseError will be
raised.
See mjml-lambda for an example lambda function that will do it.
Installation
Add this line to your application's Gemfile:
gem 'mjml-remote-rails'
And then execute:
$ bundle
Or install it yourself as:
$ gem install mjml-remote-rails
Configuring
Mjml::Remote.setup do |setup|
# Override template language - default is erb
config.template_language = :haml
# config.endpoint is required!
config.endpoint = "https://<some-server/<some-endpoint>"
# headers for the requests can be set - default is no headers
config.headers = { "x-api-key" => "some header based authentication" }
end
...why?!
Calling MJML from ruby is pretty heavy memory-wise and threw a major spanner in the works of our heavily multi-threaded background job workers when lots of emails were being processed. Installing the mjml binary also added a decent amount of weight to our docker containers once you factored in the other dependencies you need.
Moving the actual MJML processing to a lambda function means we don't need to worry about this any more, and as all our email processing is backgrounded anyway, it won't really make much of a difference to our users.
Falling back to regular MJML in development
Gemfile
group :production do
gem "mjml-remote-rails"
end
group :development do
gem "mjml-rails", require: false
gem "mjml-remote-rails", require: false
end
config/application.rb at the top after requiring rails:
if ENV["MJML_ENDPOINT"]
require "mjml-remote-rails"
else
require "mjml-rails"
end
config/initializers/mjml.rb
if Rails.env.production? || ENV["MJML_ENDPOINT"]
Mjml::Remote.setup do |config|
...
end
else
Mjml.setup do |config|
...
end
end