July 2020

Vapor with Theo - Getting Started

Theo, the Neo4j Swift driver, works well with Vapor 4.
For future reference: This post was written with Theo 5.2.0, Vapor 4.15.2 and Swift 5.2.4

Let's have a look at how to use it together, starting with the crudest example:

import Vapor
import Theo
func theoClient(completion: @escaping (BoltClient) -> ()) {
do {
let client = try BoltClient(hostname: "127.0.0.1",
port: 7687,
username: "neo4j",
password: "test",
encrypted: true)
client.connect { result in
let isSuccess = try! result.get()
assert(isSuccess)
completion(client)
}
} catch {
print("Error! \(String(describing: error))")
}
}
func routes(_ app: Application) throws {
app.get { req -> EventLoopFuture<String> in
let promise: EventLoopPromise<String> = req.eventLoop.makePromise()
theoClient() { theo in
let newNode = Node(label: "New", properties: [ "createdTime": Date().timeIntervalSince1970 ])
theo.createAndReturnNode(node: newNode) { result in
do {
let node = try result.get()
assert(node.labels.first! == "New")
promise.completeWith(.success("Newly created node!"))
} catch {
promise.completeWith(.failure(error))
}
}
}
return promise.futureResult
}
}


In the code above, we start with the theoClient function that in it's completion block provides a Bolt client. Bolt is the binary protocol used to talk to a Neo4j instance. I've configured it to connect to the instance on my machine at port 7687, the default Bolt port. I provide a username and password, and ask it to connect via SSL, a configuration you may know from the Neo4j browser as bolt+s.

For this example, I've written a router with only one endpoint and implemented it straight away. When a request is made, we make a promise to Vapor that we'll return a string. Then we ask for a Theo client, and define a new node we want to insert. The node contains a single label: "New", and a single property "createdTime", with the current time as a TimeInterval (a.k.a. Double).

We ask the client to create it, and if it is successful, we fulfil our promise saying "Newly created node!". If, however, there is a problem, we complete with a failure and report the error.