From 4499256d0e058e68de0a0d382f11f40247f197cb Mon Sep 17 00:00:00 2001 From: Shane Myrick Date: Wed, 10 Apr 2024 16:31:26 -0700 Subject: [PATCH 01/10] [docs] Update cache-configuration keyFields docs The docs were missing an explanation of how the keyFields can use false or a function --- docs/source/caching/cache-configuration.mdx | 23 +++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/docs/source/caching/cache-configuration.mdx b/docs/source/caching/cache-configuration.mdx index d114b9f1e11..93f78b6038d 100644 --- a/docs/source/caching/cache-configuration.mdx +++ b/docs/source/caching/cache-configuration.mdx @@ -176,10 +176,24 @@ const cache = new InMemoryCache({ keyFields: ["title", "author", ["name"]], }, AllProducts: { - // Singleton types that have no identifying field can use an empty - // array for their keyFields. - keyFields: [], + // Singleton types that have no identifying field. + keyFields: false, }, + Store: { + // If a type requires logic to choose the key fields, we can specify that in a function + keyFields: (object, context) => { + if (object.location == "United States") { + // We can return the array of field specifiers + return ["state", "storeNumber"]; + } else if (object.location) { + // Or we can return another function to calculate the cache key as a string + return ((obj) => "prefix:" + obj.location + obj.storeNumber); + } else { + // Or we can indicate that this type is a Singleton + return false; + } + } + } }, }); ``` @@ -194,7 +208,8 @@ This example shows a variety of `typePolicies` with different `keyFields`: ``` Book:{"title":"Fahrenheit 451","author":{"name":"Ray Bradbury"}} ``` -* The `AllProducts` type illustrates a special strategy for a **singleton** type. If the cache will only ever contain one `AllProducts` object and that object has _no_ identifying fields, you can provide an empty array for its `keyFields`. +* The `AllProducts` type illustrates a special strategy for a **singleton** type. If the cache will only ever contain one `AllProducts` object and that object has _no_ identifying fields, you can provide an empty array or `false` for its `keyFields`. +* The `Store` type provides an example of using custom logic from the given object and runtime context to calculate what fields should be used for the key field selection. If an object has multiple `keyFields`, the cache ID always lists those fields in the same order to ensure uniqueness. From cbb325af93b7bc4e0a8ec8001ab8da570f7748bd Mon Sep 17 00:00:00 2001 From: Shane Myrick Date: Thu, 11 Apr 2024 11:55:08 -0700 Subject: [PATCH 02/10] Apply suggestions from code review Co-authored-by: Jerel Miller --- docs/source/caching/cache-configuration.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/source/caching/cache-configuration.mdx b/docs/source/caching/cache-configuration.mdx index 93f78b6038d..a4a6b183705 100644 --- a/docs/source/caching/cache-configuration.mdx +++ b/docs/source/caching/cache-configuration.mdx @@ -181,11 +181,11 @@ const cache = new InMemoryCache({ }, Store: { // If a type requires logic to choose the key fields, we can specify that in a function - keyFields: (object, context) => { - if (object.location == "United States") { + keyFields: (store, context) => { + if (store.location == "United States") { // We can return the array of field specifiers return ["state", "storeNumber"]; - } else if (object.location) { + } else if (store.location) { // Or we can return another function to calculate the cache key as a string return ((obj) => "prefix:" + obj.location + obj.storeNumber); } else { From 9b57a7aac899ba3acfcfdead6b3fa182f79d8fbb Mon Sep 17 00:00:00 2001 From: Shane Myrick Date: Fri, 12 Apr 2024 19:23:07 -0700 Subject: [PATCH 03/10] Update keyFields with false --- docs/source/caching/cache-configuration.mdx | 22 +++++++-------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/docs/source/caching/cache-configuration.mdx b/docs/source/caching/cache-configuration.mdx index a4a6b183705..7775353e5ce 100644 --- a/docs/source/caching/cache-configuration.mdx +++ b/docs/source/caching/cache-configuration.mdx @@ -176,23 +176,15 @@ const cache = new InMemoryCache({ keyFields: ["title", "author", ["name"]], }, AllProducts: { - // Singleton types that have no identifying field. - keyFields: false, + // Singleton types that have no identifying field can use an empty + // array for their keyFields. + keyFields: [], }, Store: { - // If a type requires logic to choose the key fields, we can specify that in a function - keyFields: (store, context) => { - if (store.location == "United States") { - // We can return the array of field specifiers - return ["state", "storeNumber"]; - } else if (store.location) { - // Or we can return another function to calculate the cache key as a string - return ((obj) => "prefix:" + obj.location + obj.storeNumber); - } else { - // Or we can indicate that this type is a Singleton - return false; - } - } + // If you need to disable normalization, set the keyFields to false + // and the object will be embedded in the parent + // See: https://www.apollographql.com/docs/react/caching/cache-configuration/#disabling-normalization + keyFields: false } }, }); From 103f8c64b543fdbd8a10374941e0d8608252c170 Mon Sep 17 00:00:00 2001 From: Shane Myrick Date: Fri, 12 Apr 2024 19:33:07 -0700 Subject: [PATCH 04/10] Update cache-configuration.mdx --- docs/source/caching/cache-configuration.mdx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/docs/source/caching/cache-configuration.mdx b/docs/source/caching/cache-configuration.mdx index 7775353e5ce..818b171400f 100644 --- a/docs/source/caching/cache-configuration.mdx +++ b/docs/source/caching/cache-configuration.mdx @@ -183,8 +183,16 @@ const cache = new InMemoryCache({ Store: { // If you need to disable normalization, set the keyFields to false // and the object will be embedded in the parent - // See: https://www.apollographql.com/docs/react/caching/cache-configuration/#disabling-normalization keyFields: false + }, + Location: { + keyFields: (location, context) => { + if (location.state) { + return ["city, "state", "country"]; + } else { + return ["city, "country"]; + } + } } }, }); @@ -200,8 +208,10 @@ This example shows a variety of `typePolicies` with different `keyFields`: ``` Book:{"title":"Fahrenheit 451","author":{"name":"Ray Bradbury"}} ``` -* The `AllProducts` type illustrates a special strategy for a **singleton** type. If the cache will only ever contain one `AllProducts` object and that object has _no_ identifying fields, you can provide an empty array or `false` for its `keyFields`. -* The `Store` type provides an example of using custom logic from the given object and runtime context to calculate what fields should be used for the key field selection. +* The `AllProducts` type illustrates a special strategy for a **singleton** type. If the cache will only ever contain one `AllProducts` object and that object has _no_ identifying fields, you can provide an empty array for its `keyFields`. +* The `Store` type provides an example of how you can [disable normalization](https://www.apollographql.com/docs/react/caching/cache-configuration/#disabling-normalization) by setting the keyFields to `false` +* The `Location` type provides an example of using custom fuction given object and runtime context to calculate what fields should be used for the key field selection. + * Keep in mind that the first argument here is a reference to the record that will be written. As such, it does NOT include subselected fields, only scalar fields, and it contains aliases from the operation. If you need to read the real type you can use `context.storeObject`. To read even more indepth about how this function can work the best source will be our own [test cases for the cache policies](https://github.com/apollographql/apollo-client/blob/8bc7d4d406402962bf5151cdd2c5c75c9398d10c/src/cache/inmemory/__tests__/policies.ts#L5543-L5622) If an object has multiple `keyFields`, the cache ID always lists those fields in the same order to ensure uniqueness. From 2e288183a3ffa88bf9e6bc577ef500ad5b0d29af Mon Sep 17 00:00:00 2001 From: Shane Myrick Date: Sat, 13 Apr 2024 11:06:25 -0700 Subject: [PATCH 05/10] Update cache-configuration.mdx --- docs/source/caching/cache-configuration.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/caching/cache-configuration.mdx b/docs/source/caching/cache-configuration.mdx index 818b171400f..326c64a027f 100644 --- a/docs/source/caching/cache-configuration.mdx +++ b/docs/source/caching/cache-configuration.mdx @@ -186,6 +186,8 @@ const cache = new InMemoryCache({ keyFields: false }, Location: { + // You can also use a function to determine any of the values above. + // The first argument is the reference to the record to be written, and the second is the runtime context keyFields: (location, context) => { if (location.state) { return ["city, "state", "country"]; From 523c4fb635f51044de69f796ec02069bbf884a52 Mon Sep 17 00:00:00 2001 From: Shane Myrick Date: Wed, 17 Apr 2024 15:52:05 -0700 Subject: [PATCH 06/10] Update cache-configuration.mdx --- docs/source/caching/cache-configuration.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/caching/cache-configuration.mdx b/docs/source/caching/cache-configuration.mdx index 326c64a027f..31e235861b9 100644 --- a/docs/source/caching/cache-configuration.mdx +++ b/docs/source/caching/cache-configuration.mdx @@ -189,7 +189,7 @@ const cache = new InMemoryCache({ // You can also use a function to determine any of the values above. // The first argument is the reference to the record to be written, and the second is the runtime context keyFields: (location, context) => { - if (location.state) { + if (context.storeObject.location.state) { return ["city, "state", "country"]; } else { return ["city, "country"]; From d0516a86b84ad43a27db88ad9a1139d396f91b9c Mon Sep 17 00:00:00 2001 From: Shane Myrick Date: Mon, 22 Apr 2024 09:43:00 -0700 Subject: [PATCH 07/10] Update cache-configuration.mdx --- docs/source/caching/cache-configuration.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/caching/cache-configuration.mdx b/docs/source/caching/cache-configuration.mdx index 31e235861b9..8524a6b9444 100644 --- a/docs/source/caching/cache-configuration.mdx +++ b/docs/source/caching/cache-configuration.mdx @@ -189,7 +189,7 @@ const cache = new InMemoryCache({ // You can also use a function to determine any of the values above. // The first argument is the reference to the record to be written, and the second is the runtime context keyFields: (location, context) => { - if (context.storeObject.location.state) { + if (context.readField("location", context.readField("state"))) { return ["city, "state", "country"]; } else { return ["city, "country"]; From 396a27bbb3476af3aa292cb5fbcfd99025d495ff Mon Sep 17 00:00:00 2001 From: Shane Myrick Date: Mon, 22 Apr 2024 09:43:31 -0700 Subject: [PATCH 08/10] Update cache-configuration.mdx --- docs/source/caching/cache-configuration.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/caching/cache-configuration.mdx b/docs/source/caching/cache-configuration.mdx index 8524a6b9444..fd7ce19eb25 100644 --- a/docs/source/caching/cache-configuration.mdx +++ b/docs/source/caching/cache-configuration.mdx @@ -190,9 +190,9 @@ const cache = new InMemoryCache({ // The first argument is the reference to the record to be written, and the second is the runtime context keyFields: (location, context) => { if (context.readField("location", context.readField("state"))) { - return ["city, "state", "country"]; + return ["city", "state", "country"]; } else { - return ["city, "country"]; + return ["city", "country"]; } } } From 7483ab7d7fa2af5199eeb3b8e12ff6e1bbbf4d35 Mon Sep 17 00:00:00 2001 From: Shane Myrick Date: Mon, 22 Apr 2024 09:44:06 -0700 Subject: [PATCH 09/10] Update cache-configuration.mdx --- docs/source/caching/cache-configuration.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/caching/cache-configuration.mdx b/docs/source/caching/cache-configuration.mdx index fd7ce19eb25..ab6dfee341b 100644 --- a/docs/source/caching/cache-configuration.mdx +++ b/docs/source/caching/cache-configuration.mdx @@ -190,9 +190,9 @@ const cache = new InMemoryCache({ // The first argument is the reference to the record to be written, and the second is the runtime context keyFields: (location, context) => { if (context.readField("location", context.readField("state"))) { - return ["city", "state", "country"]; + return ["city", "state", "country"] } else { - return ["city", "country"]; + return ["city", "country"] } } } From 0c33efdf19d3f59875c64c4160e7e07342cdf6e9 Mon Sep 17 00:00:00 2001 From: Shane Myrick Date: Mon, 29 Apr 2024 19:06:11 -0700 Subject: [PATCH 10/10] Update cache-configuration.mdx --- docs/source/caching/cache-configuration.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/caching/cache-configuration.mdx b/docs/source/caching/cache-configuration.mdx index ab6dfee341b..0e9d15f622e 100644 --- a/docs/source/caching/cache-configuration.mdx +++ b/docs/source/caching/cache-configuration.mdx @@ -189,7 +189,7 @@ const cache = new InMemoryCache({ // You can also use a function to determine any of the values above. // The first argument is the reference to the record to be written, and the second is the runtime context keyFields: (location, context) => { - if (context.readField("location", context.readField("state"))) { + if (context.readField("state")) { return ["city", "state", "country"] } else { return ["city", "country"]