Skip to content

Instantly share code, notes, and snippets.

@vizvamitra
Last active April 11, 2025 23:58
Show Gist options
  • Select an option

  • Save vizvamitra/d215cae0721d16cd53d65be129a3e20e to your computer and use it in GitHub Desktop.

Select an option

Save vizvamitra/d215cae0721d16cd53d65be129a3e20e to your computer and use it in GitHub Desktop.
# A subdomain namespace
#
module Warehouse
# Simple PORO that doesn't have to have any fancy stuff to enforce types.
# Private to the subdomain. Implement the actual logic
#
class CreateOrder
def call(public_id:, items:)
# ...
end
end
# Public interface of the subdomain, that exposes all the posible actions
#
class Interface < BaseInterface
# Creates a #create_order method that uses a given contract to validate
# inputs in runtime, then calls `Warehouse::CreateOrder.new.call(**itput)`
#
exposes :create_order, Warehouse::CreateOrder do
param :public_id, Integer
param :items, Array do
param :sku, String
param :quantity, Integer
end
end
end
end
# Another subdomain namespace
#
module Store
class PlaceOrder
# Injects the DSL below
include CrossSubdomainCalls
# Creates a `#warehouse_create_order` method that that uses a given
# contract to validate inputs in runtime, then calls
# `Warehouse::Interface.new.create_order(**itput)`
#
accesses :warehouse, :create_order do
param :public_id, Integer
param :items, Array do
param :sku, String
param :quantity, Integer
end
end
def call(customer_id:, order_id:)
# ...
warehouse_create_order(
public_id: order.public_id,
items: order.items.map { |i| { sku: i.sku, quantity: i.quantity } }
)
# ...
end
end
end
# Since both declarations are happening at boot time, we can match them and
# see if there are any incompatibilities. In that case, we can blow up, preventing
# the app from booting and test suite -- from running
#
# Another benefit is that since you are creating metadata with those calls,
# you know exactly who calls your entrypoints, and you could even do something
# like `Warehouse.clients` and get something like:
#
# {
# create_order: [Store::PlaceOrder, ...],
# ...
# }
#
# As an improvement, would be also nice to restrict the value types with simple
# ruby types only, and to restrict the return values in the same way somehow, to
# prevent passing complex objects between subdomains
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment