SlideShare une entreprise Scribd logo
1  sur  39
Télécharger pour lire hors ligne
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

Contenu connexe

Plus de jexp

Graphs & Neo4j - Past Present Future
Graphs & Neo4j - Past Present FutureGraphs & Neo4j - Past Present Future
Graphs & Neo4j - Past Present Future
jexp
 
Intro to Graphs and Neo4j
Intro to Graphs and Neo4jIntro to Graphs and Neo4j
Intro to Graphs and Neo4j
jexp
 
Spring Data Neo4j Intro SpringOne 2012
Spring Data Neo4j Intro SpringOne 2012Spring Data Neo4j Intro SpringOne 2012
Spring Data Neo4j Intro SpringOne 2012
jexp
 
Neo4j & (J) Ruby Presentation JRubyConf.EU
Neo4j & (J) Ruby Presentation JRubyConf.EUNeo4j & (J) Ruby Presentation JRubyConf.EU
Neo4j & (J) Ruby Presentation JRubyConf.EU
jexp
 

Plus de 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
 

Dernier

AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
mohitmore19
 

Dernier (20)

Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 

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