SlideShare une entreprise Scribd logo
1  sur  75
Télécharger pour lire hors ligne
#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
#greachConf @marioggar ©	Mario	Garcia	2017
ABOUT	ME
Name
Mario	Garcia
You	can	find	me:
https://twitter.com/marioggar
https://github.com/mariogarcia
2 . 1
#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	do	one	more	REST	app	I’ll	kill	myself
I	didn’t	find	any	other	interesting	talk
Whatever	it	is…​
3 . 1
#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
4 . 2
#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	a	type	system	to	define	those	queries
5 . 2
#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
#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	language
5 . 6
#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
#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	use	web	browsers...FOR	NOW
BUT	we	have	to	be	ready	for	mobile	AT	SOME	POINT
5 . 9
#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
#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	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
#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	two	weeks
BUT	means	winter	is	coming!
and	of	course…​AT	SOME	POINT	means	probably	next
week
5 . 14
#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	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
#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	schema
6 . 2
#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	{
			lastFilm:	Film
			filmByYear(year:	Int):	Film
}
schema	{
	query:	Queries
}
http://facebook.github.io/graphql/
6 . 4
#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
#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
#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
#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
#greachConf @marioggar ©	Mario	Garcia	2017
VALIDATION
title	is	mandatory
invalid	query
type	Film	{
		title:	!String
		year:	Int
}
{
		lastFilm
}
6 . 9
#greachConf @marioggar ©	Mario	Garcia	2017
6 . 10
#greachConf @marioggar ©	Mario	Garcia	2017
JVM	LIBRARIES	OUT	THERE!
GraphQL-Java
https://github.com/graphql-java/graphql-java
6 . 11
#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
#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
#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
#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
#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	:)
https://github.com/grooviter/gql
6 . 18
#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
#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
#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
#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
#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
#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
#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	FindBondFilmByYear($year:	String){
				byYear(year:	$year)	{
						year
						title
				}
		}
