Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.
#greachConf @marioggar ©	Mario	Garcia	2017
GRAPHQL	AND	GROOVYGRAPHQL	AND	GROOVYGRAPHQL	AND	GROOVYGRAPHQL	AND	GROOVYGRAPHQL...
#greachConf @marioggar ©	Mario	Garcia	2017
ABOUT	ME
Name
Mario	Garcia
You	can	find	me:
https://twitter.com/marioggar
https...
#greachConf @marioggar ©	Mario	Garcia	2017
PROUD	MEMBER	OF…​
2 . 2
#greachConf @marioggar ©	Mario	Garcia	2017
WORKING	AT	KALEIDOS
2 . 3
#greachConf @marioggar ©	Mario	Garcia	2017
BUT	A	GREAT	FAMILY
2 . 4
#greachConf @marioggar ©	Mario	Garcia	2017
LET	ME	TELL	YOU	WHY	YOU’RE	HERE…​
I’ve	heard	GraphQL	is	the	next	big	thing
If	I...
#greachConf @marioggar ©	Mario	Garcia	2017
3 . 2
#greachConf @marioggar ©	Mario	Garcia	2017
SUMMARY
4 . 1
#greachConf @marioggar ©	Mario	Garcia	2017
GraphQL	overview
GraphQL	types	query	language
GraphQL	+	JVM	+	HTTP
Conclusions
...
#greachConf @marioggar ©	Mario	Garcia	2017
GRAPHQL	OVERVIEW
5 . 1
#greachConf @marioggar ©	Mario	Garcia	2017
WHAT	IS	GRAPHQL
Is	a	query	language
Is	also	a	server-side	runtime	spec
It	uses	...
#greachConf @marioggar ©	Mario	Garcia	2017
WHAT	IS	NOT	GRAPHQL
Is	not	a	web	framework
Is	not	about	HTTP
And	definitely,	de...
#greachConf @marioggar ©	Mario	Garcia	2017
GRAPHQL	VS	REST
5 . 4
#greachConf @marioggar ©	Mario	Garcia	2017
WHY	WE	COULD	WANT	TO	MOVE	TO	GRAPHQL	?
5 . 5
#greachConf @marioggar ©	Mario	Garcia	2017
FIRST	OF	ALL
While	REST	is	an	architectural	concept
GraphQL	is	just	a	query	lan...
#greachConf @marioggar ©	Mario	Garcia	2017
DIFFERENCES
Resources	vs	Queries
Rest:	1	URI	=⇒	1	resource
GraphQL:	1	URI	=⇒	n	...
#greachConf @marioggar ©	Mario	Garcia	2017
NO	PROBLEM.	I'LL	SEE	WHAT	I	CAN	DO
5 . 8
#greachConf @marioggar ©	Mario	Garcia	2017
THE	CHALLENGE
I	want	to	expose	all	James	Bond	films	information
Users	will	ONLY...
#greachConf @marioggar ©	Mario	Garcia	2017
WHAT	DO	WE	DO	?
We	build	up	1	API	endpoint
Only	targets	1	device
Still	we	can	c...
#greachConf @marioggar ©	Mario	Garcia	2017
THEN	SHIT	HAPPENS!
5 . 11
#greachConf @marioggar ©	Mario	Garcia	2017
AND	NORMALLY	GETS	WORST
Users	want	to	see	A,	B,	and	C	in	user	home
Front	end	co...
#greachConf @marioggar ©	Mario	Garcia	2017
5 . 13
#greachConf @marioggar ©	Mario	Garcia	2017
THEN	YOU	REMEMBER	THAT…​
ONLY	means	in	addition
FOR	NOW	means	within	the	next	t...
#greachConf @marioggar ©	Mario	Garcia	2017
GRAPHQL	+	HTTP	TO	THE	RESCUE!
5 . 15
#greachConf @marioggar ©	Mario	Garcia	2017
5 . 16
#greachConf @marioggar ©	Mario	Garcia	2017
WHAT	CHANGED	?
GraphQL	HTTP	endpoint	as	a	common	query	interface
Therefore	a	lo...
#greachConf @marioggar ©	Mario	Garcia	2017
EXECUTING	QUERIES
6 . 1
#greachConf @marioggar ©	Mario	Garcia	2017
STEPS	TO	EXECUTE	A	QUERY
Define	TYPES
Define	QUERIES
Execute	queries	against	sc...
#greachConf @marioggar ©	Mario	Garcia	2017
FIRST	EXAMPLE
6 . 3
#greachConf @marioggar ©	Mario	Garcia	2017
FIRST	EXAMPLE:	SCHEMA
type	Film	{
		title:	!String
		year:	Int
}
type	Queries	{...
#greachConf @marioggar ©	Mario	Garcia	2017
FIRST	EXAMPLE:	TYPES
Client	CAN	add/omit	as	many	optional	fields	as	it	wants
Cl...
#greachConf @marioggar ©	Mario	Garcia	2017
FIRST	EXAMPLE	:	QUERIES
Queries	always	use	types	or	scalars
Queries	may	have	ar...
#greachConf @marioggar ©	Mario	Garcia	2017
FIRST	EXAMPLE	:	EXECUTE	QUERY
query:	"give	me	the	last	James	Bond	film	with	its...
#greachConf @marioggar ©	Mario	Garcia	2017
LITTLE	BIT	CLOSER
query
1.	lastFilm:	Is	the	query	I’m	interested	in
2.	title:	I...
#greachConf @marioggar ©	Mario	Garcia	2017
VALIDATION
title	is	mandatory
invalid	query
type	Film	{
		title:	!String
		year...
#greachConf @marioggar ©	Mario	Garcia	2017
6 . 10
#greachConf @marioggar ©	Mario	Garcia	2017
JVM	LIBRARIES	OUT	THERE!
GraphQL-Java
https://github.com/graphql-java/graphql-j...
#greachConf @marioggar ©	Mario	Garcia	2017
FIRST	EXAMPLE	REVISITED:	TYPES
type	Film	{
		title:	!String
		year:	Int
}
Graph...
#greachConf @marioggar ©	Mario	Garcia	2017
FIRST	EXAMPLE	REVISITED:	QUERIES
type	Queries	{
			lastFilm:	Film
			filmByYear...
#greachConf @marioggar ©	Mario	Garcia	2017
DATA	FETCHER
Functional	Interface	graphql.schema.DataFetcher
If	using	JDK	could...
#greachConf @marioggar ©	Mario	Garcia	2017
FIRST	EXAMPLE	REVISITED:	EXECUTION
1.	schema:	query	+	types	definition
2.	query...
#greachConf @marioggar ©	Mario	Garcia	2017
TOO	MUCH	JAVA	CODE…​
6 . 16
#greachConf @marioggar ©	Mario	Garcia	2017
6 . 17
#greachConf @marioggar ©	Mario	Garcia	2017
GRAPHQL	DSL	(GQL)
DSL	over	GraphQL-Java
Still	alpha
Feeback	is	very	welcome	:)
...
#greachConf @marioggar ©	Mario	Garcia	2017
GROOVY	TIME:	TYPES
type	Film	{
		title:	!String
		year:	Int
}
DSL.type('Film')	...
#greachConf @marioggar ©	Mario	Garcia	2017
GROOVY	TIME:	TYPES	(II)
vs
GraphQLObjectType.newObject()
.name("Film")
.field(n...
#greachConf @marioggar ©	Mario	Garcia	2017
GROOVY	TIME:	QUERIES
type	Queries	{
			lastFilm:	Film
			filmByYear(year:	Int):...
#greachConf @marioggar ©	Mario	Garcia	2017
GROOVY	TIME:	QUERIES	(II)
vs
GraphQLObjectType	lastFilm	=
		GraphQLObjectType.n...
#greachConf @marioggar ©	Mario	Garcia	2017
GROOVY	TIME:	QUERY	EXECUTION
yields
def	result	=	DSL
		.execute(schema,	querySt...
#greachConf @marioggar ©	Mario	Garcia	2017
GROOVY	TIME:	QUERY	EXECUTION	(II)
vs
Map<String,Object>	result	=	new	GraphQL(sc...
#greachConf @marioggar ©	Mario	Garcia	2017
QUERIES	WITH	ARGUMENTS
6 . 25
#greachConf @marioggar ©	Mario	Garcia	2017
WHO	KNOWS	THE	TITLE	OF	1962	?
query
query	execution
queryString	=	'''
		query	F...
#greachConf @marioggar ©	Mario	Garcia	2017
DR.	NO
[byYear:	[
				title:	'DR.	NO',
				year:	"1962"
		]
]
6 . 27
#greachConf @marioggar ©	Mario	Garcia	2017
NOW…​
6 . 28
#greachConf @marioggar ©	Mario	Garcia	2017
WOULDN’T	IT	COOL	IF	I	EXPOSE	THIS	TO	THE
WORLD	?
6 . 29
#greachConf @marioggar ©	Mario	Garcia	2017
HTTP	+	GRAPHQL
7 . 1
#greachConf @marioggar ©	Mario	Garcia	2017
RATPACK	+	GRAPHQL
7 . 2
#greachConf @marioggar ©	Mario	Garcia	2017
TECHNOLOGIES	USED
Ratpack
GraphQL-java
GQL
GraphiQL
7 . 3
#greachConf @marioggar ©	Mario	Garcia	2017
FULL	FILM	TYPE
And	it	fits	in	the	slide!!
static	final	GraphQLObjectType	Film	=...
#greachConf @marioggar ©	Mario	Garcia	2017
QUERIES
return	DSL.schema	{
		query('Queries')	{
				field('lastFilm')	{
						...
#greachConf @marioggar ©	Mario	Garcia	2017
RATPACK	HANDLER
class	GraphQLHandler	implements	Handler	{
		@Inject
		GraphQLSc...
#greachConf @marioggar ©	Mario	Garcia	2017
URI	MAPPING
1.	GraphQL	endpoint
2.	GraphiQL	web	console
handlers	{
		prefix('gr...
#greachConf @marioggar ©	Mario	Garcia	2017
SHOWTIME!
query	UserHome($actor:	String,	$year:	String)	{
		latest:	lastFilm	{
...
#greachConf @marioggar ©	Mario	Garcia	2017
A	WORD	ON	QUERIES	&	MUTATIONS
Queries	are	supposed	to	be	able	to	be	batched
Que...
#greachConf @marioggar ©	Mario	Garcia	2017
GRAILS	+	RELAY
7 . 10
#greachConf @marioggar ©	Mario	Garcia	2017
RELAY	?
Good	GraphQL	practices	implemented	in	a	JS	library
https://facebook.git...
#greachConf @marioggar ©	Mario	Garcia	2017
RELAY
How	to	handle	pagination
How	to	handle	ids
HTTP	recommended	features
…​
h...
#greachConf @marioggar ©	Mario	Garcia	2017
GORM	GRAPHQL
Plugin	Grails	3
https://github.com/mrcirillo/relay-gorm-connector
...
#greachConf @marioggar ©	Mario	Garcia	2017
GRAPHQL	SCHEMA
@RelayType(description='An	optional	description	of	a	film')
clas...
#greachConf @marioggar ©	Mario	Garcia	2017
GRAILS	URLMAPPINGS
post	"/graphql"(controller:	"graph")
7 . 15
#greachConf @marioggar ©	Mario	Garcia	2017
GRAILS	CONTROLLER
class	GraphController	{
				def	relayService	//	provided	by	p...
#greachConf @marioggar ©	Mario	Garcia	2017
GRAPHQL	BEST	PRACTICES	HINT:	ID	HASHING
Instead	of	passing	1	use	a	hash	like	ha...
#greachConf @marioggar ©	Mario	Garcia	2017
CONCLUSIONS
Is	not	GraphQL	instead	of	REST
Is	about	GraphQL	over	your	existent	...
#greachConf @marioggar ©	Mario	Garcia	2017
THANK	YOU!
8 . 2
#greachConf @marioggar ©	Mario	Garcia	2017
QUESTIONS	&	ANSWERS
9
Próxima SlideShare
Cargando en…5
×

GraphQL and Groovy

1.221 visualizaciones

Publicado el

Talk at greachconf.com about developing GraphQL applications using Groovy

Publicado en: Tecnología
  • Sé el primero en comentar

GraphQL and Groovy

  1. 1. #greachConf @marioggar © Mario Garcia 2017 GRAPHQL AND GROOVYGRAPHQL AND GROOVYGRAPHQL AND GROOVYGRAPHQL AND GROOVYGRAPHQL AND GROOVYGRAPHQL AND GROOVY GRAPHQL AND GROOVY GRAPHQL AND GROOVY GRAPHQL AND GROOVY GRAPHQL AND GROOVY GRAPHQL AND GROOVY GRAPHQL AND GROOVY GRAPHQL AND GROOVY GRAPHQL AND GROOVY GRAPHQL AND GROOVYGRAPHQL AND GROOVY @marioggar 1
  2. 2. #greachConf @marioggar © Mario Garcia 2017 ABOUT ME Name Mario Garcia You can find me: https://twitter.com/marioggar https://github.com/mariogarcia 2 . 1
  3. 3. #greachConf @marioggar © Mario Garcia 2017 PROUD MEMBER OF…​ 2 . 2
  4. 4. #greachConf @marioggar © Mario Garcia 2017 WORKING AT KALEIDOS 2 . 3
  5. 5. #greachConf @marioggar © Mario Garcia 2017 BUT A GREAT FAMILY 2 . 4
  6. 6. #greachConf @marioggar © Mario Garcia 2017 LET ME TELL YOU WHY YOU’RE HERE…​ I’ve heard GraphQL is the next big thing If I do one more REST app I’ll kill myself I didn’t find any other interesting talk Whatever it is…​ 3 . 1
  7. 7. #greachConf @marioggar © Mario Garcia 2017 3 . 2
  8. 8. #greachConf @marioggar © Mario Garcia 2017 SUMMARY 4 . 1
  9. 9. #greachConf @marioggar © Mario Garcia 2017 GraphQL overview GraphQL types query language GraphQL + JVM + HTTP Conclusions 4 . 2
  10. 10. #greachConf @marioggar © Mario Garcia 2017 GRAPHQL OVERVIEW 5 . 1
  11. 11. #greachConf @marioggar © Mario Garcia 2017 WHAT IS GRAPHQL Is a query language Is also a server-side runtime spec It uses a type system to define those queries 5 . 2
  12. 12. #greachConf @marioggar © Mario Garcia 2017 WHAT IS NOT GRAPHQL Is not a web framework Is not about HTTP And definitely, definitely, definitely…​ GraphQL is not REST 5 . 3
  13. 13. #greachConf @marioggar © Mario Garcia 2017 GRAPHQL VS REST 5 . 4
  14. 14. #greachConf @marioggar © Mario Garcia 2017 WHY WE COULD WANT TO MOVE TO GRAPHQL ? 5 . 5
  15. 15. #greachConf @marioggar © Mario Garcia 2017 FIRST OF ALL While REST is an architectural concept GraphQL is just a query language 5 . 6
  16. 16. #greachConf @marioggar © Mario Garcia 2017 DIFFERENCES Resources vs Queries Rest: 1 URI =⇒ 1 resource GraphQL: 1 URI =⇒ n dataset Application layer Rest == HTTP GraphQL is not tied to any specific protocol Front-End friendly Rest: Back end is the king ...and the bottleneck 5 . 7
  17. 17. #greachConf @marioggar © Mario Garcia 2017 NO PROBLEM. I'LL SEE WHAT I CAN DO 5 . 8
  18. 18. #greachConf @marioggar © Mario Garcia 2017 THE CHALLENGE I want to expose all James Bond films information Users will ONLY use web browsers...FOR NOW BUT we have to be ready for mobile AT SOME POINT 5 . 9
  19. 19. #greachConf @marioggar © Mario Garcia 2017 WHAT DO WE DO ? We build up 1 API endpoint Only targets 1 device Still we can create a couple of views for the same data 5 . 10
  20. 20. #greachConf @marioggar © Mario Garcia 2017 THEN SHIT HAPPENS! 5 . 11
  21. 21. #greachConf @marioggar © Mario Garcia 2017 AND NORMALLY GETS WORST Users want to see A, B, and C in user home Front end could reuse views and/or aggregate calls still may not be enough and they will start asking back-end to do more…​ and more …​ and more…​ 5 . 12
  22. 22. #greachConf @marioggar © Mario Garcia 2017 5 . 13
  23. 23. #greachConf @marioggar © Mario Garcia 2017 THEN YOU REMEMBER THAT…​ ONLY means in addition FOR NOW means within the next two weeks BUT means winter is coming! and of course…​AT SOME POINT means probably next week 5 . 14
  24. 24. #greachConf @marioggar © Mario Garcia 2017 GRAPHQL + HTTP TO THE RESCUE! 5 . 15
  25. 25. #greachConf @marioggar © Mario Garcia 2017 5 . 16
  26. 26. #greachConf @marioggar © Mario Garcia 2017 WHAT CHANGED ? GraphQL HTTP endpoint as a common query interface Therefore a lot more flexibility for front end Your REST/NOT-REST microservices will be easier to maintain Will be easier to keep one single responsability in each one of them 5 . 17
  27. 27. #greachConf @marioggar © Mario Garcia 2017 EXECUTING QUERIES 6 . 1
  28. 28. #greachConf @marioggar © Mario Garcia 2017 STEPS TO EXECUTE A QUERY Define TYPES Define QUERIES Execute queries against schema 6 . 2
  29. 29. #greachConf @marioggar © Mario Garcia 2017 FIRST EXAMPLE 6 . 3
  30. 30. #greachConf @marioggar © Mario Garcia 2017 FIRST EXAMPLE: 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
  31. 31. #greachConf @marioggar © Mario Garcia 2017 FIRST EXAMPLE: TYPES Client CAN add/omit as many optional fields as it wants Client MUST add mandatory fields in the query type Film { title: !String year: Int } 6 . 5
  32. 32. #greachConf @marioggar © Mario Garcia 2017 FIRST EXAMPLE : QUERIES Queries always use types or scalars Queries may have arguments type Queries { lastFilm: Film filmByYear(year: Int): Film } 6 . 6
  33. 33. #greachConf @marioggar © Mario Garcia 2017 FIRST EXAMPLE : EXECUTE QUERY query: "give me the last James Bond film with its title result: "SPECTRE" { lastFilm { title } } { "data": { "lastFilm": { "title": "SPECTRE" } } } 6 . 7
  34. 34. #greachConf @marioggar © Mario Garcia 2017 LITTLE BIT CLOSER query 1. lastFilm: Is the query I’m interested in 2. title: Is a specific field in the return type (Film) { lastFilm { (1) title (2) } } 6 . 8
  35. 35. #greachConf @marioggar © Mario Garcia 2017 VALIDATION title is mandatory invalid query type Film { title: !String year: Int } { lastFilm } 6 . 9
  36. 36. #greachConf @marioggar © Mario Garcia 2017 6 . 10
  37. 37. #greachConf @marioggar © Mario Garcia 2017 JVM LIBRARIES OUT THERE! GraphQL-Java https://github.com/graphql-java/graphql-java 6 . 11
  38. 38. #greachConf @marioggar © Mario Garcia 2017 FIRST EXAMPLE REVISITED: TYPES type Film { title: !String year: Int } GraphQLObjectType.newObject() .name("Film") .field(newFieldDefinition() .type(GraphQLString) .name("title")) .field(newFieldDefinition() .type(GraphQLInt) .name("year")) .build(); 6 . 12
  39. 39. #greachConf @marioggar © Mario Garcia 2017 FIRST EXAMPLE REVISITED: QUERIES type Queries { lastFilm: Film filmByYear(year: Int): Film } schema { query: Queries } GraphQLObjectType lastFilm = GraphQLObjectType.newObject() .name("Queries") .field(newFieldDefinition() .type(filmType) .name("lastFilm") .dataFetcher(Queries::findLastFilm)) .build(); return GraphQLSchema .newSchema() .query(lastFilm) .build(); 6 . 13
  40. 40. #greachConf @marioggar © Mario Garcia 2017 DATA FETCHER Functional Interface graphql.schema.DataFetcher If using JDK could use method reference If using Groovy Closures FTW If using Groovy w Parrot → Both o/ 6 . 14
  41. 41. #greachConf @marioggar © Mario Garcia 2017 FIRST EXAMPLE REVISITED: EXECUTION 1. schema: query + types definition 2. query: query string 3. context: helpful for adding metadata (e.g. authorization) 4. variables: if the query has any Map<String,Object> result = new GraphQL(schema) (1) .execute(query, (2) null, (3) "") (4) .getData() as Map<String,Object> 6 . 15
  42. 42. #greachConf @marioggar © Mario Garcia 2017 TOO MUCH JAVA CODE…​ 6 . 16
  43. 43. #greachConf @marioggar © Mario Garcia 2017 6 . 17
  44. 44. #greachConf @marioggar © Mario Garcia 2017 GRAPHQL DSL (GQL) DSL over GraphQL-Java Still alpha Feeback is very welcome :) https://github.com/grooviter/gql 6 . 18
  45. 45. #greachConf @marioggar © Mario Garcia 2017 GROOVY TIME: TYPES type Film { title: !String year: Int } DSL.type('Film') { field('title') { type nonNull(GraphQLString) } field('something', GraphQLBoolean) field('year') { description 'release date' type GraphQLString } } 6 . 19
  46. 46. #greachConf @marioggar © Mario Garcia 2017 GROOVY TIME: TYPES (II) vs GraphQLObjectType.newObject() .name("Film") .field(newFieldDefinition() .type(GraphQLString) .name("title")) .field(newFieldDefinition() .type(GraphQLInt) .name("year")) .build(); DSL.type('Film') { field('title') { type nonNull(GraphQLString) } field('something', GraphQLBoolean) field('year') { description 'release date' type GraphQLString } } 6 . 20
  47. 47. #greachConf @marioggar © Mario Garcia 2017 GROOVY TIME: QUERIES type Queries { lastFilm: Film filmByYear(year: Int): Film } schema { query: Queries } return DSL.schema { query('Queries') { field('lastFilm') { type Schema.FilmType fetcher Queries.&findLastFilm } field('byYear') { type Schema.FilmType fetcher Queries.&findByYear argument('year') { type GraphQLString } } } } 6 . 21
  48. 48. #greachConf @marioggar © Mario Garcia 2017 GROOVY TIME: QUERIES (II) vs GraphQLObjectType lastFilm = GraphQLObjectType.newObject() .name("Queries") .field(newFieldDefinition() .type(filmType) .name("lastFilm") .dataFetcher(Queries::findLastFilm)) .build(); return GraphQLSchema .newSchema() .query(lastFilm) .build(); return DSL.schema { query('Queries') { field('lastFilm') { type Schema.FilmType fetcher Queries.&findLastFilm } field('byYear') { type Schema.FilmType fetcher Queries.&findByYear argument('year') { type GraphQLString } } 6 . 22
  49. 49. #greachConf @marioggar © Mario Garcia 2017 GROOVY TIME: QUERY EXECUTION yields def result = DSL .execute(schema, queryString) .data as Map<String,Object> { lastFilm: { year: 2015, title: 'SPECTRE' } } 6 . 23
  50. 50. #greachConf @marioggar © Mario Garcia 2017 GROOVY TIME: QUERY EXECUTION (II) vs Map<String,Object> result = new GraphQL(schema) (1) .execute(query, (2) null, (3) "") (4) .getData() as Map<String,Object> def result = DSL .execute(schema, queryString) .data as Map<String,Object> 6 . 24
  51. 51. #greachConf @marioggar © Mario Garcia 2017 QUERIES WITH ARGUMENTS 6 . 25
  52. 52. #greachConf @marioggar © Mario Garcia 2017 WHO KNOWS THE TITLE OF 1962 ? query query execution queryString = ''' query FindBondFilmByYear($year: String){ byYear(year: $year) { year title } } ''' Map<String,Object> result = DSL .execute(schema, queryString, [year: year]) .data 6 . 26
  53. 53. #greachConf @marioggar © Mario Garcia 2017 DR. NO [byYear: [ title: 'DR. NO', year: "1962" ] ] 6 . 27
  54. 54. #greachConf @marioggar © Mario Garcia 2017 NOW…​ 6 . 28
  55. 55. #greachConf @marioggar © Mario Garcia 2017 WOULDN’T IT COOL IF I EXPOSE THIS TO THE WORLD ? 6 . 29
  56. 56. #greachConf @marioggar © Mario Garcia 2017 HTTP + GRAPHQL 7 . 1
  57. 57. #greachConf @marioggar © Mario Garcia 2017 RATPACK + GRAPHQL 7 . 2
  58. 58. #greachConf @marioggar © Mario Garcia 2017 TECHNOLOGIES USED Ratpack GraphQL-java GQL GraphiQL 7 . 3
  59. 59. #greachConf @marioggar © Mario Garcia 2017 FULL FILM TYPE And it fits in the slide!! static final GraphQLObjectType Film = DSL.type('Film') { field 'title' , nonNull(GraphQLString) field 'year' , GraphQLInt field 'directedBy' , GraphQLString field 'bond' , GraphQLString field 'themeSong' , list(ThemeSong) field 'bondGirls' , list(BondGirl) field 'villains' , list(Villain) field 'counterparts', list(CounterPart) field 'gadgets' , list(GraphQLString) field 'vehicles' , list(GraphQLString) } 7 . 4
  60. 60. #greachConf @marioggar © Mario Garcia 2017 QUERIES return DSL.schema { query('Queries') { field('lastFilm') { type Schema.Film fetcher Queries.&findLastFilm } field('byYear') { type Schema.Film fetcher Queries.&findByYear argument('year') { type GraphQLString } } field('byBondActorNameLike') { type list(Schema.Film) fetcher Queries.&byBondActorNameLike argument('name') { type GraphQLString } } } } 7 . 5
  61. 61. #greachConf @marioggar © Mario Garcia 2017 RATPACK HANDLER class GraphQLHandler implements Handler { @Inject GraphQLSchema schema @Override void handle(final Context ctx) { def payload = ctx.get(Map) // JSON request => Map Blocking.get { DSL.execute(schema, "${payload.query}", payload.variables as Map<String,Object>) }.then { ExecutionResult result -> def response = [data: result.errors ?: result.data] ctx.render json(response) } } } 7 . 6
  62. 62. #greachConf @marioggar © Mario Garcia 2017 URI MAPPING 1. GraphQL endpoint 2. GraphiQL web console handlers { prefix('graphql') { (1) all(createBindingHandler(Map)) post(GraphQLHandler) } files { (2) dir('static').indexFiles('index.html') } } 7 . 7
  63. 63. #greachConf @marioggar © Mario Garcia 2017 SHOWTIME! query UserHome($actor: String, $year: String) { latest: lastFilm { title year directedBy bond } whenIwasBorn: byYear(year: $year) { title } favouriteActorMovies: byBondActorNameLike(name: $actor) { title year bond } } 7 . 8
  64. 64. #greachConf @marioggar © Mario Garcia 2017 A WORD ON QUERIES & MUTATIONS Queries are supposed to be able to be batched Queries are supposed to be computed in parallel Mutations are supposed to run sequentially 7 . 9
  65. 65. #greachConf @marioggar © Mario Garcia 2017 GRAILS + RELAY 7 . 10
  66. 66. #greachConf @marioggar © Mario Garcia 2017 RELAY ? Good GraphQL practices implemented in a JS library https://facebook.github.io/relay/ 7 . 11
  67. 67. #greachConf @marioggar © Mario Garcia 2017 RELAY How to handle pagination How to handle ids HTTP recommended features …​ http://graphql.org/learn/best-practices/ 7 . 12
  68. 68. #greachConf @marioggar © Mario Garcia 2017 GORM GRAPHQL Plugin Grails 3 https://github.com/mrcirillo/relay-gorm-connector 7 . 13
  69. 69. #greachConf @marioggar © Mario Garcia 2017 GRAPHQL SCHEMA @RelayType(description='An optional description of a film') class Film { @RelayField(description='An optional description of name') String title String year String bond } 7 . 14
  70. 70. #greachConf @marioggar © Mario Garcia 2017 GRAILS URLMAPPINGS post "/graphql"(controller: "graph") 7 . 15
  71. 71. #greachConf @marioggar © Mario Garcia 2017 GRAILS CONTROLLER class GraphController { def relayService // provided by plugin def index() { def query = request.JSON.query.toString() def vars = request.JSON.variables def result = relayService.query(query, null, vars?:[:]) render(result as JSON) } } 7 . 16
  72. 72. #greachConf @marioggar © Mario Garcia 2017 GRAPHQL BEST PRACTICES HINT: ID HASHING Instead of passing 1 use a hash like hagghsXy== def idString = RelayHelpers.toGlobalId("Film", film.id.toString()) def query = """ query { node(id: "$idString") { ... on Film { title } } } """ 7 . 17
  73. 73. #greachConf @marioggar © Mario Garcia 2017 CONCLUSIONS Is not GraphQL instead of REST Is about GraphQL over your existent services A great improvement from the business point of view Your front end workmates will love you 8 . 1
  74. 74. #greachConf @marioggar © Mario Garcia 2017 THANK YOU! 8 . 2
  75. 75. #greachConf @marioggar © Mario Garcia 2017 QUESTIONS & ANSWERS 9

×