Hanami 1.3 > Hanami 2.2 : tips & notes about my journey

Use case #2: slice based application, only start one slice at the time

I like monoliths when it comes to code base sharing, but I prefer spawing individual services (app / api / backoffice / pdf renderer… etc) for the run (dev or prod, doesn’t matter)

With Hanami 1.3 I’ve been doing that from the beginning by using the different apps (subfolder of apps directory)

With Hanami 2, obviously the slices are made for that. But I’ve came to the point where my app is almost empty, and I want to only start individual slices.

Here is how I did that (a bit simplified for the sake of example)

# config/routes.rb
# frozen_string_literal: true

module MyApp
  class Routes < Hanami::Routes
    
    if ENV["HANAMI_SLICES"] == "api"
      slice :api, at: "/" 
    elsif ENV["HANAMI_SLICES"] == "backoffice"
      slice :backoffice, at: "/"
    end
    
  end
end
# slices/api/config/routes.rb
# frozen_string_literal: true
require_relative "../middlewares/rack_global_error_handler" # an example of a custom middleware

module API
  class Routes < Hanami::Routes

    # Here is how I inject my custom middleware in the stack
    use API::Middlewares::RackGlobalErrorHandler

    # We are interested in the body of the request
    use :body_parser, :json

    scope 'api' do
      scope 'v1' do
        get  "/status", to: "v1.utils.status", as: :utils_status # pointing to an action in my slice
      end
    end
    
  end
end

Then we need to tweak Procfile a little bit by defining specific targets

#Procfile.dev
api: HANAMI_PORT=2303 bundle exec hanami server
backoffice: HANAMI_PORT=2308 bundle exec hanami server
assets: bundle exec hanami assets watch

And finally we adjust foreman launching to adapt to the slice we want to launch:

# bin/dev
#!/usr/bin/env sh

if ! gem list foreman -i --silent; then
  echo "Installing foreman..."
  gem install foreman
fi

# API slice does not need assets watching
if [ "$HANAMI_SLICES" = "api" ]; then
  FOREMAN_ASSETS=""
else
  FOREMAN_ASSETS=",assets=1"
fi

FOREMAN_M="$HANAMI_SLICES=1$FOREMAN_ASSETS"

exec foreman start -f Procfile.dev "$@" -m $FOREMAN_M

You can then launch the api slice alone :tada:

HANAMI_SLICES=api bundle exec hanami dev

Or the backoffice slice, which will include assets watching, with:

HANAMI_SLICES=backoffice bundle exec hanami dev
2 Likes