dotnet-sdk icon indicating copy to clipboard operation
dotnet-sdk copied to clipboard

feat: Implement server-side BatchCheck using /batch-check endpoint

Open daniel-jonathan opened this issue 3 months ago • 1 comments

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-check API 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() to ClientBatchCheck()
  • This method remains fully supported and is not deprecated
  • Makes individual parallel /check calls (useful for small numbers of checks)
  • Updated ListRelations() to use the renamed ClientBatchCheck() 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 MaxBatchSize property to IClientBatchCheckOptions and ClientBatchCheckOptions
  • Added MaxBatchSize property to ClientListRelationsOptions (implements IClientBatchCheckOptions)

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.

daniel-jonathan avatar Oct 30 '25 18:10 daniel-jonathan

[!IMPORTANT]

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in 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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot] avatar Oct 30 '25 18:10 coderabbitai[bot]