Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GraphQL From The Ground Up - Apollo Mobile Day, Online, January 2021

GraphQL From The Ground Up - Apollo Mobile Day, Online, January 2021

Video: Coming soon!

Abstract: You've heard a lot of people talking about GraphQL lately, but what IS it? What are the problems it's supposed to be solving - and what are the problems it's _not_ supposed to be solving? How can you use it to improve your mobile development process? Ellen Shapiro, who maintains the Apollo GraphQL iOS SDK, will help untangle all this and more.

C4861b1dfdf3bbb21faec4a1acdf183d?s=128

Ellen Shapiro
PRO

January 26, 2021
Tweet

Transcript

  1. GRAPHQL FROM THE GROUND UP APOLLO MOBILE DAY | THE

    INTERNETS | JANUARY 2021 ELLEN SHAPIRO | @DESIGNATEDNERD | APOLLOGRAPHQL.COM
  2. None
  3. None
  4. WTF IS GRAPHQL?

  5. None
  6. WHAT IS A GRAPH?

  7. None
  8. WHAT IS A GRAPH? (WHEN WE TALK ABOUT GRAPHQL)

  9. ! GRAPH THEORY

  10. In computer science, graphs are used to represent networks of

    communication, data organization, computational devices, the flow of computation, etc. https://en.wikipedia.org/wiki/Graph_theory#Computer_science
  11. None
  12. Source: https://neo4j.com/blog/graph-theory-predictive-modeling/

  13. Source: https://neo4j.com/blog/graph-theory-predictive-modeling/

  14. Source: https://neo4j.com/blog/graph-theory-predictive-modeling/

  15. Source: https://neo4j.com/blog/graph-theory-predictive-modeling/

  16. DIRECTED GRAPH Source: https://neo4j.com/blog/graph-theory-predictive-modeling/

  17. None
  18. UNDIRECTED GRAPH

  19. NODES INDIVIDUAL PIECES OF DATA

  20. EDGES RELATIONSHIPS BETWEEN PIECES OF DATA

  21. None
  22. SO IS A RELATIONAL DATABASE A GRAPH? !

  23. NOT QUITE.

  24. None
  25. None
  26. None
  27. None
  28. RELATIONAL DATABASES ARE FOCUSED ON SINGLE RELATIONSHIPS

  29. GRAPHS HELP YOU TO TRACK MANY RELATIONSHIPS

  30. user.father.bestFriend.children[0].middleName

  31. ✨ GRAPHQL!

  32. GRAPH QUERY LANGUAGE

  33. HOW DO I GRAPHQL?

  34. SAMPLE SERVER HTTPS://APOLLO-FULLSTACK-TUTORIAL.HEROKUAPP.COM/

  35. None
  36. THE SCHEMA

  37. THE SCHEMA WHAT IS IT POSSIBLE TO ASK FOR?

  38. SCHEMA DEFINITION LANGUAGE

  39. SCHEMA DEFINITION LANGUAGE (BASICALLY, TYPESCRIPT)

  40. None
  41. None
  42. None
  43. None
  44. SCALAR TYPES

  45. SCALAR TYPES THE BUILDING BLOCKS OF THE TYPE SYSTEM

  46. OPTIONALS?!

  47. ✍ POP QUIZ!

  48. Q. IS THIS TYPE OPTIONAL?

  49. Q. IS THIS TYPE OPTIONAL? String

  50. Q. IS THIS TYPE OPTIONAL? String A: IT DEPENDS

  51. None
  52. None
  53. IS OPTIONAL SWIFT/KOTLIN TYPE GRAPHQL TYPE

  54. IS OPTIONAL SWIFT/KOTLIN TYPE GRAPHQL TYPE No

  55. IS OPTIONAL SWIFT/KOTLIN TYPE GRAPHQL TYPE No String

  56. IS OPTIONAL SWIFT/KOTLIN TYPE GRAPHQL TYPE No String String!

  57. !

  58. GRAPHQL TYPES ARE NULLABLE BY DEFAULT

  59. IS OPTIONAL SWIFT/KOTLIN TYPE GRAPHQL TYPE No String String!

  60. IS OPTIONAL SWIFT/KOTLIN TYPE GRAPHQL TYPE No String String! Yes

  61. IS OPTIONAL SWIFT/KOTLIN TYPE GRAPHQL TYPE No String String! Yes

    String?
  62. IS OPTIONAL SWIFT/KOTLIN TYPE GRAPHQL TYPE No String String! Yes

    String? String
  63. None
  64. OPERATIONS

  65. OPERATIONS WHAT ARE THE ENTRY POINTS TO THE GRAPH?

  66. QUERY: PLEASE GIVE ME THIS DATA

  67. None
  68. MUTATION: PLEASE CHANGE THIS DATA

  69. SUBSCRIPTION: PLEASE UPDATE ME IF DATA CHANGES

  70. None
  71. ✅ HOW THINGS ARE RELATED

  72. ✅ HOW THINGS ARE RELATED ✅ WHAT YOU CAN ASK

    FOR
  73. ✅ HOW THINGS ARE RELATED ✅ WHAT YOU CAN ASK

    FOR ➡ HOW YOU ASK FOR IT
  74. GRAPHIQL

  75. None
  76. None
  77. None
  78. None
  79. None
  80. None
  81. None
  82. None
  83. None
  84. None
  85. None
  86. None
  87. None
  88. None
  89. None
  90. None
  91. None
  92. None
  93. HOW WOULD REST DO THIS?

  94. None
  95. None
  96. None
  97. None
  98. None
  99. None
  100. None
  101. VALIDATION

  102. None
  103. !

  104. VALIDATION IS WHAT I'M TRYING TO ASK FOR EVEN POSSIBLE?

  105. None
  106. None
  107. None
  108. VALIDATION + TYPES = CODE GENERATION

  109. APOLLO IOS + APOLLO ANDROID

  110. None
  111. None
  112. A VERY SHORTENED VERSION OF APOLLO'S GENERATED IOS CODE

  113. public final class LaunchInfoQuery: GraphQLQuery { public init(id: GraphQLID) {

    self.id = id } public struct Data: GraphQLSelectionSet { public var launch: Launch? { public struct Launch: GraphQLSelectionSet { public var site: String? public var mission: Mission? public var rocket: Rocket? public struct Mission: GraphQLSelectionSet { public var name: String? } public struct Rocket: GraphQLSelectionSet { public var name: String? } } } }
  114. public final class LaunchInfoQuery: GraphQLQuery { public init(id: GraphQLID) {

    self.id = id } public struct Data: GraphQLSelectionSet { public var launch: Launch? { public struct Launch: GraphQLSelectionSet { public var site: String? public var mission: Mission? public var rocket: Rocket? public struct Mission: GraphQLSelectionSet { public var name: String? } public struct Rocket: GraphQLSelectionSet { public var name: String? } } } }
  115. public final class LaunchInfoQuery: GraphQLQuery { public init(id: GraphQLID) {

    self.id = id } public struct Data: GraphQLSelectionSet { public var launch: Launch? { public struct Launch: GraphQLSelectionSet { public var site: String? public var mission: Mission? public var rocket: Rocket? public struct Mission: GraphQLSelectionSet { public var name: String? } public struct Rocket: GraphQLSelectionSet { public var name: String? } } } }
  116. public final class LaunchInfoQuery: GraphQLQuery { public init(id: GraphQLID) {

    self.id = id } public struct Data: GraphQLSelectionSet { public var launch: Launch? { public struct Launch: GraphQLSelectionSet { public var site: String? public var mission: Mission? public var rocket: Rocket? public struct Mission: GraphQLSelectionSet { public var name: String? } public struct Rocket: GraphQLSelectionSet { public var name: String? } } } }
  117. None
  118. public final class LaunchInfoQuery: GraphQLQuery { public init(id: GraphQLID) {

    self.id = id } public struct Data: GraphQLSelectionSet { public var launch: Launch? { public struct Launch: GraphQLSelectionSet { public var site: String? public var mission: Mission? public var rocket: Rocket? public struct Mission: GraphQLSelectionSet { public var name: String? } public struct Rocket: GraphQLSelectionSet { public var name: String? } } } }
  119. public final class LaunchInfoQuery: GraphQLQuery { public init(id: GraphQLID) {

    self.id = id } public struct Data: GraphQLSelectionSet { public var launch: Launch? { public struct Launch: GraphQLSelectionSet { public var site: String? public var mission: Mission? public var rocket: Rocket? public struct Mission: GraphQLSelectionSet { public var name: String? } public struct Rocket: GraphQLSelectionSet { public var name: String? } } } }
  120. YOU DON'T HAVE TO WRITE THIS CODE

  121. YOU DON'T HAVE TO WRITE THIS CODE (TIMES THE NUMBER

    OF OPERATIONS)
  122. YOU DON'T HAVE TO WRITE A NETWORKING WRAPPER

  123. None
  124. YOU DO HAVE TO WRITE SOME CODE

  125. apolloClient.fetch(query: LaunchInfoQuery(id: "80")) { result in switch result { case

    .failure(let error): print("Error: \(error)") case .success(let graphQLResult): if let errors = graphQLResult.errors { print("Errors: \(errors)") } if let missionName = graphQLData?.data?.launch?.mission?.name { print("Mission name: \(String(describing: missionName)") } } }
  126. apolloClient.fetch(query: LaunchInfoQuery(id: "80")) { result in switch result { case

    .failure(let error): print("Error: \(error)") case .success(let graphQLResult): if let errors = graphQLResult.errors { print("Errors: \(errors)") } if let missionName = graphQLData?.data?.launch?.mission?.name { print("Mission name: \(String(describing: missionName)") } } }
  127. apolloClient.fetch(query: LaunchInfoQuery(id: "80")) { result in switch result { case

    .failure(let error): print("Error: \(error)") case .success(let graphQLResult): if let errors = graphQLResult.errors { print("Errors: \(errors)") } if let missionName = graphQLData?.data?.launch?.mission?.name { print("Mission name: \(String(describing: missionName)") } } }
  128. apolloClient.fetch(query: LaunchInfoQuery(id: "80")) { result in switch result { case

    .failure(let error): print("Error: \(error)") case .success(let graphQLResult): if let errors = graphQLResult.errors { print("Errors: \(errors)") } if let missionName = graphQLData?.data?.launch?.mission?.name { print("Mission name: \(missionName) } } }
  129. None
  130. PARTIAL RESULTS

  131. apolloClient.fetch(query: LaunchInfoQuery(id: "80")) { result in switch result { case

    .failure(let error): print("Error: \(error)") case .success(let graphQLResult): if let errors = graphQLResult.errors { print("Errors: \(errors)") } if let missionName = graphQLData?.data?.launch?.mission?.name { print("Mission name: \(missionName) } } }
  132. apolloClient.fetch(query: LaunchInfoQuery(id: "80")) { result in switch result { case

    .failure(let error): print("Error: \(error)") case .success(let graphQLResult): if let errors = graphQLResult.errors { print("Errors: \(errors)") } if let missionName = graphQLData?.data?.launch?.mission?.name { print("Mission name: \(missionName) } } }
  133. USE SWIFT + KOTLIN EXTENSIONS TO HANDLE NULLABILITY GRACEFULLY

  134. extension LaunchInfoQuery.Data.Launch { var missionName: String { self.mission?.name ?? "(Unknown)"

    } }
  135. None
  136. WHAT IS GRAPHQL GOOD FOR?

  137. GET WHAT YOU WANT

  138. GET WHAT YOU WANT NOT WHAT FRONTEND, ANDROID, 3RD PARTY

    APIS, AND YOUR GRANDMA WANT
  139. YOU CAN ADD STUFF TO A GRAPH WAY FASTER THAN

    YOU CAN WITH A REST API
  140. A REST PLAY Me: Can we add this field that's

    on endpoint A to endpoint B? Backend: Sure, we'll put it in the backlog.
  141. None
  142. ANYTHING IN THE SCHEMA CAN BE ACCESSED VIA THE RELATIONSHIPS

    DEFINED IN THE GRAPH
  143. user.father.bestFriend.children[0].middleName

  144. user.father?.bestFriend.children?[0].middleName

  145. WHAT IS GRAPHQL NOT GOOD FOR?

  146. UPLOADING FILES

  147. None
  148. BETTER GRAPHQL UPLOADS

  149. BETTER GRAPHQL UPLOADS 1. Upload to something that returns a

    URL
  150. BETTER GRAPHQL UPLOADS 1. Upload to something that returns a

    URL 2. Send the URL to your graph using GraphQL
  151. BETTER GRAPHQL UPLOADS 1. Upload to something that returns a

    URL 2. Send the URL to your graph using GraphQL 3. Tear out way less hair than trying to upload with GQL
  152. HIGHLY OPTIMIZED QUERIES

  153. GQL TOOLING HELPS FIND BOTTLENECKS

  154. GQL TOOLING HELPS FIND BOTTLENECKS (BUT IT CAN'T ELIMINATE THEM)

  155. BEING ABLE TO ! COMPLETELY REMOVE THINGS QUICKLY

  156. GOOD NEWS: NO VERSIONING

  157. BAD NEWS: NO VERSIONING

  158. @deprecated

  159. None
  160. ! → " →

  161. SIMPLE SECURITY

  162. YOU CAN ASK FOR ANYTHING YOU WANT!

  163. DEVELOPERS

  164. SECURITY TEAM

  165. None
  166. None
  167. YOU'RE GONNA HAVE TO THINK MORE GRANULARLY ABOUT SECURITY

  168. MAYBE DON'T LEAVE SCHEMA INTROSPECTION UNPROTECTED

  169. OBLIGATORY SUMMARY SLIDE

  170. OBLIGATORY SUMMARY SLIDE ▸ A Graph is a way of

    conceptualizing data based on pieces of data (nodes) and the ways those pieces are connected (edges).
  171. OBLIGATORY SUMMARY SLIDE ▸ A Graph is a way of

    conceptualizing data based on pieces of data (nodes) and the ways those pieces are connected (edges). ▸ GraphQL is a way of querying your data and how it's connected
  172. OBLIGATORY SUMMARY SLIDE ▸ A Graph is a way of

    conceptualizing data based on pieces of data (nodes) and the ways those pieces are connected (edges). ▸ GraphQL is a way of querying your data and how it's connected ▸ The Schema defines what you can ask for (with types!)
  173. OBLIGATORY SUMMARY SLIDE ▸ A Graph is a way of

    conceptualizing data based on pieces of data (nodes) and the ways those pieces are connected (edges). ▸ GraphQL is a way of querying your data and how it's connected ▸ The Schema defines what you can ask for (with types!) ▸ Operations let you ask for and receive only the data you want
  174. OBLIGATORY SUMMARY SLIDE ▸ A Graph is a way of

    conceptualizing data based on pieces of data (nodes) and the ways those pieces are connected (edges). ▸ GraphQL is a way of querying your data and how it's connected ▸ The Schema defines what you can ask for (with types!) ▸ Operations let you ask for and receive only the data you want ▸ GraphQL is a real cool hammer - not every problem is a nail
  175. WANT TO TRY APOLLO? https://www.apollographql.com/docs/ios/tutorial/ https://www.apollographql.com/docs/android/tutorial/ THANK YOU!