I have been struggling with getting ROM working, and I am still unable to get use_namespace
to result in objects being instantiated from my custom Entities
.
I am not sure of the causes, but I am wondering if use_namespace
could have a strict
option.
If I tell it to use_namespace
, and it can’t find anything in that namespace, I want it to blow up , not continue on silently with generic ROM Structs.
Is this already possible, and if so how?
I’m not aware of use_namespace
in ROM, do you mean struct_namespace
?
The structs that ROM produces are not business objects. They are not intended to have any strict validation at all. They are just data containers representing the result of a query.
Relations return plain hashes by default, but it’s more common to use simple objects with attribute readers to represent data in your application. These objects should be treated as pure data structures, that don’t have to be mutated at run-time, and don’t depend on any external systems (such as mailers, API clients, message buses etc.). Their methods should only deal with the attributes they encapsulate.
Core: Structs
This flexibility is necessary because ROM is explicitly not following an Active Record convention here, and so the shape of your structs are liable to change considerably depending on how you are querying the data and for what purpose.
If you want to define strictly validated business objects and produce them from ROM, you may want to use custom mappers instead of auto struct.
Yes, copy/paste > typing. I meant struct_namespace
.
We were hoping to use the custom structs as our business object shape definitions that can be shared between services that utilize them.
I’m still hoping to make that work, but now I’m not sure if having those “shape” models will be of any utility at all in the code.
If they are public API I strongly advise owning their definition. I write simple transformers between internal and external objects as needed.
They are not public. These are internal services in a very large SOA system, and many of the parts need to use these business objects. Many services will get the objects over HTTP (some daisy chained, multiple hops away from the SQL source), and one source-of-truth service will get them from SQL. I was thinking that the namespaced Entities Structs would be the appropriate place for sharing the object shapes, and that the HTTP and SQL relations/repositories would be able to instantiate them regardless of the source (HTTP or SQL). But that isn’t looking realistic anymore. Am I missing something?
The interface contract between services is public API, that’s what I was referring to. In other words, if you make fundamental changes to your database structure, does this require changing the API? It should not.
The HTTP object shapes can be shared. That is your contract. The SQL side of things should be kept internal, and allowed to change independently.
I don’t think ROM entities are the right choice for this API contract. The HTTP objects should be strictly validated, and ROM can map your data to those objects, or you can do your own transformations.
Right. Our database looks nothing like our API contract shapes. This is one of the major reasons why ROM is so attractive. We need to do a lot of mapping and transformations to get to our desired result. I’m now thinking that ROM::Transformer
is what I need.