Skip to content

Instantly share code, notes, and snippets.

@michael-simons
Last active September 15, 2022 12:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michael-simons/f8a8a122d1066f61b2ee8cd82b6401b8 to your computer and use it in GitHub Desktop.
Save michael-simons/f8a8a122d1066f61b2ee8cd82b6401b8 to your computer and use it in GitHub Desktop.
Brings up a Neo4jGraphQL Java server.
///usr/bin/env jbang "$0" "$@" ; exit $?
//JAVA 16
//JAVAC_OPTIONS -source 16
//DEPS info.picocli:picocli:4.6.1
//DEPS io.javalin:javalin:3.13.9
//DEPS org.neo4j.driver:neo4j-java-driver:4.3.3
//DEPS org.neo4j:neo4j-graphql-java:1.3.0
//DEPS com.fasterxml.jackson.core:jackson-databind:2.10.5
//DEPS org.slf4j:slf4j-simple:1.7.31
package com.example.graphqlplain;
import io.javalin.Javalin;
import picocli.CommandLine;
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import org.neo4j.driver.AuthTokens;
import org.neo4j.driver.Config;
import org.neo4j.driver.GraphDatabase;
import org.neo4j.driver.Logging;
import org.neo4j.driver.Record;
import org.neo4j.graphql.SchemaBuilder;
import org.neo4j.graphql.Translator;
/**
* Run with {@code jbang Neo4jGraphqlJava.java}
* to bring up a Neo4j GraphQL Java server connected against your local instance with a default schema.
*
* Run {@code jbang Neo4jGraphqlJava.java --help} to print available options.
*
* @author Michael Simons
*/
@CommandLine.Command(name = "neo4j-graphql", mixinStandardHelpOptions = true,
description = "Starts a Neo4j-Graphql middleware.")
public class Neo4jGraphqlJava implements Runnable {
@CommandLine.Option(names = { "-u", "--user" }, description = "Neo4j user", defaultValue = "neo4j")
String user;
@CommandLine.Option(names = { "-p",
"--password" }, description = "Neo4j password", arity = "0..1", interactive = true, defaultValue = "secret")
char[] password;
@CommandLine.Option(names = { "-a",
"--address" }, description = "address and port to connect to", defaultValue = "neo4j://localhost:7687")
String address;
@CommandLine.Option(names = { "-P", "--port" }, description = "Port to listen on", defaultValue = "7000")
Integer port;
@CommandLine.Option(names = "--schema", arity = "0..1", description = "Schema definition")
File schema;
public static void main(String[] args) {
new CommandLine(new Neo4jGraphqlJava()).execute(args);
}
private String getSchema() {
if (this.schema != null) {
try {
return Files.readString(this.schema.toPath());
} catch (IOException e) {
throw new UncheckedIOException(e);
}
} else {
return """
type Person {
name: ID!
born: Int
actedIn: [Movie] @relation(name: "ACTED_IN")
}
type Movie {
title: ID!
released: Int
tagline: String
}
type Query {
person: [Person]
}
""";
}
}
@Override
public void run() {
var driver = GraphDatabase.driver(
address,
AuthTokens.basic(user, new String(this.password)),
Config.builder().withLogging(Logging.slf4j()).build()
);
driver.verifyConnectivity();
var graphql = new Translator(SchemaBuilder.buildSchema(getSchema()));
var server = Javalin.create()
.events(event -> event.serverStopping(() -> driver.close()))
.start(port);
server.post("/graphql", ctx -> {
if (ctx.contentLength() == 0) {
return;
}
graphql.translate(ctx.body()).stream().findFirst().ifPresent(cypher -> {
try (var session = driver.session()) {
var result = session
.writeTransaction(tx -> tx.run(cypher.getQuery(), cypher.getParams()).list(Record::asMap));
ctx.json(result);
}
});
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment