-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Object embedding should be its own middleware #11
Comments
This allows middlewares that are further up the stack to use the modifications that Conductor makes (such as embedding objects). This necessity of this might change, though. See #11.
Agreed. I was reading through Conductor yesterday because I need to check which events triggered associations, and I think it'd fit in better as its own middleware. It'd certainly make it easier to ascertain how associations are made from the code. |
After writing a bit of the implementation, I think it makes more sense to place this new middleware after Conductor in the stack. That way, any events that Conductor fires will also go through the embedding process, making the events that get published more consistent. So now, the stack is
|
Includes the definition of the ObjectEmbed class, as well as a configuration file and additions to the citybus configuration to use the middleware.
See #11. Having ObjectEmbed come after Conductor ensures that objects are embedded appropriately in all events that come out from the system. Since Conductor is responsible for publishing new events based on existing ones, if ObjectEmbed were to come before it, then those new events would either not have embedded objects, or Conductor would have to embed them manually (neither of which is a good solution).
Having gotten most of the way through the implementation for this, I'm thinking have a more-generic So, my proposal is to change I like the idea of having the serialization be something that an Object does itself. The On the other hand, I don't like the idea of having serialization handled by Object classes because it's a bundling of view logic into a model. Not that it's necessarily terrible, but the two are rather unrelated. The only actual advantage I can currently see to having it in the Object classes is better obeying the Lawguideline of Demeter, since almost all of the necessary attributes will be directly accessible. The advantages to having serialization logic managed externally include unbundling/isolating the serialization logic, and better configurability (with tl;dr: |
That makes sense to me. Since all serialized views from Shark represent a single object, it doesn't feel like you are bundling in any logic that isn't already directly related to the object's properties. |
My qualm with having it as part of For example, a Route object as a top-level argument will be serialized with all of its attributes and its associated objects. However, when it is embedded inside a Vehicle object, it only includes a few attributes (identifier, name, short_name, color) and does not include its associated objects. This context dependency seems to mean that I'm still a little torn on where the implementation should go, but I'm going to try writing it as part of |
Per #11, the `ObjectEmbed` middleware is more aptly named `Serializer`, since object embedding has no actual effect until an Object is serialized, meaning the middleware would be serializing objects before doing any embedding. Classifying the middleware as `Serializer` covers this process semantically, and generalizes the middleware, allowing it to do more than just embed objects (though, it probably won't any time soon).
Alright. I'm not entirely convinced that having serialization inside of
The advantage to this approach is simplicity: All native Ruby objects (numerics, strings, arrays, etc.) have a default |
Once again, I'm having different thoughts now.
However, native objects do not implement
With that, I'm debating whether While it provides opt-in functionality and a nice, isolated configuration scheme, it really doesn't do much, since the WAMP client expects plain objects and calls I think I'm going to try adding Shark::Object.configure do |config|
...
### Serialization ###
# Set to true to embed all objects in a one-to-many association. For example:
# when true, a Route will embed object information for each Station in its
# `stations` attribute; when false, the attribute would be kept as a list of
# identifiers.
config.embed_has_many_associations = true
# The number of levels through which object embedding will occur.
# A value of 0 will perform no embedding on Objects.
# A value of 1 will embed Objects that are direct attributes of an Object.
# Values higher than 1 will embed further-nested Object attributes.
config.embed_depth = 1
end For special cases, the configuration can be overwritten both at the class level, and the instance level: # Class-level specialization
Shark::Route.configure do |config|
config.embed_has_many_associations = false
end
# Instance-level specialization
vehicle = Shark::Vehicle.new
vehicle.configure do |config|
config.embed_depth = 3
end These options will all get parsed by the |
The `ObjectSerialization` module includes all of the logic necessary for serializing objects, including configurability through a number of options (outlined in `config/serialization.rb`). Somewhat awkwardly, `Object` is now indirectly tied to `Storage`, which means that a given Shark instance can only use one Storage instance. This was already the case, but by choice, not by requirement (though, having different adapters for a given instance would be rather odd. Sharding, for example, should be taken care of by the adapter itself, rather than configuration).
Closed by #18. |
While it makes sense to embed objects in Conductor (as it is the reason that embeds need to exist), it makes more sense to me that embedding takes place in a separate middleware, that would go before Conductor in the stack.
My current reasoning is this:
The text was updated successfully, but these errors were encountered: