Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Data feching and caching on Apollo Client
Search
joe_re
September 15, 2017
Technology
3k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Data feching and caching on Apollo Client
2017/09/15 ToKyoto.js LT
joe_re
September 15, 2017
More Decks by joe_re
See All by joe_re
Eyes on Claude Code
joere
0
150
Building Public API with GraphQL
joere
3
160
Traversing the GraphQL AST and Calculating Query Costs
joere
0
1.3k
Real-Time applications with GraphQL
joere
0
320
Prisma2 with Graphql
joere
3
1k
Go beyound static on Netlify
joere
1
390
Building Real-time Vue App
joere
4
4.8k
ReactNativeのAsyncStorageをNodeのReplから操作する
joere
0
370
Mock Native API in your E2E test
joere
2
1.3k
Other Decks in Technology
See All in Technology
Azure Serverless 2026:Production-ready な AI エージェント基盤 / Azure Serverless 2026: Production-Ready AI Agent Platform
miyake
2
660
C#未経験の僕がAIに読めるコードを書かせるまで
maguroalternative
0
340
Snowflake Horizon Catalog と Apache Iceberg で作る オープンなデータ基盤
kitagawaz
0
290
特殊変数大全
dak2
0
160
高負荷プロダクション環境におけるAWS Lambdaのリアル 〜スケールとコストを左右する実行ライフサイクルの技術仕様〜
maimyyym
2
770
Terraformを用いたJamf Pro構成のIaC, GitOps化への挑戦
yukun
0
110
GoのInterface内部構造から学ぶ!最高パフォーマンスを出すコード設計
yappli_developers
1
300
営業オントロジーの作り方と、エージェントからの辿り方 ── ナレッジワークの現場から
kworkdev
PRO
1
180
AIエージェントの一手は 誰も見ていない - Falco拡張OSS「Prempti」とeBPFで サーバーレス実行基盤を二層防御する
keitah
1
630
HolmesGPTで始めるSREエージェント入門!プラットフォームの障害調査はAIにお任せ 〜
sanghyuk
0
220
全社共通データ基盤をつくる。ソニーのDatabricks活用とデータガバナンス設計の裏側
sony
0
140
Argo CDとAtlantisで実現するインフラ管理のセルフサービス化──小規模SREチームで支えるプラットフォーム
cassius7
0
230
Featured
See All Featured
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
540
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
3
3.8k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
530
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
1k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
3k
Context Engineering - Making Every Token Count
addyosmani
9
1.2k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
480
How to build a perfect <img>
jonoalderson
1
6k
A Tale of Four Properties
chriscoyier
163
24k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
680
Code Reviewing Like a Champion
maltzj
528
40k
Transcript
Data feching and caching on Apollo Client 2017/09/15 ToKyoto.js LT
@joe_re
Who am I? twitter: @joe_re github: @joere working in freee.K.K
GraphQL Tokyo Organizer
What is Apollo Client? GraphQL のClient ライブラリ React 、Angular 、Vue
、NativeApp(ReactNative, iOS, Android) などなど幅広くサポート 対抗馬はFacebook 製のRelay
vs Relay
の話はしないけどざっくりApollo が優位なところをざっくり サポートはReact, ReactNative のみ GraphQL API に制約をかける 規約が多いので理解するまで大変 (
ただし慣れればパフォーマンスやDE は向上する)
Fundations of GraphQL
What is GraphQL Facebook が公開しているAPI の仕様 データの取得、更新を行うクエリ言語を提供する 特定の言語やフレームワークを指すものではない
Example Query query { repository(owner: "apollographql", name: "apollo-client") { name,
description, stargazers { totalCount } } } Result { "data": { "repository": { "name": "apollo-client", "description": ":rocket: A fully-featured, production ready caching GraphQL client for every server or UI framework", "stargazers": { "totalCount": 3948 } } } }
Good Points クライアント側で必要なデータを細かく取捨選択できるの で無駄がない 複数のリソースを1 つのリクエストで一度に得られる クライアントが理解できるスキーマを元にクエリするの で、期待した結果を得られる( 型定義も容易) (http://graphql.org/)
Three types of GraphQL operation Query: データの取得 Mutation: Query で取得したデータの更新
Subscription: データの変更の購読(Response Stream)
Example of Query query SearchRepository($queryString: String!, $cursor: String) { search(query:
$queryString, type: REPOSITORY, first: 30, after: $cursor) { repositoryCount edges { cursor node { ... RepositorySearchResult } } } } fragment RepositorySearchResult on Repository { databaseId name owner { avatarUrl(size: 40) login } description stargazers { totalCount } forks { totalCount } updatedAt }
Example of Mutation mutation AddStar($input: AddStarInput!) { addStar(input: $input) {
starrable { viewerHasStarred } } }
Example of Subscription subscription sub { newMessage { ... newMessageFields
} } fragment newMessageFields on Message { body sender }
※ ここからようやくApollo Client の話
DEMO (GitHub Client)
実装例にはReact を使います
Creating a client and inject via a provider const networkInterface
= createNetworkInterface({ uri: 'https://api.github.com/graphql' }); const middleWareInterface: MiddlewareInterface[] = [{ applyMiddleware(req, next) { const headers = req.options.headers || {}; AsyncStorage.getItem('token').then((token) => { headers.authorization = token ? `Bearer ${token}` : ''; req.options.headers = headers; next(); }); } }]; networkInterface.use(middleWareInterface); const client = new ApolloClient({ networkInterface }); export default class App extends React.Component { render() { return ( <ApolloProvider client={client}> <Routes /> </ApolloProvider> ) } }
Creating a client and inject via a provider 作成したclient はprovider
を通じて各コンポーネントで 利用可能となる graphql() を用いてGraohQL Container を作成することが できる GraphQL Container は与えるprops の変化によるfetch を 自動で行う client を直接呼び出して使用することも可能( withApollo())
Creating a GraphQL Container function ReleasesPage(props: Props & AppoloProps) {
if (props.loading) { return <Text>Loading</Text>; } return ( <View style={styles.page}> <ReleaseList repository={props.repository} navigation={props.navigation}/> </View> ); } const withData: OperationComponent<ShowReleasesQuery & QueryProps, Props, Props & AppoloProps> = graphql(RELEASES_QUERY, ({ options: ({ owner, name }) => ( { variables: { owner, name }, notifyOnNetworkStatusChange: true } ), props: (props) => { const { loading, repository } = props.data; return { loading, repository, } } })); export default withData(ReleasesPage);
GraphQL では大抵のリソースが 1 つのリクエストで取れる
件数が膨大なデータに対しても 1 つのリクエストで取得できる??
そんなわけはない
件数が多ければ当然 その分レスポンスは遅くなる
つまりページネーション が必要
data.fetchMore ページネーションを実現するためのAPI 現在のfetching の状態をcache に残したまま、新しく取得し た結果をマージすることができる Relay.QL のcursor のパターンだけではなく、どのページネ ーションのパターンにでも使える
Example of Pagination const withData: OperationComponent<SearchRepositoryQuery & QueryProps, Props, Props
& AppoloProps> = graphql(REPOSITORY_QUERY, ({ options: ({ queryString }) => ( { variables: { queryString }, notifyOnNetworkStatusChange: true } ), props: (props) => { const { loading, search, fetchMore } = props.data; return { loading, searchResult: { search }, loadNextPage: (cursor) => { return fetchMore({ variables: { cursor }, updateQuery: (prev, data) => { const { search } = data.fetchMoreResult; search.edges = prev.search.edges.concat(search.edges); return { search }; } }) } } } }));
Updating fetched data データの更新には前述の通りMutation を使う Mutation もQuery と同じように graphql() を用いて使用可能
になる Mutaion の場合はQuery とは違い、props の変化に応じて実行 されない
Example of Mutaion function StarBadge(props: Props) { return ( <Badge
containerStyle={{ width: 160, height: 30, backgroundColor: '#fff', marginRight: 8 }} onPress={() => rops.repository.viewerHasStarred ? props.removeStar(repository.id) : props.addStar(repository.id)}> <Text>{//... 省略}</Text> </Badge> ); } const StarBadgeWithMutations = compose( graphql(ADD_STAR_MUTATION, { props: ({ ownProps, mutate }) => ({ addStar: (id: string) => mutate({ variables: { input: { starrableId: id } }, }) }) }), graphql(REMOVE_STAR_MUTATION, { props: ({ ownProps, mutate }) => ({ removeStar: (id: string) => mutate({ variables: { input: { starrableId: id } }, }) }) }) )(StarBadge);
Automatic store updates 例ではMutation の発行のロジックしか書いていないにも関わ らず、store のデータも更新される mutation の結果で返ってきているid と同一のものがstore
にあ る場合には、store も同時に更新される mutation RemoveStar($input: RemoveStarInput!) { removeStar(input: $input) { starrable { id stargazers { totalCount } viewerHasStarred } } }
if you can't use automatic store updates... mutation のオプションを通じて手動でstore をupdate
するこ とが可能 refetchQueries: mutation の後に再度query を発行しデータを 更新する update: mutation の後にstore のcache を直接いじってデータ を更新する updateQueries: deprecated
あえてupdate を使ってcache を更新してみた const StarBadgeWithMutations = compose( graphql(ADD_STAR_MUTATION, { props:
({ ownProps, mutate }) => ({ addStar: (id: string) => mutate({ variables: { input: { starrableId: id } }, }) }) }), graphql(REMOVE_STAR_MUTATION, { props: ({ ownProps, mutate }) => { return { removeStar(id: string) { mutate({ variables: { input: { starrableId: id } }, update: (store, { data }) => { const queryOption = { query: RELEASES_QUERY, variables: { owner: ownProps.repository.owner.login, name: ownProps.repository.name } }; const cache = store.readQuery(queryOption); cache.repository.viewerHasStarred = data.removeStar.starrable.viewerHasStarred; cache.repository.stargazers.totalCount -= 1; store.writeQuery(Object.assign({}, queryOption, { data: cache })); } }) } } } }) )(StarBadge);
大変なのでなるべく Automatic store updates しましょう!
https://www.meetup.com/jaJP/GraphQLTokyo/ (多分)来月meetup するので、ご興味があればぜひ!
Thank you for your attention!