wasyl
09/12/2025, 10:05 PMresponseBased codegen, and I've got an error that Apollo: responseBased codegen does not support @catch.
I'm not too familiar with the current nullability handling state, so just wanted to get some clarity on what to expect moving forward — I see there are some limitations to the responseBased codegen listed here, but nullability is not therembonnin
09/15/2025, 9:21 AMmbonnin
09/15/2025, 9:22 AMresponseBased codegen, my current idea is that we add features there once they have been proven successful on the operationBased codegen. Maintaining the experimental features in both codegen is going to be a lotmbonnin
09/15/2025, 9:23 AMwasyl
09/15/2025, 5:11 PMresponseBased codegen will remain a first-class citizen as nullability evolves, or we should better plan to migrate to operations based (or the new experimental one with interfaces) insteadwasyl
09/15/2025, 5:11 PMwasyl
09/15/2025, 5:12 PM@nonnull annotations if responseBased codegen is used? Since there's no migration path for them, and reponseBased itself isn't deprecatedmbonnin
09/15/2025, 5:22 PMmbonnin
09/15/2025, 5:23 PM@nonnull as @semanticNonNull is usually much bettermbonnin
09/15/2025, 5:25 PMresponseBased codegenmbonnin
09/15/2025, 5:26 PMwasyl
09/15/2025, 5:27 PM@nonnull, I'd do @catchByDefault(to: NULL) in the schema extension first (that's a no op) and then replace all the @nonnull in operations with @catch(to: THROW)?mbonnin
09/15/2025, 5:28 PMmbonnin
09/15/2025, 5:28 PM@semanticNonNull to responseBased codegenwasyl
09/15/2025, 5:30 PMmbonnin
09/15/2025, 5:32 PMmbonnin
09/16/2025, 5:10 PMmbonnin
09/16/2025, 5:11 PMresponseBased is not a great contender for @catch because merged field are required to have the same @catch directives. This is probably slow to validate and breaks fragment locality
2. I realized there's no strict equivalent to @nonnull when used in queries. @semanticNonNull works only in schemasmbonnin
09/16/2025, 6:28 PMwasyl
09/16/2025, 8:50 PMmerged field are required to have the samethis means that if I'm fetching the same field in multiple places, I need to declare the samedirectives. This is probably slow to validate and breaks fragment locality@catch
@catch directive on each instance of the same field? I don't think that's too bad, but just so I understand — it means that I can't have the same fragment used in two queries where the nullability behavior is different, right? E.g. I know in query A field foo/bar will not be null, but in query B the same field might be null because it's in a different context, I can't use the same fragment for both queries?
I realized there's no strict equivalent to @nonnull when used in queries. @semanticNonNull works only in schemasthis one I'm not sure I understand. I still can use
@catch(to: NULL) in executable documents/queries, but I need to define each field as @semanticNonNullField first? So basically for each field I need at least 1 extension in the schema, and then a @catch on each usage?mbonnin
09/16/2025, 9:21 PMit means that I can’t have the same fragment used in two queries where the nullability behavior is different, right?yup, exactly that
basically for each field I need at least 1 extension in the schema, and then aalso correct. Oneon each usage?@catch
@semanticNonNull for the field definition, one @catch(to: THROW) for fields that you want to be generated as non-null typeswasyl
09/16/2025, 9:23 PMoperationBased in that in operationBased I would opt-in to catch annotations globally and then be able to catch fields in operations, no need for schema extensions?mbonnin
09/16/2025, 9:23 PMoperationBased and responseBased are really similarmbonnin
09/16/2025, 9:23 PMoperationBased also needs a schema extensionmbonnin
09/16/2025, 9:24 PMmbonnin
09/16/2025, 9:25 PMmbonnin
09/16/2025, 9:25 PMwasyl
09/16/2025, 9:28 PM@catch on a field in a query, that field
• must be nullable in the schema
• can be inferred as semantically non null (otherwise I wouldn't @catch it)
• it would make some sense to default to @catch(to: NULL) for other usages of that field that don't have an explicit catchwasyl
09/16/2025, 9:29 PMoperationBased and responseBased nullability handling would be, after the PR you opened. As a client, in queries/schema, do I do anything differently between the two codegens?mbonnin
09/16/2025, 9:29 PM• must be nullable in the schemaRight, it must be nullable in the schema as in either
foo: Int or foo: Int @semanticNonNull because there will never be an error for foo: Int!mbonnin
09/16/2025, 9:30 PM• can be inferred as semantically non null (otherwise I wouldn’tNot really. If you haveit)@catch
title: Int (regular nullable, i.e. a video may not have a title), you may still want to @catch(to: RESULT) to handle that errormbonnin
09/16/2025, 9:31 PM• it would make some sense to default toI thinkfor other usages of that field that don’t have an explicit catch@catch(to: NULL)
@catchByDefault(to: NULL) does that?mbonnin
09/16/2025, 9:32 PM@catchByDefaultmbonnin
09/16/2025, 9:32 PM@catchByDefault(to: THROW) is probably the most correct one. @catchByDefault(to: NULL) is the compatible onembonnin
09/16/2025, 9:33 PM@catchByDefault(to: THROW)mbonnin
09/16/2025, 9:33 PMdifferences betweenMostly the same thingandoperationBasednullability handling would be, after the PR you opened. As a client, in queries/schema, do I do anything differently between the two codegens?responseBased
mbonnin
09/16/2025, 9:34 PMresponseBased at the time but it turned out to be quite simplewasyl
09/16/2025, 9:34 PMthe compatible oneas in, the one that no-ops compared to the schema/queries without any nullability annotation
mbonnin
09/16/2025, 9:34 PMwasyl
09/16/2025, 9:35 PMresponseBased does something different. But the only difference is the additional restrictions about having to match the @catch annotation for fields fetched multiple times, the thing you mentioned earlier
> merged field are required to have the same @catch directives.mbonnin
09/16/2025, 9:36 PMresponseBased so it will hapen probably morembonnin
09/16/2025, 9:37 PM{
...queryDetails
foo @catch(to: NULL)
}
fragment queryDetails on Query {
foo: @catch(to: RESULT)
}mbonnin
09/16/2025, 9:37 PMresponseBased while it’s ok for operationBasedmbonnin
09/16/2025, 9:38 PMoperationBased codegenwasyl
09/16/2025, 9:38 PM@nonnull 🙂mbonnin
09/16/2025, 9:39 PMwasyl
09/16/2025, 9:39 PMmbonnin
09/16/2025, 9:39 PMmbonnin
09/16/2025, 9:39 PMwasyl
09/16/2025, 9:40 PMmbonnin
09/16/2025, 9:42 PMwasyl
09/16/2025, 9:43 PMwasyl
09/16/2025, 9:44 PMmbonnin
09/16/2025, 9:44 PM