Just got around to checking 3.6 out, and I was che...
# apollo-kotlin
s
Just got around to checking 3.6 out, and I was checking out Data builders and I had some questions. 1. Is the idea for Data builders to completely replace test builders or would they both live in parallel to achieve different goals? 2. When using data builders, I seem to have complete access to all possible fields in the generated
QueryBuilder
, at least on the first level. Meaning I could try and assign the wrong field inside my lambda. I assume this is normal and simply a tradeoff of data builders vs test builders which don’t let you assign the wrong fields in the type of object you want to create right? After going 1 level deep with
buildX
though then it’s all type-safe as far as I can tell so that’s great.
But damn this is such a nice QoL improvement overall! Got one example in [pic attached]. No more manually writing in the __typename, more descriptive
buildX
names for creating the objects (no longer confusing with the type itself) and I can simply pass in the
LocalDate
without having to use the adapter which we are using for this type to kinda hack my way into using the type and turning it into a JSON String. Just had to change my fake resolver to avoid initializing lists from
Copy code
@OptIn(ApolloExperimental::class)
object TestDataTestResolver : DefaultTestResolver() {
  override fun resolveListSize(path: List<Any>): Int {
    return 0
  }
}
to
Copy code
object TestFakeResolver : FakeResolver by DefaultFakeResolver(__Schema.all) {
  override fun resolveListSize(context: FakeResolverContext): Int {
    return 0
  }
}
And that was it, it seems to just work 🤯 Never fail to impress me with the stuff you folks are doing!
m
1. Is the idea for Data builders to completely replace test builders or would they both live in parallel to achieve different goals?
I think we want to remove the test builders eventually because they are response based and are therefore prone to the exponential blowup issue
2. Meaning I could try and assign the wrong field inside my lambda. I assume this is normal and simply a tradeoff of data builders vs test builders which don’t let you assign the wrong fields in the type of object you want to create right
Yes, data builders are not as type safe because they are generated once for the schema (and not per-operation)
There are a few things that still need to be ironed out (here and here). So expect a few changes but overall quite happy with the schema-based fakes so far
It's all a tradeoff ultimately 1. schema based (data builders) is more simple to understand but not 100 typesafe 2. response based (test builders) is typesafe but forces you to force a __typename for abstract fields and prone to exponential blowup 3. response based isn't great because it's more or less back to calling the data models constructors manually
s
Alright yeah, makes sense, I guess I can try and see if our build times blow up too, but we don’t have well organized historical data to really compare it with 😬 I can try and read that entire thread to get some ideas how to do it maybe. But for this tradeoff, from my experience I’d rather get this 1 layer of type-unsafety since all steps after that using the
buildX
functions is type-safe, so it shouldn’t be a big issue.
m
all steps after that using the
buildX
functions is type-safe
sorry to disappoint but it's not 🙈
s
Uhmm, maybe I misunderstood this part hmm
m
I mean for each composite object, you can add fields that are not used in a specific operation
So the type is safe but nothing prevents you to add more data than what is really needed (or omit some in which case it will be fake)
The plan ultimately there is to use the strict mode that @wasyl mentioned a long time ago
s
Aha yeah that part I understand. I was mostly referring to if I do like
upcomingAgreementDetailsTable = buildTable {
it works, but if I try and do
upcomingAgreementDetailsTable = buildContract {
it doesn’t let me, since the return types are wrong. I understand the over or under adding fields. But tbf in test builders you also had the problem of not adding fields and then they’d auto-generate something for you isn’t that true?
m
Yes, true but you couldn't over-add
Once we have strict mode, we can fail at runtime for over-additions
(if that's ever an issue 🤷 )
s
Awesome, I got a better understanding now then. The future does indeed look bright in this case! I guess it’d be an issue if you add something, then the schema changes, and the item is removed and you’re still defining it. Mostly a code maintenance burden, not a correctness issue I guess.
m
Exactly!
s
Leaving this here for if someone is curious how the difference looks like in some real app example https://github.com/HedvigInsurance/android/pull/1218/files I didn’t realize it initially but as I said above the
build
prefix really helps me mentally differentiate which one is which. I felt like needing to use
this.
before as can be seen on that PR, but not anymore.