{"action":"created","comment":{"url":"https://api.github.com/repos/opentable/gifts-site/pulls/comments/203847016","pull_request_review_id":138784594,"id":203847016,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIwMzg0NzAxNg==","diff_hunk":"@@ -1,12 +1,46 @@\n+import 'whatwg-fetch';\n import React from 'react';\n import { hydrate } from 'react-dom';\n import createHistory from 'history/createBrowserHistory';\n-import createAppStore from './../app/store';\n-import Root from './../app';\n-import getLocalJson from './../app/utils/getLocalJson';\n+import { ApolloClient } from 'apollo-client';\n+import { InMemoryCache } from 'apollo-cache-inmemory';\n+import { HttpLink } from 'apollo-link-http';\n+import { createPersistedQueryLink } from 'apollo-link-persisted-queries';\n+import createAppStore from '../app/store';\n+import Root from '../app';\n+import getLocalJson from '../app/utils/getLocalJson';\n \n+/**\n+ * @typedef {import('../../types/graphql').PersistedDocumentNode} PersistedDocumentNode\n+ */\n+\n+/**\n+ * Generate the hash for persistent queries\n+ * @param {import('graphql').DocumentNode | PersistedDocumentNode} query\n+ * @returns {string}\n+ */\n+function generateHash(query) {\n+  // @ts-ignore DocumentNode has no documentId\n+  return query.documentId;\n+}\n+\n+const basePath = process.env.BASE_PATH || '/gifts';\n const initialState = getLocalJson('client-state');\n+const initialData = getLocalJson('client-data');\n const history = createHistory();\n-const store = createAppStore({ initialState, history });\n+const store = createAppStore({ initialState, history, basePath });\n+\n+const link = createPersistedQueryLink({ generateHash }).concat(\n+  new HttpLink({ uri: '/gifts/graphql' })","path":"src/client/index.jsx","position":38,"original_position":38,"commit_id":"4514ccd0b1179852a63ac484ac68261c544ccb31","original_commit_id":"4514ccd0b1179852a63ac484ac68261c544ccb31","user":{"login":"char1e5","id":4701140,"node_id":"MDQ6VXNlcjQ3MDExNDA=","avatar_url":"https://avatars0.githubusercontent.com/u/4701140?v=4","gravatar_id":"","url":"https://api.github.com/users/char1e5","html_url":"https://github.com/char1e5","followers_url":"https://api.github.com/users/char1e5/followers","following_url":"https://api.github.com/users/char1e5/following{/other_user}","gists_url":"https://api.github.com/users/char1e5/gists{/gist_id}","starred_url":"https://api.github.com/users/char1e5/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/char1e5/subscriptions","organizations_url":"https://api.github.com/users/char1e5/orgs","repos_url":"https://api.github.com/users/char1e5/repos","events_url":"https://api.github.com/users/char1e5/events{/privacy}","received_events_url":"https://api.github.com/users/char1e5/received_events","type":"User","site_admin":false},"body":"can you use `${basePath}/graphql` here? To be consistent.","created_at":"2018-07-19T19:38:29Z","updated_at":"2018-07-19T19:57:21Z","html_url":"https://github.com/opentable/gifts-site/pull/7#discussion_r203847016","pull_request_url":"https://api.github.com/repos/opentable/gifts-site/pulls/7","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/opentable/gifts-site/pulls/comments/203847016"},"html":{"href":"https://github.com/opentable/gifts-site/pull/7#discussion_r203847016"},"pull_request":{"href":"https://api.github.com/repos/opentable/gifts-site/pulls/7"}}},"pull_request":{"url":"https://api.github.com/repos/opentable/gifts-site/pulls/7","id":202387211,"node_id":"MDExOlB1bGxSZXF1ZXN0MjAyMzg3MjEx","html_url":"https://github.com/opentable/gifts-site/pull/7","diff_url":"https://github.com/opentable/gifts-site/pull/7.diff","patch_url":"https://github.com/opentable/gifts-site/pull/7.patch","issue_url":"https://api.github.com/repos/opentable/gifts-site/issues/7","number":7,"state":"open","locked":false,"title":"[C4-3232] Gifts GraphQL Support","user":{"login":"matthemsteger","id":1319046,"node_id":"MDQ6VXNlcjEzMTkwNDY=","avatar_url":"https://avatars2.githubusercontent.com/u/1319046?v=4","gravatar_id":"","url":"https://api.github.com/users/matthemsteger","html_url":"https://github.com/matthemsteger","followers_url":"https://api.github.com/users/matthemsteger/followers","following_url":"https://api.github.com/users/matthemsteger/following{/other_user}","gists_url":"https://api.github.com/users/matthemsteger/gists{/gist_id}","starred_url":"https://api.github.com/users/matthemsteger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matthemsteger/subscriptions","organizations_url":"https://api.github.com/users/matthemsteger/orgs","repos_url":"https://api.github.com/users/matthemsteger/repos","events_url":"https://api.github.com/users/matthemsteger/events{/privacy}","received_events_url":"https://api.github.com/users/matthemsteger/received_events","type":"User","site_admin":false},"body":"### Overview\r\n\r\nThis adds GraphQL support to gifts fully.\r\n\r\n* Static queries `*.graphql` are in the isomorphic `src/app/queries` folder\r\n* There is a lack of tooling for white list queries because Apollo wants people to use engine. However, there is webpack tooling. This means we are using a webpack server bundle to support this (similar to the renderer). See `src/server/queries/index.js`.\r\n* The data is fetched both client and server side (but only once). So if you visit `/gifts/search` directly, then you get a server rendered page (SEO ready) and if you navigate in browser from `/gifts` to `/gifts/search` by clicking on the button, then you will hit the new `/gifts/graphql` middleware that handles whitelisting of GraphQL queries.\r\n* `redux-first-router` does not have great support for automatic baseUrl/basePath support, so instead we are putting changing the isomorphic routes to a function that takes that in. On the server this comes from settings, on the client it uses the webpack define plugin to put it on `process.env.BASE_PATH`. When we are more *12 factor app* I am thinking it would also be `process.env.BASE_PATH` on the server\r\n\r\n### How it works\r\n\r\n1. During build time, through webpack, the `*.graphql` queries are called by `src/server/queries/index.js` and by any isomorphic Apollo enabled code (like `src/app/pages/Search/index.jsx`). These are transformed **at build time** to GraphQL documents **with a new `documentId` property** thanks to the `graphql-persisted-document-loader`.\r\n2. When the server renders the app, the Apollo `getDataFromTree` will run through the React App hierarchy and fetch necessary data. This will be included in the server render.\r\n3. If it is a client based render (i.e. client navigation to an Apollo enabled page/component), then Apollo will use the above mentioned GraphQL document (with the `documentId` property) to call `/gifts/graphql` with a request that look does not contain the entire query, just the persisted query hash, the operation name, and the variables.\r\n4. The server will check the hash against the known hashes (`documentId`) and if it matches, it will talk to our internal GraphQL. If it is not known, it gives back a 400.\r\n\r\n### Ticket\r\n\r\nhttps://opentable.atlassian.net/browse/C4-3232\r\n\r\n<details>\r\n<summary>Screenshots</summary>\r\nSample GraphQL client request body\r\n\r\n![screen shot 2018-07-18 at 2 34 49 pm](https://user-images.githubusercontent.com/1319046/42909108-cf493794-8a97-11e8-95df-8b41e1f94a71.png)\r\n\r\n</details>\r\n","created_at":"2018-07-18T21:36:01Z","updated_at":"2018-07-19T19:57:21Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e0333661e0b85987c4a64f95aba701f306850e5f","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/opentable/gifts-site/pulls/7/commits","review_comments_url":"https://api.github.com/repos/opentable/gifts-site/pulls/7/comments","review_comment_url":"https://api.github.com/repos/opentable/gifts-site/pulls/comments{/number}","comments_url":"https://api.github.com/repos/opentable/gifts-site/issues/7/comments","statuses_url":"https://api.github.com/repos/opentable/gifts-site/statuses/4514ccd0b1179852a63ac484ac68261c544ccb31","head":{"label":"matthemsteger:features/C4-3232-graphql","ref":"features/C4-3232-graphql","sha":"4514ccd0b1179852a63ac484ac68261c544ccb31","user":{"login":"matthemsteger","id":1319046,"node_id":"MDQ6VXNlcjEzMTkwNDY=","avatar_url":"https://avatars2.githubusercontent.com/u/1319046?v=4","gravatar_id":"","url":"https://api.github.com/users/matthemsteger","html_url":"https://github.com/matthemsteger","followers_url":"https://api.github.com/users/matthemsteger/followers","following_url":"https://api.github.com/users/matthemsteger/following{/other_user}","gists_url":"https://api.github.com/users/matthemsteger/gists{/gist_id}","starred_url":"https://api.github.com/users/matthemsteger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matthemsteger/subscriptions","organizations_url":"https://api.github.com/users/matthemsteger/orgs","repos_url":"https://api.github.com/users/matthemsteger/repos","events_url":"https://api.github.com/users/matthemsteger/events{/privacy}","received_events_url":"https://api.github.com/users/matthemsteger/received_events","type":"User","site_admin":false},"repo":{"id":140880730,"node_id":"MDEwOlJlcG9zaXRvcnkxNDA4ODA3MzA=","name":"gifts-site","full_name":"matthemsteger/gifts-site","owner":{"login":"matthemsteger","id":1319046,"node_id":"MDQ6VXNlcjEzMTkwNDY=","avatar_url":"https://avatars2.githubusercontent.com/u/1319046?v=4","gravatar_id":"","url":"https://api.github.com/users/matthemsteger","html_url":"https://github.com/matthemsteger","followers_url":"https://api.github.com/users/matthemsteger/followers","following_url":"https://api.github.com/users/matthemsteger/following{/other_user}","gists_url":"https://api.github.com/users/matthemsteger/gists{/gist_id}","starred_url":"https://api.github.com/users/matthemsteger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matthemsteger/subscriptions","organizations_url":"https://api.github.com/users/matthemsteger/orgs","repos_url":"https://api.github.com/users/matthemsteger/repos","events_url":"https://api.github.com/users/matthemsteger/events{/privacy}","received_events_url":"https://api.github.com/users/matthemsteger/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/matthemsteger/gifts-site","description":"New OpenTable Gifts Site","fork":true,"url":"https://api.github.com/repos/matthemsteger/gifts-site","forks_url":"https://api.github.com/repos/matthemsteger/gifts-site/forks","keys_url":"https://api.github.com/repos/matthemsteger/gifts-site/keys{/key_id}","collaborators_url":"https://api.github.com/repos/matthemsteger/gifts-site/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/matthemsteger/gifts-site/teams","hooks_url":"https://api.github.com/repos/matthemsteger/gifts-site/hooks","issue_events_url":"https://api.github.com/repos/matthemsteger/gifts-site/issues/events{/number}","events_url":"https://api.github.com/repos/matthemsteger/gifts-site/events","assignees_url":"https://api.github.com/repos/matthemsteger/gifts-site/assignees{/user}","branches_url":"https://api.github.com/repos/matthemsteger/gifts-site/branches{/branch}","tags_url":"https://api.github.com/repos/matthemsteger/gifts-site/tags","blobs_url":"https://api.github.com/repos/matthemsteger/gifts-site/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/matthemsteger/gifts-site/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/matthemsteger/gifts-site/git/refs{/sha}","trees_url":"https://api.github.com/repos/matthemsteger/gifts-site/git/trees{/sha}","statuses_url":"https://api.github.com/repos/matthemsteger/gifts-site/statuses/{sha}","languages_url":"https://api.github.com/repos/matthemsteger/gifts-site/languages","stargazers_url":"https://api.github.com/repos/matthemsteger/gifts-site/stargazers","contributors_url":"https://api.github.com/repos/matthemsteger/gifts-site/contributors","subscribers_url":"https://api.github.com/repos/matthemsteger/gifts-site/subscribers","subscription_url":"https://api.github.com/repos/matthemsteger/gifts-site/subscription","commits_url":"https://api.github.com/repos/matthemsteger/gifts-site/commits{/sha}","git_commits_url":"https://api.github.com/repos/matthemsteger/gifts-site/git/commits{/sha}","comments_url":"https://api.github.com/repos/matthemsteger/gifts-site/comments{/number}","issue_comment_url":"https://api.github.com/repos/matthemsteger/gifts-site/issues/comments{/number}","contents_url":"https://api.github.com/repos/matthemsteger/gifts-site/contents/{+path}","compare_url":"https://api.github.com/repos/matthemsteger/gifts-site/compare/{base}...{head}","merges_url":"https://api.github.com/repos/matthemsteger/gifts-site/merges","archive_url":"https://api.github.com/repos/matthemsteger/gifts-site/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/matthemsteger/gifts-site/downloads","issues_url":"https://api.github.com/repos/matthemsteger/gifts-site/issues{/number}","pulls_url":"https://api.github.com/repos/matthemsteger/gifts-site/pulls{/number}","milestones_url":"https://api.github.com/repos/matthemsteger/gifts-site/milestones{/number}","notifications_url":"https://api.github.com/repos/matthemsteger/gifts-site/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/matthemsteger/gifts-site/labels{/name}","releases_url":"https://api.github.com/repos/matthemsteger/gifts-site/releases{/id}","deployments_url":"https://api.github.com/repos/matthemsteger/gifts-site/deployments","created_at":"2018-07-13T18:29:51Z","updated_at":"2018-07-19T17:54:03Z","pushed_at":"2018-07-19T17:54:01Z","git_url":"git://github.com/matthemsteger/gifts-site.git","ssh_url":"git@github.com:matthemsteger/gifts-site.git","clone_url":"https://github.com/matthemsteger/gifts-site.git","svn_url":"https://github.com/matthemsteger/gifts-site","homepage":null,"size":1008,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"opentable:master","ref":"master","sha":"d1a79e2e305f440fd366682681b5c8b53646f212","user":{"login":"opentable","id":2653541,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI2NTM1NDE=","avatar_url":"https://avatars0.githubusercontent.com/u/2653541?v=4","gravatar_id":"","url":"https://api.github.com/users/opentable","html_url":"https://github.com/opentable","followers_url":"https://api.github.com/users/opentable/followers","following_url":"https://api.github.com/users/opentable/following{/other_user}","gists_url":"https://api.github.com/users/opentable/gists{/gist_id}","starred_url":"https://api.github.com/users/opentable/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/opentable/subscriptions","organizations_url":"https://api.github.com/users/opentable/orgs","repos_url":"https://api.github.com/users/opentable/repos","events_url":"https://api.github.com/users/opentable/events{/privacy}","received_events_url":"https://api.github.com/users/opentable/received_events","type":"Organization","site_admin":false},"repo":{"id":139913112,"node_id":"MDEwOlJlcG9zaXRvcnkxMzk5MTMxMTI=","name":"gifts-site","full_name":"opentable/gifts-site","owner":{"login":"opentable","id":2653541,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI2NTM1NDE=","avatar_url":"https://avatars0.githubusercontent.com/u/2653541?v=4","gravatar_id":"","url":"https://api.github.com/users/opentable","html_url":"https://github.com/opentable","followers_url":"https://api.github.com/users/opentable/followers","following_url":"https://api.github.com/users/opentable/following{/other_user}","gists_url":"https://api.github.com/users/opentable/gists{/gist_id}","starred_url":"https://api.github.com/users/opentable/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/opentable/subscriptions","organizations_url":"https://api.github.com/users/opentable/orgs","repos_url":"https://api.github.com/users/opentable/repos","events_url":"https://api.github.com/users/opentable/events{/privacy}","received_events_url":"https://api.github.com/users/opentable/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/opentable/gifts-site","description":"New OpenTable Gifts Site","fork":false,"url":"https://api.github.com/repos/opentable/gifts-site","forks_url":"https://api.github.com/repos/opentable/gifts-site/forks","keys_url":"https://api.github.com/repos/opentable/gifts-site/keys{/key_id}","collaborators_url":"https://api.github.com/repos/opentable/gifts-site/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/opentable/gifts-site/teams","hooks_url":"https://api.github.com/repos/opentable/gifts-site/hooks","issue_events_url":"https://api.github.com/repos/opentable/gifts-site/issues/events{/number}","events_url":"https://api.github.com/repos/opentable/gifts-site/events","assignees_url":"https://api.github.com/repos/opentable/gifts-site/assignees{/user}","branches_url":"https://api.github.com/repos/opentable/gifts-site/branches{/branch}","tags_url":"https://api.github.com/repos/opentable/gifts-site/tags","blobs_url":"https://api.github.com/repos/opentable/gifts-site/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/opentable/gifts-site/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/opentable/gifts-site/git/refs{/sha}","trees_url":"https://api.github.com/repos/opentable/gifts-site/git/trees{/sha}","statuses_url":"https://api.github.com/repos/opentable/gifts-site/statuses/{sha}","languages_url":"https://api.github.com/repos/opentable/gifts-site/languages","stargazers_url":"https://api.github.com/repos/opentable/gifts-site/stargazers","contributors_url":"https://api.github.com/repos/opentable/gifts-site/contributors","subscribers_url":"https://api.github.com/repos/opentable/gifts-site/subscribers","subscription_url":"https://api.github.com/repos/opentable/gifts-site/subscription","commits_url":"https://api.github.com/repos/opentable/gifts-site/commits{/sha}","git_commits_url":"https://api.github.com/repos/opentable/gifts-site/git/commits{/sha}","comments_url":"https://api.github.com/repos/opentable/gifts-site/comments{/number}","issue_comment_url":"https://api.github.com/repos/opentable/gifts-site/issues/comments{/number}","contents_url":"https://api.github.com/repos/opentable/gifts-site/contents/{+path}","compare_url":"https://api.github.com/repos/opentable/gifts-site/compare/{base}...{head}","merges_url":"https://api.github.com/repos/opentable/gifts-site/merges","archive_url":"https://api.github.com/repos/opentable/gifts-site/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/opentable/gifts-site/downloads","issues_url":"https://api.github.com/repos/opentable/gifts-site/issues{/number}","pulls_url":"https://api.github.com/repos/opentable/gifts-site/pulls{/number}","milestones_url":"https://api.github.com/repos/opentable/gifts-site/milestones{/number}","notifications_url":"https://api.github.com/repos/opentable/gifts-site/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/opentable/gifts-site/labels{/name}","releases_url":"https://api.github.com/repos/opentable/gifts-site/releases{/id}","deployments_url":"https://api.github.com/repos/opentable/gifts-site/deployments","created_at":"2018-07-06T00:13:36Z","updated_at":"2018-07-18T15:22:18Z","pushed_at":"2018-07-18T21:44:43Z","git_url":"git://github.com/opentable/gifts-site.git","ssh_url":"git@github.com:opentable/gifts-site.git","clone_url":"https://github.com/opentable/gifts-site.git","svn_url":"https://github.com/opentable/gifts-site","homepage":null,"size":997,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"archived":false,"open_issues_count":1,"license":null,"forks":3,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/opentable/gifts-site/pulls/7"},"html":{"href":"https://github.com/opentable/gifts-site/pull/7"},"issue":{"href":"https://api.github.com/repos/opentable/gifts-site/issues/7"},"comments":{"href":"https://api.github.com/repos/opentable/gifts-site/issues/7/comments"},"review_comments":{"href":"https://api.github.com/repos/opentable/gifts-site/pulls/7/comments"},"review_comment":{"href":"https://api.github.com/repos/opentable/gifts-site/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/opentable/gifts-site/pulls/7/commits"},"statuses":{"href":"https://api.github.com/repos/opentable/gifts-site/statuses/4514ccd0b1179852a63ac484ac68261c544ccb31"}},"author_association":"NONE"}}
{"actor":{"display_login":"char1e5"}}