Rails Engines have been around for a quite a while. Many of the popular Gems (Devise, etc) that we work with through our day-to-day as a Rails developer are actually Rails Engines. The purpose of these Rails Engines is to provide additional tools/techniques to help developers divide up their Rails application into a subset of functionality. This could be moving a blogging engine out into a separate Gem or moving common controllers/models/services to a separate code base in preperation to extract the code into a Microservice.
This tutorial will be a series of tutorials to help take a normal Rails application and move it into a Microservice.
In this tutorial, I'll divide up a Rails application into separate Engines for creating boundaries around Rails services. I'll start with a simple example of having a Invoicer that builds Invoices and slowly expand it throughout the series.
Let's get started!
First we'll create some basic code that we can play with and use throught the series.
rails new engine_example
cd engine_example
git commit -am 'initial commit'
If you are using Rails 5.2.2 fix the sqlite3 issue before going farther.
With this committed we have a good foundation for experimentation. At anytime we can easily clean the repo and start over via:
git reset --hard # cleans any working directory changes
git clean -f -d # cleans up any non-tracked files
Let's start by creating an engine called Invoices:
rails plugin new invoices
You'd think the command would be
rails engine new invoices
but it's not, it's considered aplugin
.
Let's try to access the Invoices engine from the parent application.
DISABLE_SPRING=1 bundle exec rails c
> Invoices::VERSION
=> "0.1.0"
While this works, it's a bit ugly and is just sitting in the projects root directory.
This won't scale if we keep putting engines into the project root.
So let's do something about this.
The norm that I usually use is putting Engines
in an /engines
directory.
mkdir engines
mv invoices engines/
sed -i "s/path: 'invoices'/path: 'engines\/invoices'/" Gemfile
DISABLE_SPRING=1 bundle exec rails c
> Invoices::VERSION
=> "0.1.0"
Awesome, this still works. You are on your way to writing Microservices.
In this tutorial we ended up creating a new Rails application and a new Rails Engine.
We showed the process on how to access an Engine
from within the Rails application.
For the next tutorial we will take you through the process of adding a new service to the Engine
and how to access it from the parent application.
If you are more of a visual person then here is terminal session of me doing the above.