http caching for all color/species requests

This commit is contained in:
Matt Dunn-Rankin 2020-05-14 15:51:08 -07:00
parent 7847eddec3
commit 9c8a48a325
5 changed files with 56 additions and 33 deletions

View file

@ -12,6 +12,7 @@
"@testing-library/react": "^9.3.2", "@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2", "@testing-library/user-event": "^7.1.2",
"apollo-boost": "^0.4.7", "apollo-boost": "^0.4.7",
"apollo-link-persisted-queries": "^0.2.2",
"apollo-server": "^2.12.0", "apollo-server": "^2.12.0",
"apollo-server-core": "^2.12.0", "apollo-server-core": "^2.12.0",
"apollo-server-env": "^2.4.3", "apollo-server-env": "^2.4.3",

View file

@ -1,39 +1,12 @@
import React from "react"; import React from "react";
import ApolloClient from "apollo-boost";
import { ApolloProvider } from "@apollo/react-hooks"; import { ApolloProvider } from "@apollo/react-hooks";
import { CSSReset, ThemeProvider, theme } from "@chakra-ui/core"; import { CSSReset, ThemeProvider, theme } from "@chakra-ui/core";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom"; import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import apolloClient from "./apolloClient";
import HomePage from "./HomePage"; import HomePage from "./HomePage";
import WardrobePage from "./WardrobePage"; import WardrobePage from "./WardrobePage";
/**
* client is the global Apollo Client instance we use for GraphQL queries. This
* is how we communicate with the server!
*/
const client = new ApolloClient({
uri: "/api/graphql",
cacheRedirects: {
Query: {
// Teach Apollo how to serve `items` queries from the cache. That way,
// when you remove an item from your outfit, or add an item from search,
// Apollo knows it already has the data it needs and doesn't need to ask
// the server again!
items: (_, args, { getCacheKey }) =>
args.ids.map((id) => getCacheKey({ __typename: "Item", id })),
// Teach Apollo how to serve `petAppearance` queries from the cache. That
// way, when you switch pet poses, Apollo knows it already has the
// appearance data and doesn't need to ask the server again!
petAppearance: (_, args, { getCacheKey }) => {
const { speciesId, colorId, emotion, genderPresentation } = args;
const id = `${speciesId}-${colorId}-${emotion}-${genderPresentation}`;
return getCacheKey({ __typename: "PetAppearance", id });
},
},
},
});
/** /**
* App is the entry point of our application. There's not a ton of exciting * App is the entry point of our application. There's not a ton of exciting
* stuff happening here, mostly just setting up some globals and theming! * stuff happening here, mostly just setting up some globals and theming!
@ -43,7 +16,7 @@ const client = new ApolloClient({
function App() { function App() {
return ( return (
<Router> <Router>
<ApolloProvider client={client}> <ApolloProvider client={apolloClient}>
<ThemeProvider theme={theme}> <ThemeProvider theme={theme}>
<CSSReset /> <CSSReset />
<Switch> <Switch>

41
src/app/apolloClient.js Normal file
View file

@ -0,0 +1,41 @@
import { createPersistedQueryLink } from "apollo-link-persisted-queries";
import { createHttpLink } from "apollo-link-http";
import { InMemoryCache } from "apollo-cache-inmemory";
import ApolloClient from "apollo-client";
const cacheRedirects = {
Query: {
// Teach Apollo how to serve `items` queries from the cache. That way,
// when you remove an item from your outfit, or add an item from search,
// Apollo knows it already has the data it needs and doesn't need to ask
// the server again!
items: (_, args, { getCacheKey }) =>
args.ids.map((id) => getCacheKey({ __typename: "Item", id })),
// Teach Apollo how to serve `petAppearance` queries from the cache. That
// way, when you switch pet poses, Apollo knows it already has the
// appearance data and doesn't need to ask the server again!
petAppearance: (_, args, { getCacheKey }) => {
const { speciesId, colorId, emotion, genderPresentation } = args;
const id = `${speciesId}-${colorId}-${emotion}-${genderPresentation}`;
return getCacheKey({ __typename: "PetAppearance", id });
},
},
};
// The PersistedQueryLink in front of the HttpLink helps us send cacheable GET
// requests.
const persistedQueryLink = createPersistedQueryLink({
useGETForHashedQueries: true,
});
const httpLink = createHttpLink({ uri: "/api/graphql" });
/**
* apolloClient is the global Apollo Client instance we use for GraphQL
* queries. This is how we communicate with the server!
*/
export default new ApolloClient({
cacheRedirects,
link: persistedQueryLink.concat(httpLink),
cache: new InMemoryCache(),
});

View file

@ -108,8 +108,8 @@ const typeDefs = gql`
} }
type Query { type Query {
allColors: [Color!]! allColors: [Color!]! @cacheControl(maxAge: 10800) # Cache for 3 hours
allSpecies: [Species!]! allSpecies: [Species!]! @cacheControl(maxAge: 10800) # Cache for 3 hours
allValidSpeciesColorPairs: [SpeciesColorPair!]! # deprecated allValidSpeciesColorPairs: [SpeciesColorPair!]! # deprecated
items(ids: [ID!]!): [Item!]! items(ids: [ID!]!): [Item!]!
itemSearch(query: String!): ItemSearchResult! itemSearch(query: String!): ItemSearchResult!

View file

@ -2561,7 +2561,15 @@ apollo-link-http@^1.3.1:
apollo-link-http-common "^0.2.16" apollo-link-http-common "^0.2.16"
tslib "^1.9.3" tslib "^1.9.3"
apollo-link@^1.0.0, apollo-link@^1.0.6, apollo-link@^1.2.14: apollo-link-persisted-queries@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/apollo-link-persisted-queries/-/apollo-link-persisted-queries-0.2.2.tgz#156597cb259b7bb56cf4e967a7be0312954f4591"
integrity sha512-YL7XBu/5QsSbbYaWUXgm87T2Hn/2AQZk5Wr8CLXGDr3Wl3E/TRhBhKgQQTly9xhaTi7jgBO+AeIyTH5wCBHA9w==
dependencies:
apollo-link "^1.2.1"
hash.js "^1.1.3"
apollo-link@^1.0.0, apollo-link@^1.0.6, apollo-link@^1.2.1, apollo-link@^1.2.14:
version "1.2.14" version "1.2.14"
resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.14.tgz#3feda4b47f9ebba7f4160bef8b977ba725b684d9" resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.14.tgz#3feda4b47f9ebba7f4160bef8b977ba725b684d9"
integrity sha512-p67CMEFP7kOG1JZ0ZkYZwRDa369w5PIjtMjvrQd/HnIV8FRsHRqLqK+oAZQnFa1DDdZtOtHTi+aMIW6EatC2jg== integrity sha512-p67CMEFP7kOG1JZ0ZkYZwRDa369w5PIjtMjvrQd/HnIV8FRsHRqLqK+oAZQnFa1DDdZtOtHTi+aMIW6EatC2jg==
@ -5912,7 +5920,7 @@ hash-base@^3.0.0:
inherits "^2.0.1" inherits "^2.0.1"
safe-buffer "^5.0.1" safe-buffer "^5.0.1"
hash.js@^1.0.0, hash.js@^1.0.3: hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.3:
version "1.1.7" version "1.1.7"
resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42"
integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==