Should we stop passing activerecord objects between components and use poro's or ids instead?

This message was imported from the Ruby/Rails Modularity Slack server. Find more info in the import thread.

Message originally sent by slack user U783ITZM13O

I’m still wondering if you are all now stopped passing activerecord objects between components and. now use poro’s or ids really

Message originally sent by slack user U783MOJYF8Z

We’re doing less of that, but neither POROs nor IDs are good enough in the general case

Message originally sent by slack user U783MOJYF8Z

We’re still working on getting a really good solution here.

Message originally sent by slack user U783MOJYF8Z

The main problem is in serving our graphQL API, which needs to be able to dynamically and efficiently execute pretty much arbitrary queries across all components

Message originally sent by slack user U783UION177

Our approach is to model the use cases of our modules as commands and queries. These become the api of our modules. Our GraphQL API sits on top of this.

Message originally sent by slack user U783UION177

Emile, in our approach AR never leaves the module, only simple data structures.

Message originally sent by slack user U783ITZM13O

<@U783UION177> is that something you have working right now or something you’d like to work towards. Because i’ve experimenting with this a lot. And wondering how that works in practicality

Message originally sent by slack user U78EKGG059M

Our approach is AR models do not leave the bounded context - when returning cross-boundary objects we use value objects using the ValueSemantics gem

Message originally sent by slack user U783MOJYF8Z

<@U783UION177> I’m super curious as to how that works for batched queries. Can you share more?

Message originally sent by slack user U783MOJYF8Z

Like, give me the first 100 cars with all their tires, when cars and tires are in separate modules

There are ways to make this work as an efficient query, but I find none of them to be obviously good choices

Message originally sent by slack user U783ITZM13O

<@U78EKGG059M> Would be awesome if you could show some examples at some point!

Message originally sent by slack user U783UION177

It is something we have working now, but it’s still early days. We have pushed batch loading into our queries, which can be used by GQL and restful endpoints.

Message originally sent by slack user U783ITZM13O

<@U783MOJYF8Z> should the api’s not just support batch getting get_tire_by_ids(ids:) returns dumb tire obj.

Message originally sent by slack user U783MOJYF8Z

<@U783ITZM13O> how do you determine the ids of the tires to load?

Message originally sent by slack user U783ITZM13O

Ah right, magic ofc.

Message originally sent by slack user U78EKGG059M

<@U783ITZM13O> we will definitely have something to share in the near future. Right <@U78EPEM2PY0>

Message originally sent by slack user U783UION177

<@U783MOJYF8Z> So in your example we would call the CarsQuery of the Cars module and in the tires resolver of the cars output type, we’d call the TiresQuery of the Tires module. Since all of our queries are batch loaded, we avoid the n+1s in the TiresQuery. Does that make sense?

Message originally sent by slack user U783MOJYF8Z

Since all of our queries are batch loaded
Not sure I understand what you mean by that.

To narrow it down, can you guarantee a maximum of one DB query per table and graphql query? Do you use lazy evaluation like https://github.com/Shopify/graphql-batch?

Message originally sent by slack user U783MOJYF8Z

We’ve thought about custom batch loaders per entity (and actually have some of those) which I think would be close to what you’re describing

Message originally sent by slack user U783MOJYF8Z

In general, and all of our legacy code, we have implicit batch loaders that are generalized for active record (which I want to completely replace)