July 2020
Vapor with Theo - Getting Started
16/07/20 17:53
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:
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.
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:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.