Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

GraphQL y Groovy

624 views

Published on

Talk (Spanish) about GraphQL and Groovy implementations.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

GraphQL y Groovy

  1. 1. #madridGUG @marioggar © Mario Garcia 2018 GraphQL and Groovy@marioggar 1
  2. 2. #madridGUG @marioggar © Mario Garcia 2018 Me presento Nombre Mario Garcia Redes Sociales: https://twitter.com/marioggar https://github.com/mariogarcia 2 . 1
  3. 3. #madridGUG @marioggar © Mario Garcia 2018 Miembro del Mgug… 2 . 2
  4. 4. #madridGUG @marioggar © Mario Garcia 2018 Os interesa GraphQL porque… He oido que GraphQL es lo que esta de moda Estoy harto de hacer REST Me aburria y he venido a pasar el rato Sea lo que sea… 3 . 1
  5. 5. #madridGUG @marioggar © Mario Garcia 2018 3 . 2
  6. 6. #madridGUG @marioggar © Mario Garcia 2018 Que vamos a ver hoy ? 4 . 1
  7. 7. #madridGUG @marioggar © Mario Garcia 2018 Indice GraphQL en general GraphQL como lenguaje de consultas GraphQL + Ratpack/Grails Conclusiones 4 . 2
  8. 8. #madridGUG @marioggar © Mario Garcia 2018 GraphQL en general 5 . 1
  9. 9. #madridGUG @marioggar © Mario Garcia 2018 Que es GraphQL ? Es un lenguaje de consultas Usa un sistema de tipos para de nir esas consultas 5 . 2
  10. 10. #madridGUG @marioggar © Mario Garcia 2018 Que NO es GraphQL No es un web framework No tiene que ver necesariamente con HTTP Y desde luego… GraphQL no es REST 5 . 3
  11. 11. #madridGUG @marioggar © Mario Garcia 2018 GraphQL vs Rest 5 . 4
  12. 12. #madridGUG @marioggar © Mario Garcia 2018 Que los diferencia ? 5 . 5
  13. 13. #madridGUG @marioggar © Mario Garcia 2018 Lo primero Mientras que REST es buenas practicas + HTTP GraphQL es SOLO un lenguaje de consulta 5 . 6
  14. 14. #madridGUG @marioggar © Mario Garcia 2018 Diferencias 5 . 7
  15. 15. #madridGUG @marioggar © Mario Garcia 2018 Recursos vs Consultas Rest: 1 URI ⇒ 1 recurso GraphQL: 1 URI ⇒ N consultas 5 . 8
  16. 16. #madridGUG @marioggar © Mario Garcia 2018 Recursos vs Consultas 5 . 9
  17. 17. #madridGUG @marioggar © Mario Garcia 2018 Recursos vs Consultas 5 . 10
  18. 18. #madridGUG @marioggar © Mario Garcia 2018 Manejo de errores Rest ⇒ HTTP codes GraphQL error messages in responses 5 . 11
  19. 19. #madridGUG @marioggar © Mario Garcia 2018 Tipo de Aplicaciones Rest == HTTP GraphQL puede usarse con: HTTP, JDBC, AMQP…etc 5 . 12
  20. 20. #madridGUG @marioggar © Mario Garcia 2018 Documentacion Rest ⇒ varias implementaciones, no hay especi cacion (destaca Swagger) GraphQL ⇒ Todos los motores GraphQL exponen el esquema de la misma manera 5 . 13
  21. 21. #madridGUG @marioggar © Mario Garcia 2018 Front-End friendly Rest ⇒ Back a veces no puede ir a la velocidad que demanda el front GraphQL ⇒ Mucha mas exibilidad del back para dar respuesta al front 5 . 14
  22. 22. #madridGUG @marioggar © Mario Garcia 2018 Soy back quieres ser mi amigo ? 5 . 15
  23. 23. #madridGUG @marioggar © Mario Garcia 2018 Resumiendo 1 solo endpoint Deja que nos concentremos solo en la consulta Granularidad en la carga de datos Documentacion out-of-the-box 5 . 16
  24. 24. #madridGUG @marioggar © Mario Garcia 2018 El ejemplo Peliculas de James Bond Aunque ahora el client SOLO sera el navegador… Los conceptos nos serviran para cualquier tipo de cliente 5 . 17
  25. 25. #madridGUG @marioggar © Mario Garcia 2018 Ejecutando consultas 6 . 1
  26. 26. #madridGUG @marioggar © Mario Garcia 2018 Pasos para ejecutar una consulta De nir TIPOS De nir CONSULTAS Ejecutar consultas contra el esquema 6 . 2
  27. 27. #madridGUG @marioggar © Mario Garcia 2018 Primer ejemplo 6 . 3
  28. 28. #madridGUG @marioggar © Mario Garcia 2018 Primer ejemplo: SCHEMA type Film { title: !String year: Int } type Queries { lastFilm: Film filmByYear(year: Int): Film } schema { query: Queries } http://facebook.github.io/graphql/ 6 . 4
  29. 29. #madridGUG @marioggar © Mario Garcia 2018 Primer ejemplo: TIPOS El cliente PUEDE agregar/omitir tantos campos opcionales como quiera El cliente DEBE agregar los campos obligatorios en la consulta type Film { title: String! year: Int } 6 . 5
  30. 30. #madridGUG @marioggar © Mario Garcia 2018 Primer ejemplo : CONSULTAS Las consultas siempre usan tipos y escalares Las consultas puede requerir argumentos type Queries { lastFilm: Film filmByYear(year: Int): Film } 6 . 6
  31. 31. #madridGUG @marioggar © Mario Garcia 2018 Primer ejemplo : EJECUCION query: "give me the last James Bond lm with its title result: "SPECTRE" { lastFilm { title } } { "data": { "lastFilm": { "title": "SPECTRE" } } } 6 . 7
  32. 32. #madridGUG @marioggar © Mario Garcia 2018 Mirando un poco mas de cerca query 1. lastFilm: Es la consulta en la que estoy interesado 2. title: Es un campo especi co del tipo que se devuelve (Film) { lastFilm { (1) title (2) } } 6 . 8
  33. 33. #madridGUG @marioggar © Mario Garcia 2018 Validacion title es obligatorio Consulta invalida type Film { title: String! year: Int } { lastFilm } 6 . 9
  34. 34. #madridGUG @marioggar © Mario Garcia 2018 6 . 10
  35. 35. #madridGUG @marioggar © Mario Garcia 2018 6 . 11
  36. 36. #madridGUG @marioggar © Mario Garcia 2018 GraphQL DSL (GQL) DSL sobre GraphQL-Java Todavia alpha Se agradece Feeback :) https://github.com/grooviter/gql 6 . 12
  37. 37. #madridGUG @marioggar © Mario Garcia 2018 Groovy time: TIPOS GraphQL Groovy type Film { title: String! year: Int } static GraphQLObjectType Film = DSL.type('Film') { field 'title', nonNull(GraphQLString) field 'year', GraphQLInt } 6 . 13
  38. 38. #madridGUG @marioggar © Mario Garcia 2018 Groovy time: CONSULTAS type Queries { lastFilm: Film filmByYear(year: Int): Film } schema { query: Queries } return DSL.schema { queries('Queries') { field('lastFilm') { type Types.Film fetcher(Queries.&findLastFilm) // from db } field('filmByYear') { type Types.Film fetcher(Queries.&findByYear) // from db argument 'year', GraphQLString } } } 6 . 14
  39. 39. #madridGUG @marioggar © Mario Garcia 2018 Groovy time: TEST query ejecucion queryString = ''' { lastFilm { year title } } ''' def result = DSL .execute(schema, queryString) .data as Map<String,Object> 6 . 15
  40. 40. #madridGUG @marioggar © Mario Garcia 2018 Groovy time: EJECUCION (II) ejecucion when: 'executing the query' def result = DSL .execute(schema, queryString) .data as Map<String,Object> then: 'we should get the expected movie' result == [lastFilm: [year: 2015, title: 'SPECTRE']] where: 'the queryString literal is' queryString = ''' { lastFilm { year title } } ''' 6 . 16
  41. 41. #madridGUG @marioggar © Mario Garcia 2018 Queries with arguments 6 . 17
  42. 42. #madridGUG @marioggar © Mario Garcia 2018 Pelicula de 1962 ? consultas ejecucion de consultas queryString = ''' query FindBondFilmByYear($year: String){ filmByYear(year: $year) { year title } } ''' def result = DSL .execute(schema, queryString, [year: year]) 6 . 18
  43. 43. #madridGUG @marioggar © Mario Garcia 2018 DR. NO 6 . 19
  44. 44. #madridGUG @marioggar © Mario Garcia 2018 Sobre consultas & mutaciones Consultas suelen poder ejecutarse en batch Consultas suelen poder ejecutarse en paralelo Mutaciones se ejecutan de manera secuencial 6 . 20
  45. 45. #madridGUG @marioggar © Mario Garcia 2018 Agregacion de consultas varias consultas a la vez queryString = ''' query Home($year: String){ filmByYear(year: $year) { year title } lastFilm { title year } } ''' 6 . 21
  46. 46. #madridGUG @marioggar © Mario Garcia 2018 Ahora vamos a exponer esto a traves de HTTP 6 . 22
  47. 47. #madridGUG @marioggar © Mario Garcia 2018 Http + GraphQL 7 . 1
  48. 48. #madridGUG @marioggar © Mario Garcia 2018 Ratpack + GraphQL 7 . 2
  49. 49. #madridGUG @marioggar © Mario Garcia 2018 Tecnologias Ratpack GQL GraphiQL 7 . 3
  50. 50. #madridGUG @marioggar © Mario Garcia 2018 Tipo Film static GraphQLObjectType Film = DSL.type('Film') { field 'title', nonNull(GraphQLString) field 'year', GraphQLInt } 7 . 4
  51. 51. #madridGUG @marioggar © Mario Garcia 2018 Consultas return DSL.schema { queries('Queries') { field('lastFilm') { type Types.Film fetcher(Queries.&findLastFilm) // from db } field('filmByYear') { type Types.Film fetcher(Queries.&findByYear) // from db argument 'year', GraphQLString } } } 7 . 5
  52. 52. #madridGUG @marioggar © Mario Garcia 2018 Ratpack Handler @Override void handle(Context ctx) throws Exception { def payload = ctx.get(Map) def query = payload.query def params = payload.variables as Map<String,Object> Blocking.get { execute(schema, "$query", params) }.then { ExecutionResult result -> ctx.render(json(errors: result.errors, data: result.data)) } } 7 . 6
  53. 53. #madridGUG @marioggar © Mario Garcia 2018 Uri mapping 1. GraphQL endpoint 2. GraphiQL prefix('graphql') { post(Handler) // GraphQL } files { dir('static').indexFiles('index.html') // GraphiQL } 7 . 7
  54. 54. #madridGUG @marioggar © Mario Garcia 2018 Showtime! 7 . 8
  55. 55. #madridGUG @marioggar © Mario Garcia 2018 Grails + GORM 7 . 9
  56. 56. #madridGUG @marioggar © Mario Garcia 2018 GORM GraphQL https://grails.github.io/gorm-graphql/latest/guide/index.html 7 . 10
  57. 57. #madridGUG @marioggar © Mario Garcia 2018 Tu aplicacion accede a bases de datos ? 7 . 11
  58. 58. #madridGUG @marioggar © Mario Garcia 2018 Por que Grails/GORM ? GORM ❤ SQL/NoSQL Databases Entidades Gorm = Tipos/Queries/Mutations GraphQL GraphiQL out-of-the-box Plugin Grails 3 / Standalone 7 . 12
  59. 59. #madridGUG @marioggar © Mario Garcia 2018 Mapear tipos class Film { static graphql = true // exposed via GraphQL String title Integer year static constraints = { year nullable: false // GraphQL validation } } 7 . 13
  60. 60. #madridGUG @marioggar © Mario Garcia 2018 Operaciones por defecto 7 . 14
  61. 61. #madridGUG @marioggar © Mario Garcia 2018 Type Operation Query lm(id: ..) Query lmList(max: .., sort: .., etc) Query lmCount Mutation lmCreate( lm: {}) Mutation lmUpdate(id: .., lm: {}) Mutation lmDelete(id: ..) 7 . 15
  62. 62. #madridGUG @marioggar © Mario Garcia 2018 Custom Queries import org.grails.gorm.graphql.entity.dsl.GraphQLMapping class Film { static graphql = GraphQLMapping.build { query('lastFilm', Film) { dataFetcher { env -> Film.last(sort: "year") } } } String title Integer year static constraints = { year nullable: false } 7 . 16
  63. 63. #madridGUG @marioggar © Mario Garcia 2018 Grail & Spring Puedes acceder a cualquier bean en un fetcher Por ejemplo springSecurityService fetcher { env -> env.context.springSecurityService } 7 . 17
  64. 64. #madridGUG @marioggar © Mario Garcia 2018 Ademas Se puede optimizar la forma en la que se realizan las consultas Se pueden elegir como serializar los datos escalares (Fechas, monedas…) 7 . 18
  65. 65. #madridGUG @marioggar © Mario Garcia 2018 Que me dejo… ? 8 . 1
  66. 66. #madridGUG @marioggar © Mario Garcia 2018 Optimizaciones en las consultas Recuerda que cada propiedad del modelo puede tener su propio fetcher Eso deberia hacer que se pudieran optimizar las consultas 8 . 2
  67. 67. #madridGUG @marioggar © Mario Garcia 2018 Instrumentacion/Interceptor Interceptan la ejecucion por diferentes motivos Autorizar Logear Lanzar cosas en background 8 . 3
  68. 68. #madridGUG @marioggar © Mario Garcia 2018 Seguridad Depende de lo que estes utilizando HTTP ⇒ JWT esta de moda 8 . 4
  69. 69. #madridGUG @marioggar © Mario Garcia 2018 Relay Buenas practicas con GraphQL Implementadas como especi cacion en una biblioteca JS https://facebook.github.io/relay/ 8 . 5
  70. 70. #madridGUG @marioggar © Mario Garcia 2018 Relay Paginacion (restrictiva) Identi cadores (hashing) Uso de HTTP (cache por ejemplo) … http://graphql.org/learn/best-practices/ 8 . 6
  71. 71. #madridGUG @marioggar © Mario Garcia 2018 Conclusiones 8 . 7
  72. 72. #madridGUG @marioggar © Mario Garcia 2018 Conclusiones GraphQL no tiene que ser un sustituto 1 - 1 de REST pero… Es una mejora en la comunicacion con el front-end Front ❤ Back 8 . 8
  73. 73. #madridGUG @marioggar © Mario Garcia 2018 Gracias! 8 . 9
  74. 74. #madridGUG @marioggar © Mario Garcia 2018 Questions & Answers 9

×