{"action":"created","issue":{"url":"https://api.github.com/repos/apollostack/apollo-client/issues/26","repository_url":"https://api.github.com/repos/apollostack/apollo-client","labels_url":"https://api.github.com/repos/apollostack/apollo-client/issues/26/labels{/name}","comments_url":"https://api.github.com/repos/apollostack/apollo-client/issues/26/comments","events_url":"https://api.github.com/repos/apollostack/apollo-client/issues/26/events","html_url":"https://github.com/apollostack/apollo-client/issues/26","id":143163682,"number":26,"title":"Pagination idea: type-specific refetching plugins","user":{"login":"stubailo","id":448783,"avatar_url":"https://avatars.githubusercontent.com/u/448783?v=3","gravatar_id":"","url":"https://api.github.com/users/stubailo","html_url":"https://github.com/stubailo","followers_url":"https://api.github.com/users/stubailo/followers","following_url":"https://api.github.com/users/stubailo/following{/other_user}","gists_url":"https://api.github.com/users/stubailo/gists{/gist_id}","starred_url":"https://api.github.com/users/stubailo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stubailo/subscriptions","organizations_url":"https://api.github.com/users/stubailo/orgs","repos_url":"https://api.github.com/users/stubailo/repos","events_url":"https://api.github.com/users/stubailo/events{/privacy}","received_events_url":"https://api.github.com/users/stubailo/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/apollostack/apollo-client/labels/feature","name":"feature","color":"5319e7"}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":16,"created_at":"2016-03-24T06:05:57Z","updated_at":"2016-08-02T13:19:31Z","closed_at":null,"body":"In some sense, handling pagination in a smart way is just a special case of \"when you ask for data, treat certain fields in a special way because we know that the arguments are meaningful.\" So if we're looking at a Relay spec paginated list:\r\n\r\n```\r\n// first fetch\r\n{\r\n  user {\r\n    id\r\n    name\r\n    friends(first: 10) {\r\n      edges {\r\n        cursor\r\n        node {\r\n          id\r\n          name\r\n        }\r\n      }\r\n      pageInfo {\r\n        hasNextPage\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\n// new query\r\n... same stuff\r\nfriends(first: 20)\r\n\r\n// second fetch, doesn't fetch all 20 but uses the existing information\r\n... same stuff\r\nfriends(first: 10, after: \"lastCursor\")\r\n```\r\n\r\nNotice how easy it is for us as humans to imagine what data needs to be fetched to satisfy the new query.\r\n\r\nHere's a set of hypotheses:\r\n\r\n1. The initial fetch doesn't need any up-front information about types or pagination - it can look at the query result to know what to do, as long as we inject `__typename` fields where necessary.\r\n2. The re-fetch can determine the new query by the information in the store, which now has type annotations and the arguments from the new query\r\n3. The transformation from (2) can be written as a pure function that can be injected into the apollo client and associated with certain type names\r\n\r\nBasically, you could write a function and tell the apollo client:\r\n\r\n\"When refetching any field which refers to an object with a type matching this regular expression, give me the query you were going to fetch, and the contents of the store, and I'll give you a new query that says how to fetch the missing data.\"\r\n\r\nSo, for Relay pagination, you'd say:\r\n\r\n```js\r\nclient.registerPaginationPlugin(/.+Connection/, ({ state, id, selectionSet }) => {\r\n  ... do work ...\r\n\r\n  return {\r\n    // as much of the result as can be found\r\n    result,\r\n\r\n    // if empty, then the cache is sufficient and result contains the data.\r\n    // otherwise, an array of queries that need to be fetched\r\n    missingSelectionSets, \r\n  }\r\n});\r\n```\r\n\r\nIdeally this will allow plugging in to different pagination systems, as long as the paginated fields have predictable type names, for example `*PaginatedList` or `Paginated*`.\r\n\r\nIf we can do this, it will achieve some _really_ nice effects:\r\n\r\n1. You don't necessarily need to use the Relay pagination spec, which can be hard to translate to some REST APIs\r\n2. The store can avoid being concerned with pagination if the API above is indeed sufficient\r\n\r\nThis is just a very ambitious idea, and I'm eager to determine if this very simple model can actually handle all cases of pagination and Relay connections in particular. More analysis to come soon.\r\n\r\n@jbaxleyiii @helfer curious what you think about this."},"comment":{"url":"https://api.github.com/repos/apollostack/apollo-client/issues/comments/236901370","html_url":"https://github.com/apollostack/apollo-client/issues/26#issuecomment-236901370","issue_url":"https://api.github.com/repos/apollostack/apollo-client/issues/26","id":236901370,"user":{"login":"dbx834","id":4337826,"avatar_url":"https://avatars.githubusercontent.com/u/4337826?v=3","gravatar_id":"","url":"https://api.github.com/users/dbx834","html_url":"https://github.com/dbx834","followers_url":"https://api.github.com/users/dbx834/followers","following_url":"https://api.github.com/users/dbx834/following{/other_user}","gists_url":"https://api.github.com/users/dbx834/gists{/gist_id}","starred_url":"https://api.github.com/users/dbx834/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dbx834/subscriptions","organizations_url":"https://api.github.com/users/dbx834/orgs","repos_url":"https://api.github.com/users/dbx834/repos","events_url":"https://api.github.com/users/dbx834/events{/privacy}","received_events_url":"https://api.github.com/users/dbx834/received_events","type":"User","site_admin":false},"created_at":"2016-08-02T13:19:31Z","updated_at":"2016-08-02T13:19:31Z","body":"Please try again. Just checked, it works for me."}}
{"actor":{"display_login":"dbx834"}}