···5566# Schema Awareness
7788-As mentioned in the docs we allow for the schema to be passed
99-to the `cacheExchange`. This allows for partial results and deterministic
1010-fragment matching. This schema argument is of type `IntrospectionQuery`, as JSON structure that
1111-describes your entire server-side `GraphQLSchema`.
88+Previously, [on the "Normalized Caching" page](./normalized-caching.md) we've seen how Graphcache
99+stores normalized data in its store and how it traverses GraphQL documents to do so. What we've seen
1010+is that just using the GraphQL document for traversal and the `__typename` introspection field
1111+Graphcache is able to build a normalized caching structure that keeps our application up-to-date
1212+across API results, allows it to store data by entities and keys, and provides us configuration
1313+options to write [manual cache updates](./cache-updates.md) and [local
1414+resolvers](./local-resolvers.md).
1515+1616+While this is all possible without any information about a GraphQL API's schema, the `schema` option
1717+on `cacheExchange` allows us to pass an introspected schema to Graphcache:
1818+1919+```js
2020+const introspectedSchema = {
2121+ __schema: {
2222+ queryType: { name: 'Query', },
2323+ mutationType: { name: 'Mutation', },
2424+ subscriptionType: { name: 'Subscription', },
2525+ },
2626+};
2727+2828+cacheExchange({ schema: introspectedSchema });
2929+```
3030+3131+In GraphQL, [APIs allow for the entire schema to be
3232+"introspected"](https://graphql.org/learn/introspection/), which are special GraphQL queries that
3333+give us information on what the API supports. This information can either be retrieved from a
3434+GraphQL API directly or from the GraphQL.js Schema and contains a list of all types, the types'
3535+fields, scalars, and other information.
3636+3737+In Graphcache we can pass this schema information to enable several features that aren't enabled if
3838+we don't pass any information to this option:
3939+4040+- Fragments will be matched deterministically: A fragment can be written to be on an interface type
4141+ or multiple fragments can be spread for separate union'ed types in a selection set. In many cases,
4242+ if Graphcache doesn't have any schema information then it won't know what possible types a field
4343+ can return and may sometimes make a best guess and [issue a
4444+ warning](./errors.md#16-heuristic-fragment-matching). If we pass Graphcache a `schema` then it'll
4545+ be able to match fragments deterministically.
4646+- A schema may have non-default names for its root types; `Query`, `Mutation`, and `Subscription`.
4747+ The names can be changed by passing `schema` information to `cacheExchange` which is important
4848+ if the root type appears elsewhere in the schema, e.g. if the `Query` can be accessed on a
4949+ `Mutation` field's result.
5050+- We may write a lot of configuration for our `cacheExchange` but if we pass a `schema` then it'll
5151+ start checking whether any of the configuration options actually don't exist, maybe because we've
5252+ typo'd them. This is a small detail but can make a large different in a longer configuration.
5353+- Lastly; a schema contains information on **which fields are optional or required**. When
5454+ Graphcache has a schema it knows which fields can be made optional and it'll be able to generate
5555+ "partial results".
5656+5757+### Partial Results
12581313-With deterministic fragment matching if we use an interface or a union _Graphcache_ can be 100% sure
1414-what the expected types and shape of the data must be and whether the match is permitted. It also
1515-enables a feature called ["Partial Results"](#partial-results).
5959+As we navigate an app that uses Graphcache we may be in states where some of our data is already
6060+cached and some isn't. Graphcache normalizes data and stores it in tables for links and records for
6161+each entity, which means that sometimes it can maybe even execute a query against its cache that it
6262+hasn't sent to the API before.
6363+6464+[On the "Local Resolvers" page](./local-resolvers.md#resolving-entities) we've seen how to write
6565+resolvers that resolver entities without having to have seen a link from an API result before. If
6666+Graphcache uses these resolvers and previously cached data we often run into situations where a
6767+"partial result" could already be generated, which is what Graphcache does when it has `schema`
6868+information.
6969+7070+
7272+7373+Without a `schema` and information on which fields are optional, Graphcache will consider a "partial
7474+result" as a cache miss. If we don't have all of the information for a query then we can't execute
7575+it against the locally cached data after all. However, an API's schema contains information on which
7676+fields are required and which fields are optional, and if our apps are typed with this schema and
7777+TypeScript, can't we then use and handle these partial results before a request is sent to the API?
7878+7979+This is the idea behind "Schema Awareness" and "Partial Results". When Graphcache has `schema`
8080+information it may give us partial results [with the `stale` flag
8181+set](../api/core.md#operationresult) while it fetches the full result from the API in the
8282+background. This allows our apps to show some information while more is loading.
16831784## Getting your schema
18851919-But how do you get this introspected schema? The process of introspecting a schema is running an
8686+But how do you get an introspected `schema`? The process of introspecting a schema is running an
2087introspection query on the GraphQL API, which will give us our `IntrospectionQuery` result. So an
2188introspection is just another query we can run against our GraphQL APIs or schemas.
22892323-As long as `introspection` as turned on and permitted, we can download an introspection schema by
9090+As long as `introspection` is turned on and permitted, we can download an introspection schema by
2491running a normal GraphQL query against the API and save the result in a JSON file.
25922693```js
···125192It may be worth checking what your bundler or framework does when you import a JSON file. Typically
126193you can reduce the parsing time by making sure it's turned into a string and parsed using
127194`JSON.parse`
128128-129129-**What do we get from adding the schema to _Graphcache_?**
130130-131131-### Partial Results
132132-133133-Once _Schema Awareness_ is activated in _Graphcache_, it can use the schema to check which fields
134134-and lists are marked as optional fields. This is then used to delivery partial results when
135135-possible, which means that different queries may give you partial data where some uncached fields
136136-have been replaced with `null`, while loading more data in the background, instead of our apps
137137-having to wait for all data to be available.
138138-139139-Let's approach this with the example from ["Computed Queries"](./local-resolvers.md#resolve): We
140140-have our `TodosQuery` result which loads a list, and our app may want to get a specific `Todo` when
141141-the app transitions to a details page. We may have already written a resolver that tells
142142-_Graphcache_ what `Query.todo` does, but it may be missing some optional field to actuall give us
143143-the full detailed `Todo`.
144144-145145-Without a schema _Graphcache_ would assume that because some fields are uncached and missing, it
146146-can't serve this query's data. But if it has a schema, it may see that the uncached fields are
147147-optional anyway and it can return a partial result for the `Todo` while it's fetching the full query
148148-in the background, which in the `OperationResult` also causes `stale` to be set to `true`.
149149-150150-This means that _Schema Awareness_ can enable us to create apps that can display already cached data
151151-on page transitions, while the page's full data loads in the background, which can often feel much
152152-faster to the user.