feat: Implement server-side BatchCheck using /batch-check endpoint
Implement Server-Side BatchCheck Using /batch-check Endpoint
Fixes #94
Summary
This PR implements server-side batch check functionality using the /batch-check API endpoint. Previously, the SDK performed batch checks by making individual parallel /check API calls. The new implementation uses the server-side batching endpoint, significantly reducing network overhead for checking multiple authorization relationships.
Changes
New Server-Side BatchCheck Method
- Added
BatchCheck()method that uses the/batch-checkAPI endpoint - Automatically generates UUID correlation IDs for checks that don't provide them
- Validates that correlation IDs are unique within a batch
- Chunks large requests based on
MaxBatchSize(default: 50 checks per batch) - Executes batches in parallel based on
MaxParallelRequests(default: 10 concurrent batches) - Returns empty result for empty check requests (matches JavaScript SDK behavior)
- Implements fail-fast error handling
Renamed Existing Method
- Renamed existing
BatchCheck()toClientBatchCheck() - This method remains fully supported and is not deprecated
- Makes individual parallel
/checkcalls (useful for small numbers of checks) - Updated
ListRelations()to use the renamedClientBatchCheck()method
New Models
Client Models (User-Facing API):
-
ClientBatchCheckItem- User-friendly check item with simple properties -
ClientBatchCheckRequest- Request container with list of checks -
ClientBatchCheckSingleResponse- Individual check result with correlation ID -
ClientBatchCheckResponse- Response container with list of results
Utilities:
-
ClientUtils.GenerateCorrelationId()- Generates UUID correlation IDs -
ClientUtils.ChunkList<T>()- Splits lists into batches -
ClientUtils.TransformToBatchCheckItem()- Transforms client model to API model
Updated Options
- Added
MaxBatchSizeproperty toIClientBatchCheckOptionsandClientBatchCheckOptions - Added
MaxBatchSizeproperty toClientListRelationsOptions(implementsIClientBatchCheckOptions)
Naming Conventions
All naming follows the JavaScript SDK patterns for cross-SDK consistency:
| JavaScript SDK | .NET SDK | Purpose |
|---|---|---|
ClientBatchCheckItem |
ClientBatchCheckItem |
Individual check item |
ClientBatchCheckRequest |
ClientBatchCheckRequest |
Request container |
ClientBatchCheckSingleResponse |
ClientBatchCheckSingleResponse |
Individual result |
ClientBatchCheckResponse |
ClientBatchCheckResponse |
Response container |
maxBatchSize |
MaxBatchSize |
Batch size configuration |
correlationId |
CorrelationId |
Correlation identifier |
The Client* prefix pattern distinguishes user-facing models from auto-generated API models (BatchCheckItem, BatchCheckRequest, etc.).
Framework Support
The implementation supports all existing target frameworks with conditional compilation:
- .NET Standard 2.0 (supports .NET 6, 7, .NET Core 2.0+, .NET Framework 4.6.1+)
- .NET Framework 4.8
- .NET 8.0
- .NET 9.0
Uses Parallel.ForEachAsync for .NET 6+ and SemaphoreSlim for older frameworks.
Testing
- Added 18 unit tests covering models, utilities, and transformation logic
- All tests pass on all target frameworks
- Integration tested against live OpenFGA server
- Updated existing tests to use renamed
ClientBatchCheck()method
Breaking Changes
None. The renamed ClientBatchCheck() method maintains the same signature and behavior. Existing code will continue to work without modification.
Example Usage
var response = await fgaClient.BatchCheck(new ClientBatchCheckRequest {
Checks = new List<ClientBatchCheckItem> {
new() {
User = "user:anne",
Relation = "reader",
Object = "document:roadmap",
// CorrelationId is optional - auto-generated if not provided
},
new() {
User = "user:bob",
Relation = "writer",
Object = "document:budget",
CorrelationId = "custom-correlation-id-123"
}
}
});
// Results are mapped back using correlation IDs
foreach (var result in response.Result) {
Console.WriteLine($"CorrelationId: {result.CorrelationId}, Allowed: {result.Allowed}");
}
References
- Issue: https://github.com/openfga/dotnet-sdk/issues/94
- API Documentation: https://openfga.dev/api/service#/Relationship%20Queries/BatchCheck
- JavaScript SDK implementation:
js-sdk/client.ts(lines 684-759)
Summary by CodeRabbit
-
New Features
- Added dual batch checking capabilities: client-side batch checks for direct verification and server-side batch checks with correlation ID tracking for request identification.
- Introduced configurable batch size and parallel request limits to optimize bulk operation performance.
- Batch operations now support correlation IDs for enhanced request tracking and visibility.
[!IMPORTANT]
Review skipped
Auto incremental reviews are disabled on this repository.
Please check the settings in the CodeRabbit UI or the
.coderabbit.yamlfile in this repository. To trigger a single review, invoke the@coderabbitai reviewcommand.You can disable this status message by setting the
reviews.review_statustofalsein the CodeRabbit configuration file.
Walkthrough
This PR introduces a new server-side batch check API (BatchCheck) alongside refactored client-side batch functionality (ClientBatchCheck), including new model classes, correlation ID tracking, chunking utilities, configuration options, and comprehensive test coverage.
Changes
| Cohort / File(s) | Summary |
|---|---|
Example and Project Configuration example/Example1/Example1.cs, example/Example1/Example1.csproj |
Demonstrates client-side and server-side batch check APIs; switches project from NuGet package reference to local project reference for OpenFga.Sdk |
Client API Implementation src/OpenFga.Sdk/Client/Client.cs |
Renames BatchCheck(List<ClientCheckRequest>) to ClientBatchCheck(List<ClientCheckRequest>) returning ClientBatchCheckClientResponse; adds new BatchCheck(ClientBatchCheckRequest) for server-side batching with correlation IDs, chunking, and parallel execution; updates internal ListRelations to use renamed method |
Batch Check Data Models src/OpenFga.Sdk/Client/Model/ClientBatchCheckRequest.cs |
Introduces ClientBatchCheckItem, ClientBatchCheckRequest, ClientBatchCheckSingleResponse, and ClientBatchCheckResponse types with properties for batch checks, correlation IDs, and results |
Batch Check Configuration src/OpenFga.Sdk/Client/Model/ClientBatchCheckOptions.cs, ClientListRelationsOptions.cs |
Adds MaxBatchSize property to IClientBatchCheckOptions and ClientBatchCheckOptions; adds MaxBatchSize to ClientListRelationsOptions |
Utility Functions src/OpenFga.Sdk/Client/Utils/ClientUtils.cs |
Introduces static utility class with GenerateCorrelationId(), ChunkArray<T>(), ChunkList<T>(), and TransformToBatchCheckItem() for ID generation, chunking, and batch item transformation |
Test Coverage src/OpenFga.Sdk.Test/Client/ClientBatchCheckTests.cs, OpenFgaClientTests.cs |
Adds comprehensive test suite for batch check models, utilities, and options; updates existing test to use renamed ClientBatchCheck method |
Sequence Diagram(s)
sequenceDiagram
participant Client as OpenFgaClient
participant Utils as ClientUtils
participant API as OpenFga API
Note over Client: ClientBatchCheck<br/>(client-side)
Client->>Utils: List<ClientCheckRequest>
Utils-->>Client: ClientBatchCheckClientResponse
Note over Client: BatchCheck<br/>(server-side)
Client->>Utils: ClientBatchCheckRequest<br/>(List<ClientBatchCheckItem>)
Utils->>Utils: For each item:<br/>GenerateCorrelationId()
Utils->>Utils: ChunkList() by MaxBatchSize
par Parallel Execution
Utils->>API: Batch 1<br/>(with CorrelationIds)
Utils->>API: Batch 2<br/>(with CorrelationIds)
Utils->>API: Batch N<br/>(with CorrelationIds)
end
API-->>Utils: BatchCheckItem results
Utils->>Utils: Map responses back<br/>using CorrelationId
Utils-->>Client: ClientBatchCheckResponse<br/>(List<ClientBatchCheckSingleResponse>)
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~25 minutes
- Client.cs implementation: Review batching logic, correlation ID assignment, chunking, parallel execution via semaphore, and response mapping—requires verification of error handling and concurrency patterns
- New model classes: Review equality/hash code implementations, validation stubs, and serialization attributes across four new types
- Utility functions: Validate chunking logic edge cases (empty inputs, chunk sizes), correlation ID uniqueness, and batch item transformation
- Test coverage: Verify comprehensive coverage of new utilities and models, null/invalid input handling
Possibly related PRs
- #128: Modifies batch-check and list-relations options interfaces/implementations alongside this PR's option class enhancements
- #122: Addresses batch-checking API surface and implementation that this PR builds upon
- #133: Complements this PR by adding Headers properties to the same option classes being extended here
Suggested labels
enhancement
Suggested reviewers
- rhamzeh
- evansims
- ewanharris
Pre-merge checks and finishing touches
❌ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | ⚠️ Warning | Docstring coverage is 48.08% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
✅ Passed checks (4 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title Check | ✅ Passed | The pull request title "feat: Implement server-side BatchCheck using /batch-check endpoint" directly and clearly describes the main objective of this changeset. The title is concise, specific, and accurately reflects the primary feature being implemented—moving from client-side parallel /check calls to using the server-side /batch-check endpoint. A reviewer scanning the history would immediately understand the core change introduced by this PR. |
| Linked Issues Check | ✅ Passed | The PR fully addresses the coding requirements from linked issue #94. The implementation introduces a new BatchCheck() method that uses the /batch-check endpoint with auto-generated correlation IDs, batching by MaxBatchSize (default 50), and parallel execution by MaxParallelRequests (default 10). The old batch check behavior is preserved under the new name ClientBatchCheck(), and ListRelations() is properly updated to use it. Supporting infrastructure including ClientBatchCheckRequest, ClientBatchCheckResponse, ClientUtils utilities (GenerateCorrelationId, ChunkList, TransformToBatchCheckItem), and MaxBatchSize configuration options have been added. These changes achieve the goal of reducing network calls by leveraging the server-side endpoint instead of making many parallel individual /check calls. |
| Out of Scope Changes Check | ✅ Passed | All code changes are directly scoped to the server-side batch check implementation requirement. The PR modifies core client code (Client.cs) to implement and rename the batch check methods, introduces necessary model types (ClientBatchCheckRequest, ClientBatchCheckResponse, etc.) and utilities (ClientUtils for correlation IDs and chunking), updates batch check options with MaxBatchSize support, adds comprehensive unit tests, updates existing tests to reflect the renamed API, and provides example usage demonstrating the new functionality. The Example1.csproj change from NuGet package reference to local project reference is a standard development/testing setup change for validating SDK changes before publication and is not considered out of scope. |
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.