JVM drivers (Java, Scala)
Fauna’s open source JVM driver supports languages that run in the Java Virtual Machine. Currently, Java and Scala clients are implemented.
Current stable version |
4.3.0 |
Repository |
Features
-
All drivers fully support the current version of the FQL API.
-
Java and Scala clients share the same underlying library faunadb-common.
-
Supports Dropwizard Metrics hooks for stats reporting.
Driver API documentation
Javadocs and Scaladocs are hosted on GitHub:
Detailed documentation is available for each language:
Install
Usage
Java
import com.faunadb.client.FaunaClient;
import static com.faunadb.client.query.Language.*;
/**
* This example connects to FaunaDB using the secret provided
* and creates a new database named "my-first-database"
*/
public class Main {
public static void main(String[] args) throws Exception {
//Create an admin connection to FaunaDB.
FaunaClient adminClient =
FaunaClient.builder()
.withSecret("YOUR_FAUNA_SECRET")
.withEndpoint("https://db.fauna.com/") // Adjust for Region Groups
.build();
adminClient.query(
CreateDatabase(
Obj("name", Value("my-first-database"))
)
).get();
adminClient.close();
}
}
For more usage details, see the supplemental Java driver documentation, and the Connections page.
Scala
import faunadb._
import faunadb.query._
import scala.concurrent._
import scala.concurrent.duration._
/**
* This example connects to FaunaDB using the secret provided
* and creates a new database named "my-first-database"
*/
object Main extends App {
import ExecutionContext.Implicits._
val client = FaunaClient(
secret = "YOUR_FAUNA_SECRET",
endpoint = "https://db.fauna.com" // Adjust for Region Groups
)
val result = client.query(
CreateDatabase(
Obj("name" -> "my-first-database")
)
)
Await.result(result, Duration.Inf)
client.close()
}
For more usage details, see the supplemental Scala driver documentation, and the Connections page.
Per-query metrics
There are several metrics that are returned with each request in the response headers. See Per-query metrics for more details.
You can access the metrics by using client.queryWithMetrics
in place
of client.query
:
Java
import com.faunadb.client.FaunaClient;
import static com.faunadb.client.query.Language.*;
public class Main {
public static void main(String[] args) throws Exception {
FaunaClient client =
FaunaClient.builder()
.withSecret("YOUR_FAUNA_SECRET")
.withEndpoint("https://db.fauna.com") // Adjust for Region Groups
.build();
MetricsResponse metricsResponse = client.queryWithMetrics(
Paginate(Match(Index("spells_by_element"), Value("fire"))),
Optional.empty()
).get();
// the result of the query, as if you used 'client.query' instead
Value value = metricsResponse.getValue();
// get the value of 'x-byte-read-ops' metric
Optional<String> byteReadOps = metricsResponse.getMetric(
MetricsResponse.Metrics.BYTE_READ_OPS
);
// get the value of 'x-byte-write-ops' metric
Optional<String> byteWriteOps = metricsResponse.getMetric(
MetricsResponse.Metrics.BYTE_WRITE_OPS
);
// you can get other metrics in the same way,
// all of them are exposed via MetricsResponse.Metrics enum
}
}
Scala
import faunadb._
import faunadb.query._
import scala.concurrent._
import scala.concurrent.duration._
/**
* This example connects to Fauna using the secret provided
* and creates a new database named "my-first-database"
*/
object Main extends App {
import ExecutionContext.Implicits._
val client = FaunaClient(
secret = "YOUR_FAUNA_SECRET",
endpoint = "https://db.fauna.com" // Adjust for Region Groups
)
val metricsResponse = client.queryWithMetrics(
Paginate(Match(Index("spells_by_element"), Value("fire"))),
None
).futureValue
// the result of the query, as if you used 'client.query' instead
val value = metricsResponse.value
// get the value of 'x-byte-read-ops' metric
val byteReadOps = metricsResponse.getMetric(Metrics.ByteReadOps)
// get the value of 'x-byte-write-ops' metric
val byteWriteOps = metricsResponse.getMetric(Metrics.ByteWriteOps)
// you can get other metrics in the same way,
// all of them are exposed via Metrics enum
}
Custom headers
You can provide custom headers to send with each HTTP request. These headers are defined in the client constructor:
Event streaming
This section demonstrates how to subscribe to change events. To learn more, see Event streaming.
There are two kinds of event streaming:
The code required to subscribe to each type is very similar. The primary difference is the type of Reference involved in the subscription, and the kinds of events that are included in the stream.
There is a cost in compute operations to hold a stream open, or to repeatedly start a stream that fails. See Billing for details. |
Document streaming
Java
The streaming API is built using the
java.util.concurrent.Flow
API, which enables users to establish flow-controlled components in
which Publishers
produce items consumed by one or more Subscribers
,
each managed by a Subscription
.
The following example subscribes to change events for a specific document:
Before you run the example:
-
Set the
FAUNADB_SECRET
environment variable, and optionally theFAUNADB_ENDPOINT
environment variable (if you are using Region Groups or Fauna Dev). -
The collection
Scores
must exist.
Once the example is running, you can use the Fauna Dashboard, or another client application, to create or update the target document and watch the events arrive as the changes are made.
For example, if the document does not yet exist, you could run this query in the Fauna Dashboard Shell:
Create(Ref(Collection("Scores"), "1"), { data: { scores: [1, 2, 3] }})
Once the document exists, you could run this query:
Update(Ref(Collection("Scores"), "1"), { data: { scores: [5, 2, 3] }})
The streaming example waits indefinitely for events. Use Ctrl+C to terminate the program.
Scala
The following sections provide examples for managing streams with Flow
or Monix, and assume that you have already created a FaunaClient
.
Flow subscriber
It is possible to use the
java.util.concurrent.Flow
API directly by binding a Subscriber
manually.
The following example subscribes to change events for a specific document:
Before you run the example:
-
Set the
FAUNADB_SECRET
environment variable, and optionally theFAUNADB_ENDPOINT
environment variable (if you are using Region Groups or Fauna Dev). -
The collection
Scores
must exist.
Once the example is running, you can use the Fauna Dashboard, or another client application, to create or update the target document and watch the events arrive as the changes are made.
For example, if the document does not yet exist, you could run this query in the Fauna Dashboard Shell:
Create(Ref(Collection("Scores"), "1"), { data: { scores: [1, 2, 3] }})
Once the document exists, you could run this query:
Update(Ref(Collection("Scores"), "1"), { data: { scores: [5, 2, 3] }})
The streaming example waits indefinitely for events. Use Ctrl+C to terminate the program.
Monix
The reactive-streams standard offers a strong interoperability in the streaming ecosystem.
We can replicate the previous example using the Monix streaming library:
import faunadb._
import faunadb.query._
import monix.execution.Scheduler
import monix.reactive.Observable
import org.reactivestreams.{FlowAdapters, Publisher}
// docRef is a reference to the document for which we want to stream
// updates. You can acquire a document reference with a query like the
// following, but it needs to work with the documents that you have.
// val docRef = Ref(Collection("scoreboards"), "123")
client.stream(docRef).flatMap { publisher =>
val reactiveStreamsPublisher: Publisher[Value] = FlowAdapters.toPublisher(
publisherValue
)
Observable.fromReactivePublisher(reactiveStreamsPublisher)
.take(4) // 4 events
.toListL
.runToFuture(Scheduler.Implicits.global)
}
Set streaming
Java
The streaming API is built using the
java.util.concurrent.Flow
API, which enables users to establish flow-controlled components in
which Publishers
produce items consumed by one or more Subscribers
,
each managed by a Subscription
.
The following example subscribes to change events for a set:
Before you run the example:
-
Set the
FAUNADB_SECRET
environment variable, and optionally theFAUNADB_ENDPOINT
environment variable (if you are using Region Groups or Fauna Dev). -
The collection
Scores
must exist.
Once the example is running, you can use the Fauna Dashboard, or another client application, to add or delete documents in the "Scores" collection and watch the events arrive as the changes are made. For example, you could run this query in the Fauna Dashboard's Shell:
Create(Collection("Scores"), { data: { scores: [5, 6, 7] }})
The streaming example waits indefinitely for events. Use Ctrl+C to terminate the program.
Scala
The following example subscribes to change events for a set:
Before you run the example:
-
Set the
FAUNADB_SECRET
environment variable, and optionally theFAUNADB_ENDPOINT
environment variable (if you are using Region Groups or Fauna Dev). -
The collection
Scores
must exist.
Once the example is running, you can use the Fauna Dashboard, or another client application, to add or delete documents in the "Scores" collection and watch the events arrive as the changes are made. For example, you could run this query in the Fauna Dashboard's Shell:
Create(Collection("Scores"), { data: { scores: [5, 6, 7] }})
The streaming example waits indefinitely for events. Use Ctrl+C to terminate the program.
The changes required to use Monix are not repeated here. |
Next steps
-
Driver repository: https://github.com/fauna/faunadb-jvm
-
For more information about the Fauna Query Language, consult our query language reference documentation.
Is this article helpful?
Tell Fauna how the article can be improved:
Visit Fauna's forums
or email docs@fauna.com
Thank you for your feedback!