rom-rb / rom

Data mapping and persistence toolkit for Ruby
https://rom-rb.org
MIT License
2.07k stars 161 forks source link

Simplified runtime #653

Closed solnic closed 2 years ago

solnic commented 2 years ago

So, that's a lot, again 😅 The most significant improvement here is simplifying how configuration is merged/inherited. This stuff is very tricky due to backward-compat but at the same time it is actually a useful thing to support. Various DSLs can streamline setting things up and being able to automatically merge/compose/inherit settings is very nice.

This is hopefully the last big PR because I feel like the remaining work is going to be a bunch of small improvements and clean ups, which is exactly the same thing I said after the previous big PR 🤷🏻

Summary

Example

# Now the Configuration is called "Runtime" and the corresponding method is called the same
#
# This returns *an object* and it does not set any global variables during the setup process
#
# It's got the same API as the rom container but this time, again, it does not set any global
# variables. Previously during setup relation schemas would be set globally on Relations which
# was not cool. Now it's gone and this is *much more managable* and super flexible :)
#
rom = ROM.runtime(:sql, "postgres://postgres@db/rom") do |runtime|
  # You can now configure "global" settings for individual components :)
  #
  # ie this would change default relation namespace from "relations" to "stuff"
  #
  # runtime.config.relation.namespace = "stuff"

  runtime.relation(:users) do
    schema(infer: true)
  end

  runtime.relation(:tasks) do
    schema(infer: true)
  end
end

# Runtime registry is the root that can access all components
> rom
#<ROM::Registry type=root adapters=[:sql] keys=["gateways.default", "datasets.relation", "schemas.users", "schemas.tasks", "relations.users"]>

# You can ask for type-specific child registries too
> rom.relations
#<ROM::Registry type=relations adapters=[:sql] keys=["relations.users"]>

# Schemas are now even more 1st-class and accessible standalone too
> rom.schemas
#<ROM::Registry type=schemas adapters=[:sql] keys=["schemas.users", "schemas.tasks"]>

# Commands are empty by default if you didn't define anything custom (same with mappers)
> rom.commands
#<ROM::Registry type=commands adapters=[:sql] keys=[]>

# When you ask for a command...
> rom.relations[:users].command(:create)

# ...it's auto-compiled at runtime like before but now it's also stored in the runtime registry
> rom.commands
# <ROM::Registry type=commands adapters=[:sql] keys=["commands.users.create-compiled-3422153278252830503"]
paddor commented 6 months ago

How would multiple gateways actually be configured? For example one repository with two relations, each relation using a different gateway. This does not seem possible with 5.3.0.