···454454The cache read methods are not possible outside of GraphQL operations. This means these methods will
455455be limited to the different `Graphcache` configuration methods.
456456457457+## Living with limitations of Local Resolvers
458458+459459+Local Resolvers are powerful tools using which we can tell Graphcache what to do with a certain
460460+field beyond using results it’s seen on prior API results. However, it’s limitations come from this
461461+very intention they were made for.
462462+463463+Resolvers are meant to augment Graphcache and teach it what to do with some fields. Sometimes this
464464+is trivial and simple (like most examples on this page), but other times, fields are incredibly
465465+complex to reproduce and hence resolvers become more complex.
466466+467467+This section is not exhaustive, but documents some of the more commonly asked for features of
468468+resolvers. However, beyond the cases listed below, resolvers are limited and:
469469+470470+- can't manipulate or see other fields on the current entity, or fields above it.
471471+- can't update the cache (they're only “computations” but don't change the cache)
472472+- can't change the query document that's sent to the API
473473+474474+### Writing reusable resolvers
475475+476476+As we've seen before in the ["Transforming Records" section above](#transforming-records), we can
477477+write generic resolvers by using the fourth argument that resolvers receive, the `ResolveInfo`
478478+object.
479479+480480+This `info` object gives our resolvers some context on where they’re being executed and gives it
481481+information about the current field and its surroundings.
482482+483483+For instance, while Graphcache has a convenience helper to access a current record on the parent
484484+object for scalar values, it doesn't for links. Hence, if we're trying to read relationships we have
485485+to use `cache.resolve`.
486486+487487+```js
488488+cacheExchange({
489489+ resolvers: {
490490+ Todo: {
491491+ // This works:
492492+ updatedAt: parent => parent.updatedAt,
493493+ // This won't work:
494494+ author: parent => parent.author,
495495+ },
496496+ },
497497+});
498498+```
499499+500500+The `info` object actually gives us two ways of accessing the original field's value:
501501+502502+```js
503503+const resolver = (parent, args, cache, info) => {
504504+ // This is the full version
505505+ const original = cache.resolve(info.parentKey, info.fieldName, args);
506506+ // But we can replace `info.parentKey` with `parent` as a shortcut
507507+ const original = cache.resolve(parent, info.fieldName, args);
508508+ // And we can also avoid re-using arguments by using `fieldKey`
509509+ const original = cache.resolve(parent, info.fieldKey);
510510+};
511511+```
512512+513513+Apart from telling us how to access the originally cached field value, we can also get more
514514+information from `info` about our field. For instance, we can:
515515+516516+- Read the current field's name using `info.fieldName`
517517+- Read the current field's key using `info.parentFieldKey`
518518+- Read the current parent entity's key using `info.parentKey`
519519+- Read the current parent entity's typename using `info.parentTypename`
520520+- Access the current operation's raw variables using `info.variables`
521521+- Access the current operation's raw fragments using `info.fragments`
522522+523523+### Causing cache misses and partial misses
524524+525525+When we write resolvers we provide Graphcache with a value for the current field, or rather with
526526+"behavior", that it will execute no matter whether this field is also cached or not.
527527+528528+This means that, unless our resolver returns `undefined`, if the query doesn't have any other cache
529529+misses, Graphcache will consider the field a cache hit and will, unless other cache misses occur,
530530+not make a network request.
531531+532532+> **Note:** An exception for this is [Schema Awareness](./schema-awareness.md), which can
533533+> automatically cause partial cache misses.
534534+535535+However, sometimes we may want a resolver to return a result, while still sending a GraphQL API
536536+request in the background to update our resolver’s values.
537537+538538+To achieve this we can update the `info.partial` field.
539539+540540+```js
541541+cacheExchange({
542542+ resolvers: {
543543+ Todo: {
544544+ author(parent, args, cache, info) {
545545+ const author = cache.resolve(parent, info.fieldKey);
546546+ if (author === null) {
547547+ info.partial = true;
548548+ }
549549+ return author;
550550+ },
551551+ },
552552+ },
553553+});
554554+```
555555+556556+Suppose we have a field that our GraphQL schema _sometimes_ returns a `null` value for, but that may
557557+be upated with a value in the future. In the above example, we wrote a resolver that sets
558558+`info.partial = true` if a field’s value is `null`. This causes Graphcache to consider the result
559559+“partial and stale” and will cause it to make a background request to the API, while still
560560+delivering the outdated result.
561561+562562+### Conditionally applying resolvers
563563+564564+We may not always want a resolver to be used. While sometimes this can be dangerous (if your
565565+resolver affects the shape and types of your fields), in other cases this is necessary.
566566+For instance, if your resolver handles infinite-scroll pagination, like the examples [in the next
567567+section](#pagination), then you may not always want to apply this resolver.
568568+569569+For this reason, Graphcache also supports [“local directives”, which are introduced on the next docs
570570+page.](./local-directives.md)
571571+457572## Pagination
458573459574`Graphcache` offers some preset `resolvers` to help us out with endless scrolling pagination, also