Slide 1

Slide 1 text

film character species homeworld episode

Slide 2

Slide 2 text

film character species homeworld episode GR APHQL IN REAL L IFE ROBERTO ORGIU - @_TIWIZ

Slide 3

Slide 3 text

the problem

Slide 4

Slide 4 text

the portrait version I N T R O D U C I N G

Slide 5

Slide 5 text

the landscape version W H I C H B E C O M E S

Slide 6

Slide 6 text

Fun fact GraphQL.replace(REST) usually returns false

Slide 7

Slide 7 text

Architectural Pattern Query Language

Slide 8

Slide 8 text

Leverage Protocol Use own Conventions

Slide 9

Slide 9 text

Versioning Evolution

Slide 10

Slide 10 text

Full request Client Performances

Slide 11

Slide 11 text

Ease of Caching DIY Cache

Slide 12

Slide 12 text

Query Strings Query Language

Slide 13

Slide 13 text

Multiple Endpoints Single Endpoint

Slide 14

Slide 14 text

Unified Precise

Slide 15

Slide 15 text

What is GraphQ What is GraphQL? D E E P D I V E I N T O

Slide 16

Slide 16 text

graphqlbin.com GraphQLBin insomnia.rest/graphql Insomnia altair.sirmuel.design Altair swapi.graph.cool GraphCool graphql.org/swapi-graphql GraphiQL

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

WHY APOLLO? Compile time safety Caching Community Code generation

Slide 19

Slide 19 text

buildscriptT{ repositoriesT{ google()T }A dependenciesT{ classpathA"com.android.tools.build:gradle:$tools_version" classpathB"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" }B }C allprojectsT{ repositoriesB{ google()B }D }E

Slide 20

Slide 20 text

buildscriptT{ repositoriesT{ google()T jcenter() }A dependenciesT{ classpathA"com.android.tools.build:gradle:$tools_version" classpathB"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "com.apollographql.apollo:gradle-plugin:$apollo_version" }B }C allprojectsT{ repositoriesB{ google()B jcenter() }D }E

Slide 21

Slide 21 text

buildscriptT{ repositoriesT{ google()T jcenter() }A dependenciesT{ classpathA"com.android.tools.build:gradle:$tools_version" classpathB"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "com.apollographql.apollo:gradle-plugin:$apollo_version" }B }C allprojectsT{ repositoriesB{ google()B jcenter() }D }E

Slide 22

Slide 22 text

apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { ... }

Slide 23

Slide 23 text

apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'com.apollographql.android' android { ... }

Slide 24

Slide 24 text

dependencies { ... implementation "com.apollographql.apollo:apollo-runtime:$apollo_version" implementation "com.apollographql.apollo:apollo-rx2-support:$apollo_version" ... }

Slide 25

Slide 25 text

DOWNSIDES Apollo-plugin schema.json *.graphql X X

Slide 26

Slide 26 text

testing

Slide 27

Slide 27 text

testing Compile time safety MockWebServer

Slide 28

Slide 28 text

> Task :apollo:generateDebugApolloIR FAILED .../android/apollo/Query.graphql: Cannot query field "nam" on type "YourType". Did you mean "name"? error: Validation of GraphQL query document failed FAILURE: Build failed with an exception.

Slide 29

Slide 29 text

@get:Rule val mockWebServer = MockWebServerRule() mockWebServer.enqueueResponse("/response.json") val testApolloClient = ApolloClient.builder() .serverUrl(mockWebServer.url) .okHttpClient(client) .build()

Slide 30

Slide 30 text

WHY?

Slide 31

Slide 31 text

CDN Android Back end Cache 8 KB limit

Slide 32

Slide 32 text

Solutions 2 solutions O k H t t p I n t e r c e p t o r A u t o m a t i c P e r s i s t e d Q u e r i e s W e f o u n d

Slide 33

Slide 33 text

query filmById($filmId: ID){ film(filmID :$filmId){ title episodeID characterConnectionT{ charactersT{ name homeworldT{ name }A speciesT{ name classification }B filmConnectionT{ filmsT{ title episodeID }C }D }E }F }G }H A u t o m a t i c P e r s i s t e d Q u e r i e s

Slide 34

Slide 34 text

query filmById($filmId: ID){ film(filmID :$filmId){ title episodeID characterConnectionT{ charactersT{ name homeworldT{ name }A speciesT{ name classification }B filmConnectionT{ filmsT{ title episodeID }C }D }E }F }G }H A u t o m a t i c P e r s i s t e d Q u e r i e s variables { "filmId" : 1 }A query: query filmById($filmId: ID) { film(filmId :$filmId) { title episodeID characterConnection { name homeworld{ name }B species { name classification }C filmConnection { films { title episodeID }D }E }F }G }H operationName: filmById

Slide 35

Slide 35 text

query filmById($filmId: ID){ film(filmID :$filmId){ title episodeID characterConnectionT{ charactersT{ name homeworldT{ name }A speciesT{ name classification }B filmConnectionT{ filmsT{ title episodeID }C }D }E }F }G }H A u t o m a t i c P e r s i s t e d Q u e r i e s variables { "filmId" : 1 }A query: query filmById($filmId: ID) { film(filmId :$filmId) { title episodeID characterConnection { name homeworld{ name }B species { name classification }C filmConnection { films { title episodeID }D }E }F }G }H operationName: filmById operationName: filmById variables { "filmId" : 1 }T

Slide 36

Slide 36 text

query filmById($filmId: ID){ film(filmID :$filmId){ title episodeID characterConnectionT{ charactersT{ name homeworldT{ name }A speciesT{ name classification }B filmConnectionT{ filmsT{ title episodeID }C }D }E }F }G }H A u t o m a t i c P e r s i s t e d Q u e r i e s variables { "filmId" : 1 }A query: query filmById($filmId: ID) { film(filmId :$filmId) { title episodeID characterConnection { name homeworld{ name }B species { name classification }C filmConnection { films { title episodeID }D }E }F }G }H operationName: filmById operationName: filmById variables { "filmId" : 1 }T

Slide 37

Slide 37 text

A u t o m a t i c P e r s i s t e d Q u e r i e s operationName: filmById variables { "filmId" : 1 }T extensions: { persistedQuery: { "version": 1, "sha256Hash": "queryHash" } }

Slide 38

Slide 38 text

Android Back end Query Hash Query Hash Not Found Whole Query + Query Hash Response

Slide 39

Slide 39 text

@get:Rule valTmockWebServerT=TMockWebServerRule() mockWebServer.enqueueResponse(“/response.json") valTurlT=TmockWebServer.url valßapolloClientT= ApolloClient.builder() .serverUrl(url) .okHttpClient(client) .build()

Slide 40

Slide 40 text

valßapolloClientT= ApolloClient.builder() .serverUrl(url) .okHttpClient(client) .build()

Slide 41

Slide 41 text

valßapolloClientT= ApolloClient.builder() .serverUrl(url) .okHttpClient(client) .enableAutoPersistedQueries(true) .build()

Slide 42

Slide 42 text

Tricks Tricks J U S T S O M E query SampleQuery { assetID: sourceId fingerprint: modified headlineInfo: headline { __typename headline: default }A lastUpdated: lastModification }B

Slide 43

Slide 43 text

Tricks Tricks L A B E L F I E L D S C A N G O A L O N G D I S T A N C E J U S T S O M E query SampleQuery { assetID: sourceId fingerprint: modified headlineInfo: headline { __typename headline: default }A lastUpdated: lastModification }B

Slide 44

Slide 44 text

Tricks Tricks A P O L L O A D D S T Y P E N A M E E V E R Y W H E R E J U S T S O M E query SampleQuery { assetID: sourceId fingerprint: modified headlineInfo: headline { __typename headline: default }A lastUpdated: lastModification }B

Slide 45

Slide 45 text

Tricks Tricks S C H E M A A N D Q U E R I E S C A N B E M O V E D J U S T S O M E apollo { schemaFilePath = "/path/my-schema.json" outputPackageName = "pkg.graphql.api" }

Slide 46

Slide 46 text

Tricks Tricks S U P P O R T S F O R J A V A B E A N S E M A N T I C S J U S T S O M E class Type { public Another getAnother() { ... } } //build.gradle apollo { useJavaBeansSemanticNaming = true }

Slide 47

Slide 47 text

Tricks Tricks R E M E M B E R T O B E O N L I N E ¯ \ _ ( ツ ) _ / ¯ J U S T S O M E

Slide 48

Slide 48 text

THANK YOU!