'''
Map<String,Object>	result	=	DSL
		.execute(schema,	queryString,	[year:	year])
		.data
6 . 26
#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	=
		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
#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
#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
#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
#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
#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
#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.github.io/relay/
7 . 11
#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
#greachConf @marioggar ©	Mario	Garcia	2017
GORM	GRAPHQL
Plugin	Grails	3
https://github.com/mrcirillo/relay-gorm-connector
7 . 13
#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
#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	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
#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
#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
#greachConf @marioggar ©	Mario	Garcia	2017
THANK	YOU!
8 . 2
#greachConf @marioggar ©	Mario	Garcia	2017
QUESTIONS	&	ANSWERS
9

Contenu connexe

Tendances

Workshop de FacilitAção (Duração 8h)
Workshop de FacilitAção (Duração 8h)Workshop de FacilitAção (Duração 8h)
Workshop de FacilitAção (Duração 8h)
Mayra de Souza
 
Mr presentatie voor_de_oudervereniging
Mr presentatie voor_de_ouderverenigingMr presentatie voor_de_oudervereniging
Mr presentatie voor_de_oudervereniging
LiselotteMertens
 
ウォーターフォールとアジャイル開発の比較 
ウォーターフォールとアジャイル開発の比較 ウォーターフォールとアジャイル開発の比較 
ウォーターフォールとアジャイル開発の比較 
Unicast Inc.
 
Agile Development Overview
Agile Development OverviewAgile Development Overview
Agile Development Overview
guestb4c770
 

Tendances (20)

10 differences between SAFe and LeSS
10 differences between SAFe and LeSS10 differences between SAFe and LeSS
10 differences between SAFe and LeSS
 
Guia do Papel e Responsabilidade do Scrum Master
Guia do Papel e Responsabilidade do Scrum MasterGuia do Papel e Responsabilidade do Scrum Master
Guia do Papel e Responsabilidade do Scrum Master
 
Workshop de FacilitAção (Duração 8h)
Workshop de FacilitAção (Duração 8h)Workshop de FacilitAção (Duração 8h)
Workshop de FacilitAção (Duração 8h)
 
Lean Inception custo ou desperdício? Como engajar participantes?
Lean Inception custo ou desperdício? Como engajar participantes?Lean Inception custo ou desperdício? Como engajar participantes?
Lean Inception custo ou desperdício? Como engajar participantes?
 
Management 3.0 デレゲーションと エンパワーメント
Management 3.0 デレゲーションと エンパワーメントManagement 3.0 デレゲーションと エンパワーメント
Management 3.0 デレゲーションと エンパワーメント
 
Value Driven Over Plan Driven
Value Driven Over Plan DrivenValue Driven Over Plan Driven
Value Driven Over Plan Driven
 
UnityでのLINQ活用例
UnityでのLINQ活用例UnityでのLINQ活用例
UnityでのLINQ活用例
 
Das Perfekte Team - und die Praxis
Das Perfekte Team - und die PraxisDas Perfekte Team - und die Praxis
Das Perfekte Team - und die Praxis
 
Lean Change Management - チーム・組織に変化を起こす!オリジナルのチェンジ・フレームワークを構築する方法
Lean Change Management - チーム・組織に変化を起こす!オリジナルのチェンジ・フレームワークを構築する方法Lean Change Management - チーム・組織に変化を起こす!オリジナルのチェンジ・フレームワークを構築する方法
Lean Change Management - チーム・組織に変化を起こす!オリジナルのチェンジ・フレームワークを構築する方法
 
Agilität kurz & bündig
Agilität kurz & bündigAgilität kurz & bündig
Agilität kurz & bündig
 
Mr presentatie voor_de_oudervereniging
Mr presentatie voor_de_ouderverenigingMr presentatie voor_de_oudervereniging
Mr presentatie voor_de_oudervereniging
 
Scrum methodology
Scrum methodologyScrum methodology
Scrum methodology
 
ウォーターフォールとアジャイル開発の比較 
ウォーターフォールとアジャイル開発の比較 ウォーターフォールとアジャイル開発の比較 
ウォーターフォールとアジャイル開発の比較 
 
Agile Development Overview
Agile Development OverviewAgile Development Overview
Agile Development Overview
 
Empowering Agile Teams
Empowering Agile TeamsEmpowering Agile Teams
Empowering Agile Teams
 
Software Methodologies & Frameworks
Software Methodologies & FrameworksSoftware Methodologies & Frameworks
Software Methodologies & Frameworks
 
#T3SCRUM: 12 principles of agile
#T3SCRUM: 12 principles of agile#T3SCRUM: 12 principles of agile
#T3SCRUM: 12 principles of agile
 
Laravelで作成したアプリ紹介
Laravelで作成したアプリ紹介Laravelで作成したアプリ紹介
Laravelで作成したアプリ紹介
 
Agile & SCRUM basics
Agile & SCRUM basicsAgile & SCRUM basics
Agile & SCRUM basics
 
AzureDevOps ユーザーストーリーを作ってみよう - 201904
AzureDevOps ユーザーストーリーを作ってみよう - 201904AzureDevOps ユーザーストーリーを作ってみよう - 201904
AzureDevOps ユーザーストーリーを作ってみよう - 201904
 

Plus de Mario García

Plus de Mario García (16)

Blockchain 101 (spanish)
Blockchain 101 (spanish)Blockchain 101 (spanish)
Blockchain 101 (spanish)
 
Jbake workshop (Greach 2019)
Jbake workshop (Greach 2019)Jbake workshop (Greach 2019)
Jbake workshop (Greach 2019)
 
Groovy 2.5 and 3.0 (Spanish)
Groovy 2.5 and 3.0 (Spanish)Groovy 2.5 and 3.0 (Spanish)
Groovy 2.5 and 3.0 (Spanish)
 
GraphQL & Ratpack
GraphQL & RatpackGraphQL & Ratpack
GraphQL & Ratpack
 
GraphQL y Groovy
GraphQL y GroovyGraphQL y Groovy
GraphQL y Groovy
 
Calidad del codigo (MadridGUG)
Calidad del codigo (MadridGUG)Calidad del codigo (MadridGUG)
Calidad del codigo (MadridGUG)
 
Macro macro, burrito burrit
Macro macro, burrito burritMacro macro, burrito burrit
Macro macro, burrito burrit
 
Creating ASTTs The painful truth
Creating ASTTs The painful truthCreating ASTTs The painful truth
Creating ASTTs The painful truth
 
Groovy android
Groovy androidGroovy android
Groovy android
 
Groovy on Android
Groovy on AndroidGroovy on Android
Groovy on Android
 
Gpars Workshop 2014
Gpars Workshop 2014Gpars Workshop 2014
Gpars Workshop 2014
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
Test Motherfucker...Test
Test Motherfucker...TestTest Motherfucker...Test
Test Motherfucker...Test
 
Programación concurrente con GPars
Programación concurrente con GParsProgramación concurrente con GPars
Programación concurrente con GPars
 
Gradle vs Maven
Gradle vs MavenGradle vs Maven
Gradle vs Maven
 
Greach 2011 : Creando Plugins Con Griffon
Greach 2011 : Creando Plugins Con GriffonGreach 2011 : Creando Plugins Con Griffon
Greach 2011 : Creando Plugins Con Griffon
 

Dernier

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Dernier (20)

08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 

GraphQL and Groovy