{"id":25021363,"url":"https://github.com/hypermodeinc/dgraph4j","last_synced_at":"2025-04-12T18:49:01.762Z","repository":{"id":45279178,"uuid":"62293060","full_name":"hypermodeinc/dgraph4j","owner":"hypermodeinc","description":"Official Dgraph Java client","archived":false,"fork":false,"pushed_at":"2025-04-11T00:29:20.000Z","size":999,"stargazers_count":161,"open_issues_count":0,"forks_count":63,"subscribers_count":34,"default_branch":"main","last_synced_at":"2025-04-11T01:29:00.854Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://dgraph.io","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hypermodeinc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-06-30T08:17:58.000Z","updated_at":"2025-04-11T00:29:22.000Z","dependencies_parsed_at":"2024-06-27T15:08:21.346Z","dependency_job_id":"d48488f8-340a-43ec-8142-e203a586c918","html_url":"https://github.com/hypermodeinc/dgraph4j","commit_stats":null,"previous_names":["hypermodeinc/dgraph4j"],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hypermodeinc%2Fdgraph4j","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hypermodeinc%2Fdgraph4j/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hypermodeinc%2Fdgraph4j/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hypermodeinc%2Fdgraph4j/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hypermodeinc","download_url":"https://codeload.github.com/hypermodeinc/dgraph4j/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248618218,"owners_count":21134199,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-02-05T13:00:52.022Z","updated_at":"2025-04-12T18:49:01.755Z","avatar_url":"https://github.com/hypermodeinc.png","language":"Java","readme":"# Dgraph Client for Java\n\nA minimal implementation for a Dgraph client for Java 11 and above, using [grpc].\n\n**Note:** v24.0.0 features an upgraded protobuf dependency which requires an upgrade to JDK 11. On\naccount of this breaking change, all legacy applications built upon JDK 8 would be impacted.\n\n[grpc]: https://grpc.io/\n\nThis client follows the [Dgraph Go client][goclient] closely.\n\n[goclient]: https://github.com/dgraph-io/dgo\n\nBefore using this client, we highly recommend that you go through [docs.dgraph.io], and understand\nhow to run and work with Dgraph.\n\n[docs.dgraph.io]: https://docs.dgraph.io\n\n**Use [Discuss Issues](https://discuss.dgraph.io/c/issues/35/clients/46) for reporting issues about\nthis repository.**\n\n## Table of Contents\n\n- [Dgraph Client for Java](#dgraph-client-for-java)\n\n  - [Table of Contents](#table-of-contents)\n  - [Download](#download)\n  - [Supported Versions](#supported-versions)\n    - [Note regarding Java 1.8.x support:](#note-regarding-java-18x-support)\n  - [Quickstart](#quickstart)\n  - [Intro](#intro)\n  - [Using the Synchronous Client](#using-the-synchronous-client)\n    - [Creating a Client](#creating-a-client)\n    - [Creating a Client for Dgraph Cloud](#creating-a-client-for-dgraph-cloud)\n    - [Creating a Secure Client using TLS](#creating-a-secure-client-using-tls)\n    - [Check Dgraph version](#check-dgraph-version)\n    - [Login Using ACL](#login-using-acl)\n    - [Altering the Database](#altering-the-database)\n    - [Creating a Transaction](#creating-a-transaction)\n    - [Running a Mutation](#running-a-mutation)\n    - [Committing a Transaction](#committing-a-transaction)\n    - [Running a Query](#running-a-query)\n    - [Running a Query with RDF response](#running-a-query-with-rdf-response)\n    - [Running an Upsert: Query + Mutation](#running-an-upsert-query--mutation)\n    - [Running a Conditional Upsert](#running-a-conditional-upsert)\n    - [Setting Deadlines](#setting-deadlines)\n      - [Setting deadlines for all requests](#setting-deadlines-for-all-requests)\n      - [Setting deadlines for a single request](#setting-deadlines-for-a-single-request)\n    - [Setting Metadata Headers](#setting-metadata-headers)\n    - [Helper Methods](#helper-methods)\n      - [Delete multiple edges](#delete-multiple-edges)\n    - [Closing the DB Connection](#closing-the-db-connection)\n  - [Using the Asynchronous Client](#using-the-asynchronous-client)\n  - [Checking the request latency](#checking-the-request-latency)\n  - [Development](#development)\n    - [Building the source](#building-the-source)\n    - [Code Style](#code-style)\n    - [Running unit tests](#running-unit-tests)\n\n- [Using the Asynchronous Client](#using-the-asynchronous-client)\n- [Checking the request latency](#checking-the-request-latency)\n\n- [Development](#development)\n  - [Building the source](#building-the-source)\n  - [Code Style](#code-style)\n  - [Running unit tests](#running-unit-tests)\n\n## Download\n\ngrab via Maven:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eio.dgraph\u003c/groupId\u003e\n  \u003cartifactId\u003edgraph4j\u003c/artifactId\u003e\n  \u003cversion\u003e24.1.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nor Gradle:\n\n```groovy\ncompile 'io.dgraph:dgraph4j:24.1.1'\n```\n\n## Supported Versions\n\nDepending on the version of Dgraph that you are connecting to, you will have to use a different\nversion of this client.\n\n| Dgraph version  | dgraph4j version | java version |\n| :-------------: | :--------------: | :----------: |\n|      1.0.X      |      1.X.X       |    1.9.X     |\n|  1.1.0 - 2.X.X  |      2.X.X       |    1.9.X     |\n| 20.03.X-20.07.X |     20.03.X      |    1.9.X     |\n|     20.11.X     |     20.11.X      |    1.9.X     |\n|   \u003e= 21.XX.X    |     21.XX.X      |    1.9.X     |\n|    \u003e= 24.X.X    |      24.X.X      |      11      |\n\n### Note regarding Java 1.8.x support\n\nv24.0.0 features an upgraded protoc-protobuf dependency that requires an upgrade to JDK 11. This\nversion is incompatible with Java 1.8 and and requires an upgrade to Java 11.\n\nThe following is only applicable to dgraph4j versions \u003c v24.X.X.\n\n- If you aren't using gRPC with TLS, then the above version table will work for you with Java 1.8.x\n  too.\n- If you're using gRPC with TLS on Java 1.8.x, then you will need to follow gRPC docs\n  [here](https://github.com/grpc/grpc-java/blob/master/SECURITY.md#tls-on-non-android). Basically,\n  it will require you to add the following dependency in your app with correct version for the\n  corresponding `grpc-netty` version used by `dgraph4j`. You can find out the correct version of the\n  dependency to use from the version combination table in [this section] in `grpc-netty` docs.\n\n  For maven:\n\n  ```xml\n  \u003cdependency\u003e\n    \u003cgroupId\u003eio.netty\u003c/groupId\u003e\n    \u003cartifactId\u003enetty-tcnative-boringssl-static\u003c/artifactId\u003e\n    \u003cversion\u003e\u003c!-- See table in gRPC docs for correct version --\u003e\u003c/version\u003e\n  \u003c/dependency\u003e\n  ```\n\n  For Gradle:\n\n  ```groovy\n  compile 'io.netty:netty-tcnative-boringssl-static:\u003cSee table in gRPC docs for correct version\u003e'\n  ```\n\n  The following table lists the `grpc-netty` versions used by different `dgraph4j` versions over\n  time, along with the supported versions of `netty-tcnative-boringssl-static` for the corresponding\n  `grpc-netty` version:\n\n  | dgraph4j version | grpc-netty version | netty-tcnative-boringssl-static version |\n  | :--------------: | :----------------: | :-------------------------------------: |\n  |   1.0.0-1.2.0    |       1.7.0        |               2.0.6.Final               |\n  |   1.4.0-1.6.0    |       1.10.0       |               2.0.7.Final               |\n  |      1.7.0       |       1.15.0       |              2.0.12.Final               |\n  |   1.7.3-1.7.5    |       1.15.1       |              2.0.12.Final               |\n  |   2.0.0-2.1.0    |       1.22.1       |              2.0.25.Final               |\n  | 20.03.0-20.03.3  |       1.26.0       |              2.0.26.Final               |\n  |    \u003e= 20.11.0    |       1.34.1       |              2.0.31.Final               |\n  |    \u003e= 24.0.0     |       1.65.1       |              4.1.100.Final              |\n  |    \u003e= 24.1.1     |       1.68.2       |              4.1.110.Final              |\n\n  For example, when using `dgraph4j v24.0.0`, the version of the `netty-tcnative-boringssl-static`\n  dependency to be used is `4.1.100.Final`, as suggested by gRPC docs for `grpc-netty v1.65.1`.\n\n[this section]: https://github.com/grpc/grpc-java/blob/master/SECURITY.md#netty\n\n## Quickstart\n\nBuild and run the [DgraphJavaSample] project in the `samples` folder, which contains an end-to-end\nexample of using the Dgraph Java client. Follow the instructions in the README of that project.\n\n[DgraphJavaSample]: https://github.com/hypermodeinc/dgraph4j/tree/master/samples/DgraphJavaSample\n\n## Intro\n\nThis library supports two styles of clients, the synchronous client `DgraphClient` and the async\nclient `DgraphAsyncClient`. A `DgraphClient` or `DgraphAsyncClient` can be initialised by passing it\na list of `DgraphBlockingStub` clients. The `anyClient()` API can randomly pick a stub, which can\nthen be used for GRPC operations. In the next section, we will explain how to create a synchronous\nclient and use it to mutate or query dgraph. For the async client, more details can be found in the\n[Using the Asynchronous Client](#using-the-asynchronous-client) section.\n\n## Using the Synchronous Client\n\n### Creating a Client\n\n#### Using a Connection String\n\nThis library supports connecting to a Dgraph cluster using connection strings. Dgraph connections\nstrings take the form `dgraph://{username:password@}host:port?args`.\n\n`username` and `password` are optional. If username is provided, a password must also be present. If\nsupplied, these credentials are used to log into a Dgraph cluster through the ACL mechanism.\n\nValid connection string args:\n\n| Arg         | Value                           | Description                                                                                                                                                   |\n| ----------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| apikey      | \\\u003ckey\\\u003e                         | a Dgraph Cloud API Key                                                                                                                                        |\n| bearertoken | \\\u003ctoken\\\u003e                       | an access token                                                                                                                                               |\n| sslmode     | disable \\| require \\| verify-ca | TLS option, the default is `disable`. If `verify-ca` is set, the TLS certificate configured in the Dgraph cluster must be from a valid certificate authority. |\n\nNote that using `sslmode=require` disables certificate validation and significantly reduces the\nsecurity of TLS. This mode should only be used in non-production (e.g., testing or development)\nenvironments.\n\nSome example connection strings:\n\n| Value                                                                                                        | Explanation                                                                         |\n| ------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- |\n| dgraph://localhost:9080                                                                                      | Connect to localhost, no ACL, no TLS                                                |\n| dgraph://sally:supersecret@dg.example.com:443?sslmode=verify-ca                                              | Connect to remote server, use ACL and require TLS and a valid certificate from a CA |\n| dgraph://foo-bar.grpc.us-west-2.aws.cloud.dgraph.io:443?sslmode=verify-ca\u0026apikey=\\\u003cyour-api-connection-key\\\u003e | Connect to a Dgraph Cloud cluster                                                   |\n| dgraph://foo-bar.grpc.hypermode.com?sslmode=verify-ca\u0026bearertoken=\\\u003csome access token\\\u003e                      | Connect to a Dgraph cluster protected by a secure gateway                           |\n\nUsing the `DgraphClient.open` function with a connection string:\n\n```java\n// open a connection to an ACL-enabled, non-TLS cluster and login as groot\nDgraphClient client = DgraphClient.open(\"dgraph://groot:password@localhost:8090\");\n\n// some time later...\nclient.shutdown();\n```\n\n#### Using Managed Channels\n\nThe following code snippet shows how to create a synchronous client using three connections.\n\n```java\nManagedChannel channel1 = ManagedChannelBuilder\n    .forAddress(\"localhost\", 9080)\n    .usePlaintext().build();\nDgraphStub stub1 = DgraphGrpc.newStub(channel1);\n\nManagedChannel channel2 = ManagedChannelBuilder\n    .forAddress(\"localhost\", 9082)\n    .usePlaintext().build();\nDgraphStub stub2 = DgraphGrpc.newStub(channel2);\n\nManagedChannel channel3 = ManagedChannelBuilder\n    .forAddress(\"localhost\", 9083)\n    .usePlaintext().build();\nDgraphStub stub3 = DgraphGrpc.newStub(channel3);\n\nDgraphClient dgraphClient = new DgraphClient(stub1, stub2, stub3);\n```\n\n### Creating a Client for Dgraph Cloud\n\nIf you want to connect to Dgraph running on a [Dgraph Cloud](https://cloud.dgraph.io) instance, then\nall you need is the URL of your Dgraph Cloud instance and the API key. You can get a client with\nthem as follows :\n\n```java\nDgraphStub stub = DgraphClient.clientStubFromCloudEndpoint(\"https://your-instance.cloud.dgraph.io/graphql\", \"your-api-key\");\nDgraphClient dgraphClient = new DgraphClient(stub);\n```\n\nNote the `DgraphClient.open` method can be used if you have a Dgraph connection string (see above).\n\n### Creating a Secure Client using TLS\n\nTo setup a client using TLS, you could use the following code snippet. The server needs to be setup\nusing the instructions provided [here](https://docs.dgraph.io/deploy/#tls-configuration).\n\nIf you are doing client verification, you need to convert the client key from PKCS#1 format to\nPKCS#8 format. By default, grpc doesn't support reading PKCS#1 format keys. To convert the format,\nyou could use the `openssl` tool.\n\nFirst, let's install the `openssl` tool:\n\n```sh\napt install openssl\n```\n\nNow, use the following command to convert the key:\n\n```sh\nopenssl pkcs8 -in client.name.key -topk8 -nocrypt -out client.name.java.key\n```\n\nNow, you can use the following code snippet to connect to Alpha over TLS:\n\n```java\nSslContextBuilder builder = GrpcSslContexts.forClient();\nbuilder.trustManager(new File(\"\u003cpath to ca.crt\u003e\"));\n// Skip the next line if you are not performing client verification.\nbuilder.keyManager(new File(\"\u003cpath to client.name.crt\u003e\"), new File(\"\u003cpath to client.name.java.key\u003e\"));\nSslContext sslContext = builder.build();\n\nManagedChannel channel = NettyChannelBuilder.forAddress(\"localhost\", 9080)\n    .sslContext(sslContext)\n    .build();\nDgraphGrpc.DgraphStub stub = DgraphGrpc.newStub(channel);\nDgraphClient dgraphClient = new DgraphClient(stub);\n```\n\n### Check Dgraph version\n\nChecking the version of the Dgraph server this client is interacting with is as easy as:\n\n```java\nVersion v = dgraphClient.checkVersion();\nSystem.out.println(v.getTag());\n```\n\nChecking the version, before doing anything else can be used as a test to find out if the client is\nable to communicate with the Dgraph server. This will also help reduce the latency of the first\nquery/mutation which results from some dynamic library loading and linking that happens in JVM (see\n[this issue](https://github.com/hypermodeinc/dgraph4j/issues/108) for more details).\n\n### Login Using ACL\n\nIf ACL is enabled then you can log-in to the default namespace (0) with following:\n\n```java\ndgraphClient.login(USER_ID, USER_PASSWORD);\n```\n\nFor logging-in to some other namespace, use the `loginIntoNamespace` method on the client:\n\n```java\ndgraphClient.loginIntoNamespace(USER_ID, USER_PASSWORD, NAMESPACE);\n```\n\nOnce logged-in, the `dgraphClient` object can be used to do any further operations.\n\n### Altering the Database\n\nTo set the schema, create an `Operation` object, set the schema and pass it to `DgraphClient#alter`\nmethod.\n\n```java\nString schema = \"name: string @index(exact) .\";\nOperation operation = Operation.newBuilder().setSchema(schema).build();\ndgraphClient.alter(operation);\n```\n\nStarting Dgraph version 20.03.0, indexes can be computed in the background. You can call the\nfunction `setRunInBackground(true)` as shown below before calling `alter`. You can find more details\n[here](https://docs.dgraph.io/master/query-language/#indexes-in-background).\n\n```java\nString schema = \"name: string @index(exact) .\";\nOperation operation = Operation.newBuilder()\n        .setSchema(schema)\n        .setRunInBackground(true)\n        .build();\ndgraphClient.alter(operation);\n```\n\n`Operation` contains other fields as well, including drop predicate and drop all. Drop all is useful\nif you wish to discard all the data, and start from a clean slate, without bringing the instance\ndown.\n\n```java\n// Drop all data including schema from the dgraph instance. This is useful\n// for small examples such as this, since it puts dgraph into a clean\n// state.\ndgraphClient.alter(Operation.newBuilder().setDropAll(true).build());\n```\n\n### Creating a Transaction\n\nThere are two types of transactions in dgraph, i.e. the read-only transactions that only include\nqueries and the transactions that change data in dgraph with mutate operations. Both the synchronous\nclient `DgraphClient` and the async client `DgraphAsyncClient` support the two types of transactions\nby providing the `newTransaction` and the `newReadOnlyTransaction` APIs. Creating a transaction is a\nlocal operation and incurs no network overhead.\n\nIn most of the cases, the normal read-write transactions is used, which can have any number of query\nor mutate operations. However, if a transaction only has queries, you might benefit from a read-only\ntransaction, which can share the same read timestamp across multiple such read-only transactions and\ncan result in lower latencies.\n\nFor normal read-write transactions, it is a good practise to call `Transaction#discard()` in a\n`finally` block after running the transaction. Calling `Transaction#discard()` after\n`Transaction#commit()` is a no-op and you can call `discard()` multiple times with no additional\nside-effects.\n\n```java\nTransaction txn = dgraphClient.newTransaction();\ntry {\n    // Do something here\n    // ...\n} finally {\n    txn.discard();\n}\n```\n\nFor read-only transactions, there is no need to call `Transaction.discard`, which is equivalent to a\nno-op.\n\n```java\nTransaction readOnlyTxn = dgraphClient.newReadOnlyTransaction();\n```\n\nRead-only transactions can be set as best-effort. Best-effort queries relax the requirement of\nlinearizable reads. This is useful when running queries that do not require a result from the latest\ntimestamp.\n\n```java\nTransaction bestEffortTxn = dgraphClient.newReadOnlyTransaction()\n    .setBestEffort(true);\n```\n\n### Running a Mutation\n\n`Transaction#mutate` runs a mutation. It takes in a `Mutation` object, which provides two main ways\nto set data: JSON and RDF N-Quad. You can choose whichever way is convenient.\n\nWe're going to use JSON. First we define a `Person` class to represent a person. This data will be\nserialized into JSON.\n\n```java\nclass Person {\n    String name\n    Person() {}\n}\n```\n\nNext, we initialise a `Person` object, serialize it and use it in `Mutation` object.\n\n```java\n// Create data\nPerson person = new Person();\nperson.name = \"Alice\";\n\n// Serialize it\nGson gson = new Gson();\nString json = gson.toJson(person);\n// Run mutation\nMutation mu = Mutation.newBuilder()\n    .setSetJson(ByteString.copyFromUtf8(json.toString()))\n    .build();\n// mutationResponse stores a Response protocol buffer object\nResponse mutationResponse = txn.mutate(mu);\n// eg: to get the UIDs created in this mutation\nSystem.out.println(mutationResponse.getUidsMap())\n```\n\nSometimes, you only want to commit mutation, without querying anything further. In such cases, you\ncan use a `CommitNow` field in `Mutation` object to indicate that the mutation must be immediately\ncommitted.\n\nMutation can be run using the `doRequest` function as well.\n\n```java\nRequest request = Request.newBuilder()\n    .addMutations(mu)\n    .build();\ntxn.doRequest(request);\n```\n\n### Committing a Transaction\n\nA transaction can be committed using the `Transaction#commit()` method. If your transaction\nconsisted solely of calls to `Transaction#query()`, and no calls to `Transaction#mutate()`, then\ncalling `Transaction#commit()` is not necessary.\n\nAn error will be returned if other transactions running concurrently modify the same data that was\nmodified in this transaction. It is up to the user to retry transactions when they fail.\n\n```java\nTransaction txn = dgraphClient.newTransaction();\n\ntry {\n    // …\n    // Perform any number of queries and mutations\n    // …\n    // and finally …\n    txn.commit()\n} catch (TxnConflictException ex) {\n    // Retry or handle exception.\n} finally {\n    // Clean up. Calling this after txn.commit() is a no-op\n    // and hence safe.\n    txn.discard();\n}\n```\n\n### Running a Query\n\nYou can run a query by calling `Transaction#query()`. You will need to pass in a GraphQL+- query\nstring, and a map (optional, could be empty) of any variables that you might want to set in the\nquery.\n\nThe response would contain a `JSON` field, which has the JSON encoded result. You will need to\ndecode it before you can do anything useful with it.\n\nLet’s run the following query:\n\n```java\nquery all($a: string) {\n  all(func: eq(name, $a)) {\n            name\n  }\n}\n```\n\nFirst we must create a `People` class that will help us deserialize the JSON result:\n\n```java\nclass People {\n    List\u003cPerson\u003e all;\n    People() {}\n}\n```\n\nThen we run the query, deserialize the result and print it out:\n\n```java\n// Query\nString query =\n\"query all($a: string){\\n\" +\n\"  all(func: eq(name, $a)) {\\n\" +\n\"    name\\n\" +\n\"  }\\n\" +\n\"}\\n\";\n\nMap\u003cString, String\u003e vars = Collections.singletonMap(\"$a\", \"Alice\");\nResponse response = dgraphClient.newReadOnlyTransaction().queryWithVars(query, vars);\n\n// Deserialize\nPeople ppl = gson.fromJson(response.getJson().toStringUtf8(), People.class);\n\n// Print results\nSystem.out.printf(\"people found: %d\\n\", ppl.all.size());\nppl.all.forEach(person -\u003e System.out.println(person.name));\n```\n\nThis should print:\n\n```sh\npeople found: 1\nAlice\n```\n\nYou can also use `doRequest` function to run the query.\n\n```java\nRequest request = Request.newBuilder()\n    .setQuery(query)\n    .build();\ntxn.doRequest(request);\n```\n\n### Running a Query with RDF response\n\nYou can get query results as an RDF response by calling either `queryRDF()` or `queryRDFWithVars()`.\nThe response contains the `getRdf()` method, which will provide the RDF encoded output.\n\n**Note**: If you are querying for `uid` values only, use a JSON format response\n\n```java\n// Query\nString query = \"query me($a: string) { me(func: eq(name, $a)) { name }}\";\nMap\u003cString, String\u003e vars = Collections.singletonMap(\"$a\", \"Alice\");\nResponse response =\n    dgraphAsyncClient.newReadOnlyTransaction().queryRDFWithVars(query, vars).join();\n\n// Print results\nSystem.out.println(response.getRdf().toStringUtf8());\n```\n\nThis should print (assuming Alice's `uid` is `0x2`):\n\n```sh\n\u003c0x2\u003e \u003cname\u003e \"Alice\" .\n```\n\n### Running an Upsert: Query + Mutation\n\nThe `txn.doRequest` function allows you to run upserts consisting of one query and one mutation.\nVariables can be defined in the query and used in the mutation. You could also use `txn.doRequest`\nto perform a query followed by a mutation.\n\nTo know more about upsert, we highly recommend going through the docs at\nhttps://docs.dgraph.io/mutations/#upsert-block.\n\n```java\nString query = \"query {\\n\" +\n  \"user as var(func: eq(email, \\\"wrong_email@dgraph.io\\\"))\\n\" +\n  \"}\\n\";\nMutation mu = Mutation.newBuilder()\n    .setSetNquads(ByteString.copyFromUtf8(\"uid(user) \u003cemail\u003e \\\"correct_email@dgraph.io\\\" .\"))\n    .build();\nRequest request = Request.newBuilder()\n    .setQuery(query)\n    .addMutations(mu)\n    .setCommitNow(true)\n    .build();\ntxn.doRequest(request);\n```\n\n### Running a Conditional Upsert\n\nThe upsert block also allows specifying a conditional mutation block using an `@if` directive. The\nmutation is executed only when the specified condition is true. If the condition is false, the\nmutation is silently ignored.\n\nSee more about Conditional Upsert [Here](https://docs.dgraph.io/mutations/#conditional-upsert).\n\n```java\nString query = \"query {\\n\" +\n    \"user as var(func: eq(email, \\\"wrong_email@dgraph.io\\\"))\\n\" +\n    \"}\\n\";\nMutation mu = Mutation.newBuilder()\n    .setSetNquads(ByteString.copyFromUtf8(\"uid(user) \u003cemail\u003e \\\"correct_email@dgraph.io\\\" .\"))\n    .setCond(\"@if(eq(len(user), 1))\")\n    .build();\nRequest request = Request.newBuilder()\n    .setQuery(query)\n    .addMutations(mu)\n    .setCommitNow(true)\n    .build();\ntxn.doRequest(request);\n```\n\n### Setting Deadlines\n\nIt is recommended that you always set a deadline for each client call, after which the client\nterminates. This is in line with the recommendation for any gRPC client. Read [this forum\npost][deadline-post] for more details.\n\n#### Setting deadlines for all requests\n\n```java\nchannel = ManagedChannelBuilder.forAddress(\"localhost\", 9080).usePlaintext(true).build();\nDgraphGrpc.DgraphStub stub = DgraphGrpc.newStub(channel);\nClientInterceptor timeoutInterceptor = new ClientInterceptor(){\n    @Override\n    public \u003cReqT, RespT\u003e ClientCall\u003cReqT, RespT\u003e interceptCall(\n            MethodDescriptor\u003cReqT, RespT\u003e method, CallOptions callOptions, Channel next) {\n        return next.newCall(method, callOptions.withDeadlineAfter(500, TimeUnit.MILLISECONDS));\n    }\n};\nstub = stub.withInterceptors(timeoutInterceptor);\nDgraphClient dgraphClient = new DgraphClient(stub);\n```\n\n#### Setting deadlines for a single request\n\n```java\ndgraphClient.newTransaction().query(query, 500, TimeUnit.MILLISECONDS);\n```\n\n[deadline-post]: https://discuss.dgraph.io/t/dgraph-java-client-setting-deadlines-per-call/3056\n\n### Setting Metadata Headers\n\nCertain headers such as authentication tokens need to be set globally for all subsequent calls.\nBelow is an example of setting a header with the name \"auth-token\":\n\n```java\n// create the stub first\nManagedChannel channel =\nManagedChannelBuilder.forAddress(TEST_HOSTNAME, TEST_PORT).usePlaintext(true).build();\nDgraphStub stub = DgraphGrpc.newStub(channel);\n\n// use MetadataUtils to augment the stub with headers\nMetadata metadata = new Metadata();\nmetadata.put(\n        Metadata.Key.of(\"auth-token\", Metadata.ASCII_STRING_MARSHALLER), \"the-auth-token-value\");\nstub = MetadataUtils.attachHeaders(stub, metadata);\n\n// create the DgraphClient wrapper around the stub\nDgraphClient dgraphClient = new DgraphClient(stub);\n\n// trigger a RPC call using the DgraphClient\ndgraphClient.alter(Operation.newBuilder().setDropAll(true).build());\n```\n\n### Helper Methods\n\n#### Delete multiple edges\n\nThe example below uses the helper method `Helpers#deleteEdges` to delete multiple edges\ncorresponding to predicates on a node with the given uid. The helper method takes an existing\nmutation, and returns a new mutation with the deletions applied.\n\n```java\nMutation mu = Mutation.newBuilder().build()\nmu = Helpers.deleteEdges(mu, uid, \"friends\", \"loc\");\ndgraphClient.newTransaction().mutate(mu);\n```\n\n### Closing the DB Connection\n\nTo disconnect from Dgraph, call `ManagedChannel#shutdown` on the gRPC channel object created when\n[creating a Dgraph client](#creating-a-client).\n\n```java\nchannel.shutdown();\n```\n\nYou can also close all channels in from the client object:\n\n```java\ndgraphClient.shutdown();\n```\n\n## Using the Asynchronous Client\n\nDgraph Client for Java also bundles an asynchronous API, which can be used by instantiating the\n`DgraphAsyncClient` class. The usage is almost exactly the same as the `DgraphClient` (show in\nprevious section) class. The main differences is that the `DgraphAsyncClient#newTransacation()`\nreturns an `AsyncTransaction` class. The API for `AsyncTransaction` is exactly `Transaction`. The\nonly difference is that instead of returning the results directly, it returns immediately with a\ncorresponding `CompletableFuture\u003cT\u003e` object. This object represents the computation which runs\nasynchronously to yield the result in the future. Read more about `CompletableFuture\u003cT\u003e` in the\n[Java 8 documentation][futuredocs].\n\n[futuredocs]: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html\n\nHere is the asynchronous version of the code above, which runs a query.\n\n```java\n// Query\nString query =\n\"query all($a: string){\\n\" +\n\"  all(func: eq(name, $a)) {\\n\" +\n\"    name\\n\" +\n \"}\\n\" +\n\"}\\n\";\n\nMap\u003cString, String\u003e vars = Collections.singletonMap(\"$a\", \"Alice\");\n\nAsyncTransaction txn = dgraphAsyncClient.newTransaction();\ntxn.query(query).thenAccept(response -\u003e {\n    // Deserialize\n    People ppl = gson.fromJson(res.getJson().toStringUtf8(), People.class);\n\n    // Print results\n    System.out.printf(\"people found: %d\\n\", ppl.all.size());\n    ppl.all.forEach(person -\u003e System.out.println(person.name));\n});\n```\n\n## Checking the request latency\n\nIf you would like to see the latency for either a mutation or query request, the latency field in\nthe returned result can be helpful. Here is an example to log the latency of a query request:\n\n```java\nResponse resp = txn.query(query);\nLatency latency = resp.getLatency();\nlogger.info(\"parsing latency:\" + latency.getParsingNs());\nlogger.info(\"processing latency:\" + latency.getProcessingNs());\nlogger.info(\"encoding latency:\" + latency.getEncodingNs());\n```\n\nSimilarly you can get the latency of a mutation request:\n\n```java\nAssigned assignedIds = dgraphClient.newTransaction().mutate(mu);\nLatency latency = assignedIds.getLatency();\n```\n\n## Development\n\n### Building the source\n\n**Warning**: The gradle build runs integration tests on a locally running Dgraph server. The tests\nwill remove all data from your Dgraph instance. So make sure that you don't have any important data\non your Dgraph instance.\n\n```sh\n./gradlew build\n```\n\nIf you have made changes to the `task.proto` file, this step will also regenerate the source files\ngenerated by Protocol Buffer tools.\n\n### Code Style\n\nWe use [google-java-format] to format the source code. If you run `./gradlew build`, you will be\nwarned if there is code that is not conformant. You can run `./gradlew goJF` to format the source\ncode, before committing it.\n\n[google-java-format]: https://github.com/google/google-java-format\n\n### Running unit tests\n\n**Warning**: This command will runs integration tests on a locally running Dgraph server. The tests\nwill remove all data from your Dgraph instance. So make sure that you don't have any important data\non your Dgraph instance.\n\nMake sure you have a Dgraph server running on localhost before you run this task.\n\n```sh\n./gradlew test\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhypermodeinc%2Fdgraph4j","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhypermodeinc%2Fdgraph4j","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhypermodeinc%2Fdgraph4j/lists"}