From cc16f05e342b377ac7757ed0e1dba1259f13fa27 Mon Sep 17 00:00:00 2001 From: Jim Anderson Date: Wed, 5 Feb 2025 17:19:47 -0600 Subject: [PATCH] docs: Update README for server-side batch check --- README.md | 116 ++++++++++++++++++++++++++++++++-- build.gradle | 8 +-- example/example1/build.gradle | 4 +- 3 files changed, 118 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index f4d7e92..0b259c8 100644 --- a/README.md +++ b/README.md @@ -601,14 +601,122 @@ var response = fgaClient.check(request, options).get(); ##### Batch Check -Run a set of [checks](#check). Batch Check will return `allowed: false` if it encounters an error, and will return the error in the body. -If 429s or 5xxs are encountered, the underlying check will retry up to 3 times before giving up. +Similar to [check](#check), but instead of checking a single user-object relationship, accepts a list of relationships to check. Requires OpenFGA version 1.8.0 or greater. + +[API Documentation](https://openfga.dev/api/service#/Relationship%20Queries/BatchCheck) -> Passing `ClientBatchCheckClientOptions` is optional. All fields of `ClientBatchCheckClientOptions` are optional. +> Passing `ClientBatchCheckOptions` is optional. All fields of `ClientBatchCheckOptions` are optional. ```java +var reequst = new ClientBatchCheckRequest().checks( + List.of( + new ClientBatchCheckItem() + .user("user:81684243-9356-4421-8fbf-a4f8d36aa31b") + .relation("viewer") + ._object("document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a") + .correlationId("cor-1") // optional, one will be generated for you if not provided + .contextualTuples(List.of( + new ClientTupleKey() + .user("user:81684243-9356-4421-8fbf-a4f8d36aa31b") + .relation("editor") + ._object("document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a") + )), + new ClientCheckRequest() + .user("user:81684243-9356-4421-8fbf-a4f8d36aa31b") + .relation("admin") + ._object("document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a"), + .correlationId("cor-2") // optional, one will be generated for you if not provided + .contextualTuples(List.of( + new ClientTupleKey() + .user("user:81684243-9356-4421-8fbf-a4f8d36aa31b") + .relation("editor") + ._object("document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a") + )), + new ClientCheckRequest() + .user("user:81684243-9356-4421-8fbf-a4f8d36aa31b") + .relation("creator") + ._object("document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a") + .correlationId("cor-3), // optional, one will be generated for you if not provided + new ClientCheckRequest() + .user("user:81684243-9356-4421-8fbf-a4f8d36aa31b") + .relation("deleter") + ._object("document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a") + .correlationId("cor-4") // optional, one will be generated for you if not provided + ) +); + +var options = new ClientBatchCheckOptions() + .additionalHeaders(Map.of("Some-Http-Header", "Some value")) + // You can rely on the model id set in the configuration or override it for this specific request + .authorizationModelId("01GXSA8YR785C4FYS3C0RTG7B1") + .maxParallelRequests(5); // Max number of requests to issue in parallel, defaults to 10 + .maxBatchSize(20); // Max number of batches to split the list of checks into, defaults to 50 + +var response = fgaClient.batchCheck(request, options).get(); + +/* +response.getResult() = [{ + allowed: false, + correlationId: "cor-1", + request: { + user: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", + relation: "viewer", + _object: "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", + correlationId: "cor-1", + contextualTuples: [{ + user: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", + relation: "editor", + _object: "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a" + }] + }, + }, + { + allowed: false, + correlationId: "cor-2", + request: { + user: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", + relation: "admin", + _object: "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", + correlationId: "cor-2", + contextualTuples: [{ + user: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", + relation: "editor", + _object: "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a" + }] + } + }, + { + allowed: false, + correlationId: "cor-3", + request: { + user: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", + relation: "creator", + _object: "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", + correlationId: "cor-3", + }, + error: + }, + { + allowed: true, + correlationId: "cor-4", + request: { + user: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", + relation: "deleter", + _object: "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", + correlationId: "cor-4", + } + }, +] +*/ +``` + +If you are using an OpenFGA version less than 1.8.0, you can use `clientBatchCheck`, +which calls `check` in parallel. It will return `allowed: false` if it encounters an error, and will return the error in the body. +If 429s or 5xxs are encountered, the underlying check will retry up to 3 times before giving up. + +``` var request = List.of( - new ClientCheckRequest() + new ClientBatchCheckItem() .user("user:81684243-9356-4421-8fbf-a4f8d36aa31b") .relation("viewer") ._object("document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a") diff --git a/build.gradle b/build.gradle index c26049a..4148c9d 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { // Quality id 'jacoco' id 'jvm-test-suite' - id 'com.diffplug.spotless' version '6.25.0' + id 'com.diffplug.spotless' version '7.0.2' // IDE id 'idea' @@ -66,7 +66,7 @@ dependencies { implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version" implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version" implementation "org.openapitools:jackson-databind-nullable:0.2.6" - implementation platform("io.opentelemetry:opentelemetry-bom:1.45.0") + implementation platform("io.opentelemetry:opentelemetry-bom:1.46.0") implementation "io.opentelemetry:opentelemetry-api" } @@ -78,9 +78,9 @@ testing { dependencies { implementation project() implementation "org.junit.jupiter:junit-jupiter:$junit_version" - implementation "org.mockito:mockito-core:5.14.2" + implementation "org.mockito:mockito-core:5.15.2" runtimeOnly "org.junit.platform:junit-platform-launcher" - implementation "org.wiremock:wiremock:3.10.0" + implementation "org.wiremock:wiremock:3.11.0" // This test-only dependency is convenient but not widely used. // Review project activity before updating the version here. diff --git a/example/example1/build.gradle b/example/example1/build.gradle index d4c6aa7..9ca41a6 100644 --- a/example/example1/build.gradle +++ b/example/example1/build.gradle @@ -1,7 +1,7 @@ plugins { id 'application' - id 'com.diffplug.spotless' version '6.25.0' - id 'org.jetbrains.kotlin.jvm' version '2.1.0' + id 'com.diffplug.spotless' version '7.0.2' + id 'org.jetbrains.kotlin.jvm' version '2.1.10' } application {