SlideShare a Scribd company logo
1 of 39
Download to read offline
Not your fathers
Java
GraphQL Server with Kotlin and
GraphQL-Java
Michael Hunger
Developer Relations Engineer
github.com/neo4j-contrib/*
twitter & github & medium/@mesirii
GrandStack.io
A GraphQL-Server on the JVM in 33 Lines
val Int.odd : Boolean get() = this % 2 == 1
inline fun <R,reified T> Map<*,*>.aggregate(acc: R, operation: (R,T)->R) =
values.filterIsInstance<T>().fold(acc, operation)
data class Word(val text:String, val len:Int = text.length)
fun main(args: Array<String>) {
val message = """Hello ${args.firstOrNull() ?: "GraphQL Europe"}
|in ${args.getOrNull(1) ?:"Berlin"} <3""".trimMargin()
println(message)
// Hello GraphQL Europe in Berlin <3
val words = message.split("s+".toRegex())
.withIndex()
.associate { (i,w) -> i to if (i.odd) w else Word(w)}
.toSortedMap()
println(words)
// {0=Word(text=Hello, len=5), 1=GraphQL, 2=Word(text=Europe, len=6), 3=in, 4=Word(text=Berlin, len=6)
println(words.aggregate(1) {a,w:Word -> a*w.len})
// 180
}
Andy Marek's
GraphQL-Java 9.0
easy to use
spec compatible
async APIs
github.com/graphql-java/awesome-graphql-java
Minimal Example
type Query {
hello(what:String):String
}
query($p:String) {
hello(what: $p)
}
{"p" : "Berlin"}
GraphQL-Java
public class HelloWorld {
public static void main(String[] args) {
String schema = "type Query { " +
" hello(what:String = "World"): String " +
" }";
SchemaParser schemaParser = new SchemaParser();
TypeDefinitionRegistry typeDefinitionRegistry = schemaParser.parse(schema);
RuntimeWiring runtimeWiring = newRuntimeWiring()
.type("Query",
builder -> builder.dataFetcher("hello",
env -> "Hello "+env.getArgument("what")+"!"))
.build();
SchemaGenerator schemaGenerator = new SchemaGenerator();
GraphQLSchema graphQLSchema = schemaGenerator.makeExecutableSchema(typeDefinitionRegistry, runtimeWiring);
GraphQL build = GraphQL.newGraphQL(graphQLSchema).build();
ExecutionResult executionResult = build.execute("{hello(what:"Java")}");
System.out.println(executionResult.<Map<String,Object>>getData());
// Prints: {hello=Hello Java!}
}} http://graphql-java.readthedocs.io/en/latest/getting_started.html
GraphQL-Kotlin
fun main(args: Array<String>) {
val schema = """type Query {
hello(what:String = "World"): String
}"""
val schemaParser = SchemaParser()
val typeDefinitionRegistry = schemaParser.parse(schema)
val runtimeWiring = newRuntimeWiring()
.type("Query")
{ it.dataFetcher("hello") { env -> "Hello ${env.getArgument<Any>("what")}!" } }
.build()
val schemaGenerator = SchemaGenerator()
val graphQLSchema = schemaGenerator.makeExecutableSchema(typeDefinitionRegistry, runtimeWiring)
val build = GraphQL.newGraphQL(graphQLSchema).build()
val executionResult = build.execute("""{ hello (what:"Kotlin") } """)
println(executionResult.getData<Any>())
// Prints: {hello=Hello Kotlin!}
}
GraphQL-Kotlin
fun main(args: Array<String>) {
val schema = """type Query {
hello(what:String = "World"): String
}"""
val runtimeWiring = newRuntimeWiring()
.type("Query")
{ it.dataFetcher("hello") { env -> "Hello ${env.getArgument<Any>("what")}!" } }
.build()
val graphQLSchema = SchemaGenerator().makeExecutableSchema(SchemaParser().parse(schema), runtimeWiring)
val build = GraphQL.newGraphQL(graphQLSchema).build()
val executionResult = build.execute("""{ hello (what:"Kotlin") } """)
println(executionResult.getData<Any>())
// Prints: {hello=Hello Kotlin!}
}
GraphQL- Handler - Schema
class GraphQLHandler(private val schema:GraphQLSchema) {
constructor(schema:String, resolvers: Map<String, List<Pair<String, DataFetcher<*>>>>) :
this(schema(schema,resolvers))
companion object {
fun schema(schema: String, resolvers: Map<String,List<Pair<String, DataFetcher<*>>>>): GraphQLSchema {
val typeDefinitionRegistry = SchemaParser().parse(schema)
val runtimeWiring = newRuntimeWiring()
.apply { resolvers.forEach { (type, fields) -> this.type(type)
{ builder -> fields.forEach { (field, resolver) -> builder.dataFetcher(field, resolver) };builder } } }
.build()
return SchemaGenerator().makeExecutableSchema(typeDefinitionRegistry, runtimeWiring)
}
}
class GraphQLHandler(private val schema:GraphQLSchema) {
suspend fun execute(query: String, params: Map<String, Any>, op:String?, ctx : Any?): ExecutionResult {
val graphql = GraphQL.newGraphQL(schema).build()
val executionResult = graphql.executeAsync{
builder -> builder.query(query).variables(params).operationName(op).context(ctx) }
return executionResult.await()
}
}
GraphQL-Kotlin - Execute
async via co-routines
fun main(args: Array<String>) {
runBlocking {
val schema = """type Query {
answer: Int
hello(what:String="World"): String
}"""
val resolvers = mapOf("Query" to
listOf("hello" to DataFetcher { env -> "Hello"+env.getArgument("what") },
"answer" to StaticDataFetcher(42)))
with(GraphQLHandler(schema, resolvers)) {
val result = execute(args.first(), args.drop(1).zipWithNext().toMap())
println(result.getData() as Any)
}
}
}
GraphQL-Kotlin - Run
Run main: "query($p:String) { hello(what:$p) }" p GraphQL
Output: {hello=Hello GraphQL}
Let's build a server
ktor.io
lightweight, concise Server & Client
async via coroutines
HTTP/2, WS, JWT, HTML DSL, ...
Kotlin Web Server
val server = embeddedServer(Netty, port = 8080) {
install(ContentNegotiation) { jackson { } }
routing {
get("/") {
call.respondText("Hello World!n", ContentType.Text.Plain)
}
get("/json") {
call.respond(mapOf("OK" to true))
}
post("/post/{name}") {
val body = call.receive<Text>()
call.respond(Text(body.text+" from "+call.parameters["name"]))
}
get("/html") {
call.respondHtml {
head { title { +"Title"} }
body { p { +"Body" }}
}
}
}
}
server.start(wait = true)
localhost:8080/
Hello World!
localhost:8080/json
{"OK":true}
localhost:8080/post/Joe -d'{"text":"Hi"}'
-H content-type:application/json
{"text":"Hi from Joe"}
localhost:8080/html
<html>
<head>
<title>Title</title>
</head>
<body>
<p>Body</p>
</body>
</html>
GraphQL Http Server
fun main(args: Array<String>) {
val schema = """type Query {
answer: Int
hello(what:String="World"): String
}"""
val fetchers = mapOf("Query" to
listOf("hello" to DataFetcher { env -> "Hello "+env.getArgument("what") },
"answer" to StaticDataFetcher(42)))
val handler = GraphQLHandler(schema, fetchers)
data class Request(val query:String, val params:Map<String,Any>, val operationName : String?)
val server = embeddedServer(Netty, port = 8080) {
install(ContentNegotiation) { jackson { } }
routing {
post("/graphql") {
val request = call.receive<Request>()
val result = handler.execute(request.query, request.params)
call.respond(mapOf("data" to result.getData<Any>()))
}
}
}
server.start(wait = true)
}
GraphQL Server
data class Request(val query:String, val variables:Any?, val operationName : String?) {
// for GraphiQL
val params get() =
when (variables) {
is String -> MAPPER.readValue(variables, Map::class.java)
is Map<*, *> -> variables
else -> emptyMap<String, Any>()
} as Map<String, Any>
}
GraphQL Server (Response)
curl localhost:8080/graphql
-H content-type:application/json
-d'{"query":"{answer}"}'
{"data":{"answer":42}}
What Else?
Kotlin JavaScript
Kotlin JavaScript
● Cross compile to JavaScript
● Include kotlin.js std library (npm install kotlin)
● Use existing JS libraries with TypeScript headers (ts2kt) or
● turn them into dynamic objects with asDynamic()
● Reuse common (business) code in multi-platform projects
● Node and Web support, incl. DOM
JavaScript
var express = require('express');
var graphqlHTTP = require('express-graphql');
var { buildSchema } = require('graphql');
var schema = buildSchema(`
type Query {
hello: String
}
`);
var root = { hello: () => { return 'Hello world!'; },};
var app = express();
app.use('/graphql', graphqlHTTP({schema: schema, rootValue: root, graphiql: true}));
app.listen(4000);
console.log('Running a GraphQL API server at localhost:4000/graphql');
graphql.org/graphql-js/running-an-express-graphql-server/
Kotlin JavaScript
external fun require(module:String):dynamic
val express = require("express")
val graphqlHTTP = require("express-graphql");
val buildSchema = require("graphql").buildSchema;
val schema = buildSchema("""
type Query {
hello(what:String="World"): String
}
""")
fun main(args: Array<String>) {
val root = asObject("hello" to {ctx:dynamic -> "Hello ${ctx["what"]}"})
val options = asObject("schema" to schema, "rootValue" to root, "graphiql" to true)
val app = express()
app.use("/graphql-js", graphqlHTTP(options))
app.listen(3000, {
println("Server started")
})
}
kotlinlang.org/docs/tutorials/javascript/
Kotlin JavaScript
Kotlin Native
Kotlin Native
● using LLVM, cross-compile to LLVM-IR
● iOS, Android, Windows, OSX, Unix, WebAssembly
● Use native libs
● Interop with Swift, C / C++, ...
● generate native libs and executables
● use typesafe, clean Kotlin code
Kotlin Native
● use microHttpd (MHD) as webserver
● use github.com/graphql/libgraphqlparser
for schema & query parsing
● resolvers as callback functions
● use any db connection or libcurl for API calls for
resolvers
● KGraphQL - Pure Kotlin GraphQL implementation
● kraph: GraphQL request string builder in Kotlin
● Ktor + Koin + KGraphQL + Squash
● Android/Apollo + GraphKool + GraphQL Java Server
● Writing a GraphQL Server in Kotlin
Other Notables
● Micronaut.io Framework (Java, Groovy, Kotlin)
○ GraphQL Demo
● GraphQL Server via GORM
● GraphQL with Kotlin + Spring Boot
Other Notables
GrandStack
Hackathon - June 30
Questions? Hang out at our booth
@mesirii
Links
● github.com/jexp/kotlin-graphql
● github.com/graphql-java
● ktor.io
● kotlin-lang.org
● kotlinbyexample.org
● grandstack.io

More Related Content

More from jexp

Neo4j Graph Streaming Services with Apache Kafka
Neo4j Graph Streaming Services with Apache KafkaNeo4j Graph Streaming Services with Apache Kafka
Neo4j Graph Streaming Services with Apache Kafkajexp
 
How Graph Databases efficiently store, manage and query connected data at s...
How Graph Databases efficiently  store, manage and query  connected data at s...How Graph Databases efficiently  store, manage and query  connected data at s...
How Graph Databases efficiently store, manage and query connected data at s...jexp
 
APOC Pearls - Whirlwind Tour Through the Neo4j APOC Procedures Library
APOC Pearls - Whirlwind Tour Through the Neo4j APOC Procedures LibraryAPOC Pearls - Whirlwind Tour Through the Neo4j APOC Procedures Library
APOC Pearls - Whirlwind Tour Through the Neo4j APOC Procedures Libraryjexp
 
Refactoring, 2nd Edition
Refactoring, 2nd EditionRefactoring, 2nd Edition
Refactoring, 2nd Editionjexp
 
New Features in Neo4j 3.4 / 3.3 - Graph Algorithms, Spatial, Date-Time & Visu...
New Features in Neo4j 3.4 / 3.3 - Graph Algorithms, Spatial, Date-Time & Visu...New Features in Neo4j 3.4 / 3.3 - Graph Algorithms, Spatial, Date-Time & Visu...
New Features in Neo4j 3.4 / 3.3 - Graph Algorithms, Spatial, Date-Time & Visu...jexp
 
GraphQL - The new "Lingua Franca" for API-Development
GraphQL - The new "Lingua Franca" for API-DevelopmentGraphQL - The new "Lingua Franca" for API-Development
GraphQL - The new "Lingua Franca" for API-Developmentjexp
 
A whirlwind tour of graph databases
A whirlwind tour of graph databasesA whirlwind tour of graph databases
A whirlwind tour of graph databasesjexp
 
Practical Graph Algorithms with Neo4j
Practical Graph Algorithms with Neo4jPractical Graph Algorithms with Neo4j
Practical Graph Algorithms with Neo4jjexp
 
A Game of Data and GraphQL
A Game of Data and GraphQLA Game of Data and GraphQL
A Game of Data and GraphQLjexp
 
Querying Graphs with GraphQL
Querying Graphs with GraphQLQuerying Graphs with GraphQL
Querying Graphs with GraphQLjexp
 
Graphs & Neo4j - Past Present Future
Graphs & Neo4j - Past Present FutureGraphs & Neo4j - Past Present Future
Graphs & Neo4j - Past Present Futurejexp
 
Intro to Graphs and Neo4j
Intro to Graphs and Neo4jIntro to Graphs and Neo4j
Intro to Graphs and Neo4jjexp
 
Class graph neo4j and software metrics
Class graph neo4j and software metricsClass graph neo4j and software metrics
Class graph neo4j and software metricsjexp
 
New Neo4j Auto HA Cluster
New Neo4j Auto HA ClusterNew Neo4j Auto HA Cluster
New Neo4j Auto HA Clusterjexp
 
Spring Data Neo4j Intro SpringOne 2012
Spring Data Neo4j Intro SpringOne 2012Spring Data Neo4j Intro SpringOne 2012
Spring Data Neo4j Intro SpringOne 2012jexp
 
Intro to Cypher
Intro to CypherIntro to Cypher
Intro to Cypherjexp
 
Geekout publish
Geekout publishGeekout publish
Geekout publishjexp
 
Intro to Neo4j presentation
Intro to Neo4j presentationIntro to Neo4j presentation
Intro to Neo4j presentationjexp
 
Neo4j & (J) Ruby Presentation JRubyConf.EU
Neo4j & (J) Ruby Presentation JRubyConf.EUNeo4j & (J) Ruby Presentation JRubyConf.EU
Neo4j & (J) Ruby Presentation JRubyConf.EUjexp
 
Intro to Spring Data Neo4j
Intro to Spring Data Neo4jIntro to Spring Data Neo4j
Intro to Spring Data Neo4jjexp
 

More from jexp (20)

Neo4j Graph Streaming Services with Apache Kafka
Neo4j Graph Streaming Services with Apache KafkaNeo4j Graph Streaming Services with Apache Kafka
Neo4j Graph Streaming Services with Apache Kafka
 
How Graph Databases efficiently store, manage and query connected data at s...
How Graph Databases efficiently  store, manage and query  connected data at s...How Graph Databases efficiently  store, manage and query  connected data at s...
How Graph Databases efficiently store, manage and query connected data at s...
 
APOC Pearls - Whirlwind Tour Through the Neo4j APOC Procedures Library
APOC Pearls - Whirlwind Tour Through the Neo4j APOC Procedures LibraryAPOC Pearls - Whirlwind Tour Through the Neo4j APOC Procedures Library
APOC Pearls - Whirlwind Tour Through the Neo4j APOC Procedures Library
 
Refactoring, 2nd Edition
Refactoring, 2nd EditionRefactoring, 2nd Edition
Refactoring, 2nd Edition
 
New Features in Neo4j 3.4 / 3.3 - Graph Algorithms, Spatial, Date-Time & Visu...
New Features in Neo4j 3.4 / 3.3 - Graph Algorithms, Spatial, Date-Time & Visu...New Features in Neo4j 3.4 / 3.3 - Graph Algorithms, Spatial, Date-Time & Visu...
New Features in Neo4j 3.4 / 3.3 - Graph Algorithms, Spatial, Date-Time & Visu...
 
GraphQL - The new "Lingua Franca" for API-Development
GraphQL - The new "Lingua Franca" for API-DevelopmentGraphQL - The new "Lingua Franca" for API-Development
GraphQL - The new "Lingua Franca" for API-Development
 
A whirlwind tour of graph databases
A whirlwind tour of graph databasesA whirlwind tour of graph databases
A whirlwind tour of graph databases
 
Practical Graph Algorithms with Neo4j
Practical Graph Algorithms with Neo4jPractical Graph Algorithms with Neo4j
Practical Graph Algorithms with Neo4j
 
A Game of Data and GraphQL
A Game of Data and GraphQLA Game of Data and GraphQL
A Game of Data and GraphQL
 
Querying Graphs with GraphQL
Querying Graphs with GraphQLQuerying Graphs with GraphQL
Querying Graphs with GraphQL
 
Graphs & Neo4j - Past Present Future
Graphs & Neo4j - Past Present FutureGraphs & Neo4j - Past Present Future
Graphs & Neo4j - Past Present Future
 
Intro to Graphs and Neo4j
Intro to Graphs and Neo4jIntro to Graphs and Neo4j
Intro to Graphs and Neo4j
 
Class graph neo4j and software metrics
Class graph neo4j and software metricsClass graph neo4j and software metrics
Class graph neo4j and software metrics
 
New Neo4j Auto HA Cluster
New Neo4j Auto HA ClusterNew Neo4j Auto HA Cluster
New Neo4j Auto HA Cluster
 
Spring Data Neo4j Intro SpringOne 2012
Spring Data Neo4j Intro SpringOne 2012Spring Data Neo4j Intro SpringOne 2012
Spring Data Neo4j Intro SpringOne 2012
 
Intro to Cypher
Intro to CypherIntro to Cypher
Intro to Cypher
 
Geekout publish
Geekout publishGeekout publish
Geekout publish
 
Intro to Neo4j presentation
Intro to Neo4j presentationIntro to Neo4j presentation
Intro to Neo4j presentation
 
Neo4j & (J) Ruby Presentation JRubyConf.EU
Neo4j & (J) Ruby Presentation JRubyConf.EUNeo4j & (J) Ruby Presentation JRubyConf.EU
Neo4j & (J) Ruby Presentation JRubyConf.EU
 
Intro to Spring Data Neo4j
Intro to Spring Data Neo4jIntro to Spring Data Neo4j
Intro to Spring Data Neo4j
 

Recently uploaded

WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park masabamasaba
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Bert Jan Schrijver
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastPapp Krisztián
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2
 
tonesoftg
tonesoftgtonesoftg
tonesoftglanshi9
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfonteinmasabamasaba
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrandmasabamasaba
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...Jittipong Loespradit
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024VictoriaMetrics
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationJuha-Pekka Tolvanen
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...masabamasaba
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxAnnaArtyushina1
 

Recently uploaded (20)

WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaS
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - Keynote
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 

LT: Building GraphQL Servers with Kotlin

  • 1. Not your fathers Java GraphQL Server with Kotlin and GraphQL-Java
  • 2. Michael Hunger Developer Relations Engineer github.com/neo4j-contrib/* twitter & github & medium/@mesirii
  • 4.
  • 5. A GraphQL-Server on the JVM in 33 Lines
  • 6.
  • 7. val Int.odd : Boolean get() = this % 2 == 1 inline fun <R,reified T> Map<*,*>.aggregate(acc: R, operation: (R,T)->R) = values.filterIsInstance<T>().fold(acc, operation) data class Word(val text:String, val len:Int = text.length) fun main(args: Array<String>) { val message = """Hello ${args.firstOrNull() ?: "GraphQL Europe"} |in ${args.getOrNull(1) ?:"Berlin"} <3""".trimMargin() println(message) // Hello GraphQL Europe in Berlin <3 val words = message.split("s+".toRegex()) .withIndex() .associate { (i,w) -> i to if (i.odd) w else Word(w)} .toSortedMap() println(words) // {0=Word(text=Hello, len=5), 1=GraphQL, 2=Word(text=Europe, len=6), 3=in, 4=Word(text=Berlin, len=6) println(words.aggregate(1) {a,w:Word -> a*w.len}) // 180 }
  • 8.
  • 9.
  • 10.
  • 11. Andy Marek's GraphQL-Java 9.0 easy to use spec compatible async APIs github.com/graphql-java/awesome-graphql-java
  • 12. Minimal Example type Query { hello(what:String):String } query($p:String) { hello(what: $p) } {"p" : "Berlin"}
  • 13. GraphQL-Java public class HelloWorld { public static void main(String[] args) { String schema = "type Query { " + " hello(what:String = "World"): String " + " }"; SchemaParser schemaParser = new SchemaParser(); TypeDefinitionRegistry typeDefinitionRegistry = schemaParser.parse(schema); RuntimeWiring runtimeWiring = newRuntimeWiring() .type("Query", builder -> builder.dataFetcher("hello", env -> "Hello "+env.getArgument("what")+"!")) .build(); SchemaGenerator schemaGenerator = new SchemaGenerator(); GraphQLSchema graphQLSchema = schemaGenerator.makeExecutableSchema(typeDefinitionRegistry, runtimeWiring); GraphQL build = GraphQL.newGraphQL(graphQLSchema).build(); ExecutionResult executionResult = build.execute("{hello(what:"Java")}"); System.out.println(executionResult.<Map<String,Object>>getData()); // Prints: {hello=Hello Java!} }} http://graphql-java.readthedocs.io/en/latest/getting_started.html
  • 14. GraphQL-Kotlin fun main(args: Array<String>) { val schema = """type Query { hello(what:String = "World"): String }""" val schemaParser = SchemaParser() val typeDefinitionRegistry = schemaParser.parse(schema) val runtimeWiring = newRuntimeWiring() .type("Query") { it.dataFetcher("hello") { env -> "Hello ${env.getArgument<Any>("what")}!" } } .build() val schemaGenerator = SchemaGenerator() val graphQLSchema = schemaGenerator.makeExecutableSchema(typeDefinitionRegistry, runtimeWiring) val build = GraphQL.newGraphQL(graphQLSchema).build() val executionResult = build.execute("""{ hello (what:"Kotlin") } """) println(executionResult.getData<Any>()) // Prints: {hello=Hello Kotlin!} }
  • 15. GraphQL-Kotlin fun main(args: Array<String>) { val schema = """type Query { hello(what:String = "World"): String }""" val runtimeWiring = newRuntimeWiring() .type("Query") { it.dataFetcher("hello") { env -> "Hello ${env.getArgument<Any>("what")}!" } } .build() val graphQLSchema = SchemaGenerator().makeExecutableSchema(SchemaParser().parse(schema), runtimeWiring) val build = GraphQL.newGraphQL(graphQLSchema).build() val executionResult = build.execute("""{ hello (what:"Kotlin") } """) println(executionResult.getData<Any>()) // Prints: {hello=Hello Kotlin!} }
  • 16. GraphQL- Handler - Schema class GraphQLHandler(private val schema:GraphQLSchema) { constructor(schema:String, resolvers: Map<String, List<Pair<String, DataFetcher<*>>>>) : this(schema(schema,resolvers)) companion object { fun schema(schema: String, resolvers: Map<String,List<Pair<String, DataFetcher<*>>>>): GraphQLSchema { val typeDefinitionRegistry = SchemaParser().parse(schema) val runtimeWiring = newRuntimeWiring() .apply { resolvers.forEach { (type, fields) -> this.type(type) { builder -> fields.forEach { (field, resolver) -> builder.dataFetcher(field, resolver) };builder } } } .build() return SchemaGenerator().makeExecutableSchema(typeDefinitionRegistry, runtimeWiring) } }
  • 17. class GraphQLHandler(private val schema:GraphQLSchema) { suspend fun execute(query: String, params: Map<String, Any>, op:String?, ctx : Any?): ExecutionResult { val graphql = GraphQL.newGraphQL(schema).build() val executionResult = graphql.executeAsync{ builder -> builder.query(query).variables(params).operationName(op).context(ctx) } return executionResult.await() } } GraphQL-Kotlin - Execute async via co-routines
  • 18. fun main(args: Array<String>) { runBlocking { val schema = """type Query { answer: Int hello(what:String="World"): String }""" val resolvers = mapOf("Query" to listOf("hello" to DataFetcher { env -> "Hello"+env.getArgument("what") }, "answer" to StaticDataFetcher(42))) with(GraphQLHandler(schema, resolvers)) { val result = execute(args.first(), args.drop(1).zipWithNext().toMap()) println(result.getData() as Any) } } } GraphQL-Kotlin - Run Run main: "query($p:String) { hello(what:$p) }" p GraphQL Output: {hello=Hello GraphQL}
  • 19. Let's build a server
  • 20. ktor.io lightweight, concise Server & Client async via coroutines HTTP/2, WS, JWT, HTML DSL, ...
  • 21. Kotlin Web Server val server = embeddedServer(Netty, port = 8080) { install(ContentNegotiation) { jackson { } } routing { get("/") { call.respondText("Hello World!n", ContentType.Text.Plain) } get("/json") { call.respond(mapOf("OK" to true)) } post("/post/{name}") { val body = call.receive<Text>() call.respond(Text(body.text+" from "+call.parameters["name"])) } get("/html") { call.respondHtml { head { title { +"Title"} } body { p { +"Body" }} } } } } server.start(wait = true) localhost:8080/ Hello World! localhost:8080/json {"OK":true} localhost:8080/post/Joe -d'{"text":"Hi"}' -H content-type:application/json {"text":"Hi from Joe"} localhost:8080/html <html> <head> <title>Title</title> </head> <body> <p>Body</p> </body> </html>
  • 22. GraphQL Http Server fun main(args: Array<String>) { val schema = """type Query { answer: Int hello(what:String="World"): String }""" val fetchers = mapOf("Query" to listOf("hello" to DataFetcher { env -> "Hello "+env.getArgument("what") }, "answer" to StaticDataFetcher(42))) val handler = GraphQLHandler(schema, fetchers) data class Request(val query:String, val params:Map<String,Any>, val operationName : String?) val server = embeddedServer(Netty, port = 8080) { install(ContentNegotiation) { jackson { } } routing { post("/graphql") { val request = call.receive<Request>() val result = handler.execute(request.query, request.params) call.respond(mapOf("data" to result.getData<Any>())) } } } server.start(wait = true) }
  • 23. GraphQL Server data class Request(val query:String, val variables:Any?, val operationName : String?) { // for GraphiQL val params get() = when (variables) { is String -> MAPPER.readValue(variables, Map::class.java) is Map<*, *> -> variables else -> emptyMap<String, Any>() } as Map<String, Any> }
  • 24. GraphQL Server (Response) curl localhost:8080/graphql -H content-type:application/json -d'{"query":"{answer}"}' {"data":{"answer":42}}
  • 25.
  • 28. Kotlin JavaScript ● Cross compile to JavaScript ● Include kotlin.js std library (npm install kotlin) ● Use existing JS libraries with TypeScript headers (ts2kt) or ● turn them into dynamic objects with asDynamic() ● Reuse common (business) code in multi-platform projects ● Node and Web support, incl. DOM
  • 29. JavaScript var express = require('express'); var graphqlHTTP = require('express-graphql'); var { buildSchema } = require('graphql'); var schema = buildSchema(` type Query { hello: String } `); var root = { hello: () => { return 'Hello world!'; },}; var app = express(); app.use('/graphql', graphqlHTTP({schema: schema, rootValue: root, graphiql: true})); app.listen(4000); console.log('Running a GraphQL API server at localhost:4000/graphql'); graphql.org/graphql-js/running-an-express-graphql-server/
  • 30. Kotlin JavaScript external fun require(module:String):dynamic val express = require("express") val graphqlHTTP = require("express-graphql"); val buildSchema = require("graphql").buildSchema; val schema = buildSchema(""" type Query { hello(what:String="World"): String } """) fun main(args: Array<String>) { val root = asObject("hello" to {ctx:dynamic -> "Hello ${ctx["what"]}"}) val options = asObject("schema" to schema, "rootValue" to root, "graphiql" to true) val app = express() app.use("/graphql-js", graphqlHTTP(options)) app.listen(3000, { println("Server started") }) } kotlinlang.org/docs/tutorials/javascript/
  • 33. Kotlin Native ● using LLVM, cross-compile to LLVM-IR ● iOS, Android, Windows, OSX, Unix, WebAssembly ● Use native libs ● Interop with Swift, C / C++, ... ● generate native libs and executables ● use typesafe, clean Kotlin code
  • 34. Kotlin Native ● use microHttpd (MHD) as webserver ● use github.com/graphql/libgraphqlparser for schema & query parsing ● resolvers as callback functions ● use any db connection or libcurl for API calls for resolvers
  • 35. ● KGraphQL - Pure Kotlin GraphQL implementation ● kraph: GraphQL request string builder in Kotlin ● Ktor + Koin + KGraphQL + Squash ● Android/Apollo + GraphKool + GraphQL Java Server ● Writing a GraphQL Server in Kotlin Other Notables
  • 36. ● Micronaut.io Framework (Java, Groovy, Kotlin) ○ GraphQL Demo ● GraphQL Server via GORM ● GraphQL with Kotlin + Spring Boot Other Notables
  • 38. Questions? Hang out at our booth @mesirii
  • 39. Links ● github.com/jexp/kotlin-graphql ● github.com/graphql-java ● ktor.io ● kotlin-lang.org ● kotlinbyexample.org ● grandstack.io