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

5 problems (and solutions) when using GraphQL with Spring Boot

5 problems (and solutions) when using GraphQL with Spring Boot

Slides from presetation at CareerCon Kariera IT in Warsaw, 24.03.2018

Krzysztof Pawlowski

March 24, 2018
Tweet

More Decks by Krzysztof Pawlowski

Other Decks in Technology

Transcript

  1. 5 problems (and solutions) when using GraphQL with Spring Boot

    Krzysztof Pawłowski [email protected] | krzychpawlowski CareerCon Kariera IT Warszawa, 24.03.2018
  2. About me ‣Software Development Director Poland @ Merapar Technologies ‣Coder,

    Lecturer (PJATK), Java Trainer (infoShare Academy) ‣7+ years of experience in Java Development ‣using GraphQL for over a year now ‣E-mail: [email protected] ‣Twitter: krzychpawlowski
  3. Agenda ‣Why GraphQL? ‣Short introduction to GraphQL ‣Benefits of GraphQL

    ‣Problems we encountered when using GraphQL with Spring Boot ‣How we solved the problems
  4. REST not so restful? GET /author/:id <<class>>
 Author Long id

    String name String email String bio List<BlogEntry>
 blogEntries <<class>>
 BlogEntry Long id String title List<Comment> comments <<class>>
 Comment Long id String author String comment
  5. REST not so restful? GET /author/:id GET /author/:id/blogEntry/:id <<class>>
 Author

    Long id String name String email String bio List<BlogEntry>
 blogEntries <<class>>
 BlogEntry Long id String title List<Comment> comments <<class>>
 Comment Long id String author String comment
  6. REST not so restful? GET /author/:id/blogEntry/:id/comments GET /author/:id GET /author/:id/blogEntry/:id

    <<class>>
 Author Long id String name String email String bio List<BlogEntry>
 blogEntries <<class>>
 BlogEntry Long id String title List<Comment> comments <<class>>
 Comment Long id String author String comment
  7. While in GraphQL… authors(filter : {id : 1 }) {


    name
 blogEntry {
 title
 comment {
 comment
 }
 }
 } <<class>>
 Author Long id String name String email String bio List<BlogEntry>
 blogEntries <<class>>
 BlogEntry Long id String title List<Comment> comments <<class>>
 Comment Long id String author String comment
  8. Origins of GraphQL ‣Developed internally at Facebook in 2012 ‣Publicly

    released in 2015 as open source project ‣Major clients: Apollo, Relay ‣GraphQL servers available in multiple languages: ‣Java ‣JavaScript ‣Python ‣Ruby ‣C# ‣Scala ‣Go ‣…
  9. What is GraphQL? “GraphQL is a query language for APIs

    and a runtime for fulfilling those queries with your existing data.” — http://graphql.org
  10. What is GraphQL? “GraphQL is a query language for APIs

    and a runtime for fulfilling those queries with your existing data.” — http://graphql.org Declarative
 Ask for what you need, get exactly that
  11. What is GraphQL? “GraphQL is a query language for APIs

    and a runtime for fulfilling those queries with your existing data.” — http://graphql.org Declarative
 Ask for what you need, get exactly that Compositional
 Get many resources in a single request
  12. What is GraphQL? “GraphQL is a query language for APIs

    and a runtime for fulfilling those queries with your existing data.” — http://graphql.org Declarative
 Ask for what you need, get exactly that Compositional
 Get many resources in a single request Strongly Typed
 Describe what’s possible with a type system
  13. GraphQL query authors { # queries can have comments! name

    email blogEntries { title } } { "data": { "authors": [ { "name": "author 1", "email": "Python dev", "blogEntries": [ { "title": "blog entry 1" }, { "title": "blog entry 3" } ] }, { "name": "author 2", "email": "Java dev", "blogEntries": [ { "title": "blog entry 2" }, { "title": "blog entry 4" } ] } ] }
  14. GraphQL query - filter authors(filter : {id : 1 })

    { name email blogEntries { title } }
  15. GraphQL query - filter authors(filter : {id : 1 })

    { name email blogEntries { title } } { "data": { "authors": [ { "name": "author 1", "email": "Python dev", "blogEntries": [ { "title": "blog entry 1" }, { "title": "blog entry 3" } ] } ] } }
  16. GraphQL mutation mutation addAuthorMutation($authorInfo: addAuthorInput!) { addAuthor(input : $authorInfo) {

    id name bio email } } { "authorInfo": { "id": 1, “name" : "Krzysztof Pawlowski", "bio" : "java dev", "email" : "[email protected]" } }
  17. GraphQL mutation mutation addAuthorMutation($authorInfo: addAuthorInput!) { addAuthor(input : $authorInfo) {

    id name bio email } } { "authorInfo": { "id": 1, “name" : "Krzysztof Pawlowski", "bio" : "java dev", "email" : "[email protected]" } } { "data": { "addAuthor": { "id": 1, "name": "Krzysztof Pawlowski", "bio": "java dev", "email": 
 “[email protected]" } } }
  18. GraphQL schema type Author {
 id: Long! name: String bio:

    String email: String
 blogEntries: [BlogEntry] }
 
 type BlogEntry { id: Long! title: String! comments: [Comment] } type Comment { id: Long! author: String comment: String }

  19. GraphQL schema type Author {
 id: Long! name: String bio:

    String email: String
 blogEntries: [BlogEntry] }
 
 type BlogEntry { id: Long! title: String! comments: [Comment] } type Comment { id: Long! author: String comment: String }
 type Query { authors(id: Long!): Author blogEntries(id: Long!): BlogEntry comments(id: Long!): Comment } type Mutation { addAuthor(author: Author!): Author updateAuthor(author: Author!): Author deleteAuthor(id: Long!): Author … }
  20. GraphQL schema type Author {
 id: Long! name: String bio:

    String email: String
 blogEntries: [BlogEntry] }
 
 type BlogEntry { id: Long! title: String! comments: [Comment] } type Comment { id: Long! author: String comment: String }
 type Query { authors(id: Long!): Author blogEntries(id: Long!): BlogEntry comments(id: Long!): Comment } type Mutation { addAuthor(author: Author!): Author updateAuthor(author: Author!): Author deleteAuthor(author: Author!): Author … } schema { query: Query mutation: Mutation }
  21. Benefits of GraphQL ‣flexibility and efficiency ‣one end-point ‣self-documenting (strong

    typing and schema) ‣query validation ‣easy to implement consumer-driven contracts
  22. graphql-java library ‣implements GraphQL specification ‣open source ‣requires at least

    Java 8 ‣allows to implement GraphQL schema ‣contains executor for GraphQL queries and mutations ‣BUT a lot of boiler-plate code to configure GraphQL
 and no support for Spring Framework
  23. Spring Boot Starter for GraphQL ‣adding Maven dependency creates GraphQL

    controller under
 /v1/graphql <dependency> <groupId>com.merapar</groupId> <artifactId>graphql-spring-boot-starter</artifactId> <version>1.0.2</version> </dependency> ‣adding new queries and mutation is a matter of implementing GraphQlFields interface ‣very useful with micro-services
  24. Error handling ‣All requests returns 200 response ‣Stack trace in

    “error” field of response json ‣Error msg in “message” field of response json

  25. Caching GraphQL requests ‣one endpoint —> no default HTTP level

    caching ‣no built-in mechanism for caching in GraphQL
  26. Caching for aggregation service service 1 service 2 service 3

    client 1 client 2 client 3 cache 1 cache 2 cache 3 GraphQL DataFetchers GraphQL API GraphQL API Aggregation Service Google Guava Cache
  27. Cache invalidation in aggregation service ‣Cache expiration (based on cached

    items TTL) ‣Invalidating key ‣when mutation executed (data changed only via GraphQL API) ‣when notification from service received (via RabbitMQ, Kafka, other messaging system)
  28. Performance optimisation ‣gRPC vs http (REST) ‣Reactive Streams for asynchronous

    calls to service’s API ‣RxJava ‣Project Reactor
  29. Unpredictable execution ‣Composition might result in not efficient calls (many

    repositories, many services called at once) ‣End-user doesn’t know the internal implementation ‣Solution: ‣No cycles in schema ‣If cycles —> max level of nesting 
 in response json must be set type Person { id: ID! name: String! friends: [Person] }
  30. File upload ‣No such feature in GraphQL ‣We had to

    implement REST endpoint for file uploading
  31. Security of GraphQL - JWT Token ‣No built-in mechanism for

    authentication and authorisation in GraphQL ‣JWT token (eg. Auth0 or Cognito) ‣GraphQL end-point secured like REST endpoint in Spring Boot ‣Roles must be handled in Data Fetchers