From 6c4259b913eeb7732f1aedb842f218a47f63a954 Mon Sep 17 00:00:00 2001 From: "John P. Vajda" Date: Fri, 24 Jun 2022 11:56:31 -0600 Subject: [PATCH 1/4] emptye From fe096176888f329344f81888ac4ce4f1a351fd81 Mon Sep 17 00:00:00 2001 From: "John P. Vajda" Date: Fri, 15 Jul 2022 16:06:51 -0600 Subject: [PATCH 2/4] documented typePolicy inheritance --- docs/source/caching/cache-configuration.mdx | 55 +++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/docs/source/caching/cache-configuration.mdx b/docs/source/caching/cache-configuration.mdx index 2943ad5adea..b7db4a5e07d 100644 --- a/docs/source/caching/cache-configuration.mdx +++ b/docs/source/caching/cache-configuration.mdx @@ -313,3 +313,58 @@ For most objects in a graph, the `__typename` field is vital for proper identifi ### The `fields` property The final property within `TypePolicy` is the `fields` property, which enables you to [customize the behavior of individual cached fields](./cache-field-behavior). + +## TypePolicy inheritence + +JavaScript developers will be familiar with the idea of [inheritance](https://en.m.wikipedia.org/wiki/Inheritance_(object-oriented_programming)) from the `extends` clause of `class` declarations, or possibly from dealing with prototype chains created by `Object.create`. + +Inheritance is a powerful code-sharing tool, and it works well for Apollo Client for several reasons: + + * `InMemoryCache` already knows about the supertype-subtype relationships (_interfaces and unions_) in your schema, thanks to `possibleTypes`, so no additional configuration is necessary to provide that information. + + * Inheritance allows a supertype to provide default configuration values to all its subtypes, including `keyFields` and individual field policies, which can be selectively overridden by subtypes that want something different. + + * A single subtype can have multiple supertypes in a GraphQL schema, which is difficult to model using the single inheritance model of classes or prototypes. In other words, supporting multiple inheritance in JavaScript requires building a system something like this one, rather than just reusing built-in language features. + + * Developers can add their own client-only supertypes to the `possibleTypes` map, as a way of reusing behavior across types, even if their schema knows nothing about those made-up supertypes + + * The `possibleTypes` map is currently used only for fragment matching purposes, which is an important but fairly small part of what the client does. Inheritance adds another compelling use for `possibleTypes`, and should drastically reduce repetition of `typePolicies` when used effectively. + +Here's how type policy inheritance works for `InMemoryCache`, considering the example below: + +```ts +const cache = new InMemoryCache({ + possibleTypes: { + Reptile: ["Snake", "Turtle"], + Snake: ["Python", "Viper", "Cobra"], + Viper: ["Cottonmouth", "DeathAdder"], + }, + + typePolicies: { + Reptile: { + // Suppose all our reptiles are captive, and have a tag with an ID. + keyFields: ["tagId"], + fields: { + // Scientific name-related logic can be shared among Reptile subtypes. + scientificName: { + merge(_, incoming) { + // Normalize all scientific names to lower case. + return incoming.toLowerCase(); + }, + }, + }, + }, + + Snake: { + fields: { + // Default to a truthy non-boolean value if we don't know + // whether this snake is venomous. + venomous(status = "unknown") { + return status; + }, + }, + }, + }, +}); +``` + From d13ceb18eff3c03d39b08cca288dd744cedfd300 Mon Sep 17 00:00:00 2001 From: "John P. Vajda" Date: Mon, 18 Jul 2022 11:24:19 -0600 Subject: [PATCH 3/4] moves content to advanced topics --- docs/source/caching/advanced-topics.mdx | 54 +++++++++++++++++++++ docs/source/caching/cache-configuration.mdx | 54 --------------------- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/docs/source/caching/advanced-topics.mdx b/docs/source/caching/advanced-topics.mdx index 655ca26222e..849395ab087 100644 --- a/docs/source/caching/advanced-topics.mdx +++ b/docs/source/caching/advanced-topics.mdx @@ -106,6 +106,60 @@ export class Foo extends Component { export default withApollo(Foo); ``` +## TypePolicy inheritence + +JavaScript developers will be familiar with the idea of [inheritance](https://en.m.wikipedia.org/wiki/Inheritance_(object-oriented_programming)) from the `extends` clause of `class` declarations, or possibly from dealing with prototype chains created by `Object.create`. + +Inheritance is a powerful code-sharing tool, and it works well with Apollo Client for several reasons: + + * `InMemoryCache` already knows about the supertype-subtype relationships (_interfaces and unions_) in your schema, thanks to `possibleTypes`, so no additional configuration is necessary to provide that information. + + * Inheritance allows a supertype to provide default configuration values to all its subtypes, including `keyFields` and individual field policies, which can be selectively overridden by subtypes that want something different. + + * A single subtype can have multiple supertypes in a GraphQL schema, which is difficult to model using the single inheritance model of classes or prototypes. In other words, supporting multiple inheritance in JavaScript requires building a system something like this one, rather than just reusing built-in language features. + + * Developers can add their own client-only supertypes to the `possibleTypes` map, as a way of reusing behavior across types, even if their schema knows nothing about those made-up supertypes + + * The `possibleTypes` map is currently used only for fragment matching purposes, which is an important but fairly small part of what the client does. Inheritance adds another compelling use for `possibleTypes`, and should drastically reduce repetition of `typePolicies` when used effectively. + +Here's how type policy inheritance works for `InMemoryCache`, considering the example below: + +```ts +const cache = new InMemoryCache({ + possibleTypes: { + Reptile: ["Snake", "Turtle"], + Snake: ["Python", "Viper", "Cobra"], + Viper: ["Cottonmouth", "DeathAdder"], + }, + + typePolicies: { + Reptile: { + // Suppose all our reptiles are captive, and have a tag with an ID. + keyFields: ["tagId"], + fields: { + // Scientific name-related logic can be shared among Reptile subtypes. + scientificName: { + merge(_, incoming) { + // Normalize all scientific names to lower case. + return incoming.toLowerCase(); + }, + }, + }, + }, + + Snake: { + fields: { + // Default to a truthy non-boolean value if we don't know + // whether this snake is venomous. + venomous(status = "unknown") { + return status; + }, + }, + }, + }, +}); +``` + ## Refetching queries after a mutation In certain cases, writing an `update` function to [update the cache after a mutation](../data/mutations/#updating-local-data) can be complex, or even impossible if the mutation doesn't return modified fields. diff --git a/docs/source/caching/cache-configuration.mdx b/docs/source/caching/cache-configuration.mdx index b7db4a5e07d..730ac1830c4 100644 --- a/docs/source/caching/cache-configuration.mdx +++ b/docs/source/caching/cache-configuration.mdx @@ -314,57 +314,3 @@ For most objects in a graph, the `__typename` field is vital for proper identifi The final property within `TypePolicy` is the `fields` property, which enables you to [customize the behavior of individual cached fields](./cache-field-behavior). -## TypePolicy inheritence - -JavaScript developers will be familiar with the idea of [inheritance](https://en.m.wikipedia.org/wiki/Inheritance_(object-oriented_programming)) from the `extends` clause of `class` declarations, or possibly from dealing with prototype chains created by `Object.create`. - -Inheritance is a powerful code-sharing tool, and it works well for Apollo Client for several reasons: - - * `InMemoryCache` already knows about the supertype-subtype relationships (_interfaces and unions_) in your schema, thanks to `possibleTypes`, so no additional configuration is necessary to provide that information. - - * Inheritance allows a supertype to provide default configuration values to all its subtypes, including `keyFields` and individual field policies, which can be selectively overridden by subtypes that want something different. - - * A single subtype can have multiple supertypes in a GraphQL schema, which is difficult to model using the single inheritance model of classes or prototypes. In other words, supporting multiple inheritance in JavaScript requires building a system something like this one, rather than just reusing built-in language features. - - * Developers can add their own client-only supertypes to the `possibleTypes` map, as a way of reusing behavior across types, even if their schema knows nothing about those made-up supertypes - - * The `possibleTypes` map is currently used only for fragment matching purposes, which is an important but fairly small part of what the client does. Inheritance adds another compelling use for `possibleTypes`, and should drastically reduce repetition of `typePolicies` when used effectively. - -Here's how type policy inheritance works for `InMemoryCache`, considering the example below: - -```ts -const cache = new InMemoryCache({ - possibleTypes: { - Reptile: ["Snake", "Turtle"], - Snake: ["Python", "Viper", "Cobra"], - Viper: ["Cottonmouth", "DeathAdder"], - }, - - typePolicies: { - Reptile: { - // Suppose all our reptiles are captive, and have a tag with an ID. - keyFields: ["tagId"], - fields: { - // Scientific name-related logic can be shared among Reptile subtypes. - scientificName: { - merge(_, incoming) { - // Normalize all scientific names to lower case. - return incoming.toLowerCase(); - }, - }, - }, - }, - - Snake: { - fields: { - // Default to a truthy non-boolean value if we don't know - // whether this snake is venomous. - venomous(status = "unknown") { - return status; - }, - }, - }, - }, -}); -``` - From 1fef842905658187324ae2bf6428c9be38e7ce96 Mon Sep 17 00:00:00 2001 From: JV Date: Tue, 19 Jul 2022 15:04:13 -0600 Subject: [PATCH 4/4] Update docs/source/caching/advanced-topics.mdx Co-authored-by: alessia --- docs/source/caching/advanced-topics.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/caching/advanced-topics.mdx b/docs/source/caching/advanced-topics.mdx index 849395ab087..af36698d0b0 100644 --- a/docs/source/caching/advanced-topics.mdx +++ b/docs/source/caching/advanced-topics.mdx @@ -118,7 +118,7 @@ Inheritance is a powerful code-sharing tool, and it works well with Apollo Clien * A single subtype can have multiple supertypes in a GraphQL schema, which is difficult to model using the single inheritance model of classes or prototypes. In other words, supporting multiple inheritance in JavaScript requires building a system something like this one, rather than just reusing built-in language features. - * Developers can add their own client-only supertypes to the `possibleTypes` map, as a way of reusing behavior across types, even if their schema knows nothing about those made-up supertypes + * Developers can add their own client-only supertypes to the `possibleTypes` map, as a way of reusing behavior across types, even if their schema knows nothing about those supertypes. * The `possibleTypes` map is currently used only for fragment matching purposes, which is an important but fairly small part of what the client does. Inheritance adds another compelling use for `possibleTypes`, and should drastically reduce repetition of `typePolicies` when used effectively.