diff --git a/package.json b/package.json index 0c36aed..f33a7f8 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@testing-library/react": "^9.3.2", "@testing-library/user-event": "^7.1.2", "apollo-boost": "^0.4.7", + "apollo-link-persisted-queries": "^0.2.2", "apollo-server": "^2.12.0", "apollo-server-core": "^2.12.0", "apollo-server-env": "^2.4.3", diff --git a/src/app/App.js b/src/app/App.js index dbac302..668b287 100644 --- a/src/app/App.js +++ b/src/app/App.js @@ -1,39 +1,12 @@ import React from "react"; -import ApolloClient from "apollo-boost"; import { ApolloProvider } from "@apollo/react-hooks"; import { CSSReset, ThemeProvider, theme } from "@chakra-ui/core"; import { BrowserRouter as Router, Switch, Route } from "react-router-dom"; +import apolloClient from "./apolloClient"; import HomePage from "./HomePage"; 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 * stuff happening here, mostly just setting up some globals and theming! @@ -43,7 +16,7 @@ const client = new ApolloClient({ function App() { return ( - + diff --git a/src/app/apolloClient.js b/src/app/apolloClient.js new file mode 100644 index 0000000..37af783 --- /dev/null +++ b/src/app/apolloClient.js @@ -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(), +}); diff --git a/src/server/index.js b/src/server/index.js index 91e2220..c39055e 100644 --- a/src/server/index.js +++ b/src/server/index.js @@ -108,8 +108,8 @@ const typeDefs = gql` } type Query { - allColors: [Color!]! - allSpecies: [Species!]! + allColors: [Color!]! @cacheControl(maxAge: 10800) # Cache for 3 hours + allSpecies: [Species!]! @cacheControl(maxAge: 10800) # Cache for 3 hours allValidSpeciesColorPairs: [SpeciesColorPair!]! # deprecated items(ids: [ID!]!): [Item!]! itemSearch(query: String!): ItemSearchResult! diff --git a/yarn.lock b/yarn.lock index bd8b085..521331a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2561,7 +2561,15 @@ apollo-link-http@^1.3.1: apollo-link-http-common "^0.2.16" 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" resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.14.tgz#3feda4b47f9ebba7f4160bef8b977ba725b684d9" integrity sha512-p67CMEFP7kOG1JZ0ZkYZwRDa369w5PIjtMjvrQd/HnIV8FRsHRqLqK+oAZQnFa1DDdZtOtHTi+aMIW6EatC2jg== @@ -5912,7 +5920,7 @@ hash-base@^3.0.0: inherits "^2.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" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==