Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 26 additions & 98 deletions src/OpenFga.Sdk/Client/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

namespace OpenFga.Sdk.Client;

public class OpenFgaClient : IDisposable {
public class OpenFgaClient : IOpenFgaClient, IDisposable {
private readonly ClientConfiguration _configuration;
protected OpenFgaApi api;

Expand All @@ -31,17 +31,13 @@ public OpenFgaClient(
api = new OpenFgaApi(_configuration, httpClient);
}

/// <summary>
/// Store ID
/// </summary>
/// <inheritdoc />
public string? StoreId {
get => _configuration.StoreId;
set => _configuration.StoreId = value;
}

/// <summary>
/// Authorization Model ID
/// </summary>
/// <inheritdoc />
public string? AuthorizationModelId {
get => _configuration.AuthorizationModelId;
set => _configuration.AuthorizationModelId = value;
Expand Down Expand Up @@ -226,56 +222,42 @@ private static WriteRequestDeletes.OnMissingEnum MapOnMissingDeletes(OnMissingDe
* Stores *
**********/

/**
* ListStores - Get a paginated list of stores.
*/
/// <inheritdoc />
public async Task<ListStoresResponse> ListStores(IClientListStoresRequest? body, IClientListStoresOptions? options = default,
CancellationToken cancellationToken = default) =>
await api.ListStores(options?.PageSize, options?.ContinuationToken, body?.Name, options, cancellationToken);

/**
* CreateStore - Initialize a store
*/
/// <inheritdoc />
public async Task<CreateStoreResponse> CreateStore(ClientCreateStoreRequest body,
IClientRequestOptions? options = default,
CancellationToken cancellationToken = default) =>
await api.CreateStore(body, options, cancellationToken);

/**
* GetStore - Get information about the current store
*/
/// <inheritdoc />
public async Task<GetStoreResponse> GetStore(IClientRequestOptionsWithStoreId? options = default, CancellationToken cancellationToken = default) =>
await api.GetStore(GetStoreId(options), options, cancellationToken);

/**
* DeleteStore - Delete a store
*/
/// <inheritdoc />
public async Task DeleteStore(IClientRequestOptionsWithStoreId? options = default, CancellationToken cancellationToken = default) =>
await api.DeleteStore(GetStoreId(options), options, cancellationToken);

/************************
* Authorization Models *
************************/

/**
* ReadAuthorizationModels - Read all authorization models
*/
/// <inheritdoc />
public async Task<ReadAuthorizationModelsResponse> ReadAuthorizationModels(
IClientReadAuthorizationModelsOptions? options = default,
CancellationToken cancellationToken = default) =>
await api.ReadAuthorizationModels(GetStoreId(options), options?.PageSize, options?.ContinuationToken, options, cancellationToken);

/**
* WriteAuthorizationModel - Create a new version of the authorization model
*/
/// <inheritdoc />
public async Task<WriteAuthorizationModelResponse> WriteAuthorizationModel(ClientWriteAuthorizationModelRequest body,
IClientRequestOptionsWithStoreId? options = default,
CancellationToken cancellationToken = default) =>
await api.WriteAuthorizationModel(GetStoreId(options), body, options, cancellationToken);

/**
* ReadAuthorizationModel - Read the current authorization model
*/
/// <inheritdoc />
public async Task<ReadAuthorizationModelResponse> ReadAuthorizationModel(
IClientReadAuthorizationModelOptions? options = default,
CancellationToken cancellationToken = default) {
Expand All @@ -287,9 +269,7 @@ public async Task<ReadAuthorizationModelResponse> ReadAuthorizationModel(
return await api.ReadAuthorizationModel(GetStoreId(options), authorizationModelId, options, cancellationToken);
}

/**
* ReadLatestAuthorizationModel - Read the latest authorization model for the current store
*/
/// <inheritdoc />
public async Task<ReadAuthorizationModelResponse?> ReadLatestAuthorizationModel(
IClientRequestOptionsWithAuthZModelId? options = default,
CancellationToken cancellationToken = default) {
Expand All @@ -307,17 +287,13 @@ public async Task<ReadAuthorizationModelResponse> ReadAuthorizationModel(
* Relationship Tuples *
***********************/

/**
* Read Changes - Read the list of historical relationship tuple writes and deletes
*/
/// <inheritdoc />
public async Task<ReadChangesResponse> ReadChanges(ClientReadChangesRequest? body = default,
ClientReadChangesOptions? options = default,
CancellationToken cancellationToken = default) =>
await api.ReadChanges(GetStoreId(options), body?.Type, options?.PageSize, options?.ContinuationToken, body?.StartTime, options, cancellationToken);

/**
* Read - Read tuples previously written to the store (does not evaluate)
*/
/// <inheritdoc />
public async Task<ReadResponse> Read(ClientReadRequest? body = default, IClientReadOptions? options = default,
CancellationToken cancellationToken = default) {
ReadRequestTupleKey tupleKey = null;
Expand All @@ -334,9 +310,7 @@ public async Task<ReadResponse> Read(ClientReadRequest? body = default, IClientR
}, options, cancellationToken);
}

/**
* Write - Create or delete relationship tuples
*/
/// <inheritdoc />
public async Task<ClientWriteResponse> Write(ClientWriteRequest body, IClientWriteOptions? options = default,
CancellationToken cancellationToken = default) {
var maxPerChunk =
Expand Down Expand Up @@ -408,16 +382,12 @@ await ProcessWriteChunksAsync(
return new ClientWriteResponse { Writes = writeResponses.ToList(), Deletes = deleteResponses.ToList() };
}

/**
* WriteTuples - Utility method to write tuples, wraps Write
*/
/// <inheritdoc />
public async Task<ClientWriteResponse> WriteTuples(List<ClientTupleKey> body, IClientWriteOptions? options = default,
CancellationToken cancellationToken = default) =>
await Write(new ClientWriteRequest { Writes = body }, options, cancellationToken);

/**
* DeleteTuples - Utility method to delete tuples, wraps Write
*/
/// <inheritdoc />
public async Task<ClientWriteResponse> DeleteTuples(List<ClientTupleKeyWithoutCondition> body, IClientWriteOptions? options = default,
CancellationToken cancellationToken = default) =>
await Write(new ClientWriteRequest { Deletes = body }, options, cancellationToken);
Expand All @@ -426,9 +396,7 @@ public async Task<ClientWriteResponse> DeleteTuples(List<ClientTupleKeyWithoutCo
* Relationship Queries *
************************/

/**
* Check - Check if a user has a particular relation with an object (evaluates)
*/
/// <inheritdoc />
public async Task<CheckResponse> Check(IClientCheckRequest body,
IClientCheckOptions? options = default,
CancellationToken cancellationToken = default) =>
Expand All @@ -445,20 +413,8 @@ await api.Check(
AuthorizationModelId = GetAuthorizationModelId(options),
Consistency = options?.Consistency,
}, options, cancellationToken);

/// <summary>
/// ClientBatchCheck - Run a set of checks by executing individual /check calls in parallel (evaluates)
/// </summary>
/// <remarks>
/// This method makes individual check API calls in parallel on the client side.
/// Best for small batches (< 10 checks) when you need specific control over individual requests.
///
/// For larger batches or to use the server-side /batch-check endpoint, use the BatchCheck method instead.
/// </remarks>
/// <param name="body">List of check requests to execute</param>
/// <param name="options">Optional configuration including MaxParallelRequests</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>ClientBatchCheckClientResponse with list of individual check responses</returns>

/// <inheritdoc />
public async Task<ClientBatchCheckClientResponse> ClientBatchCheck(List<ClientCheckRequest> body,
IClientBatchCheckClientOptions? options = default,
CancellationToken cancellationToken = default) {
Expand All @@ -471,23 +427,7 @@ public async Task<ClientBatchCheckClientResponse> ClientBatchCheck(List<ClientCh
return new ClientBatchCheckClientResponse { Responses = responses.ToList() };
}

/// <summary>
/// BatchCheck - Run a set of checks using the server-side /batch-check endpoint (evaluates)
/// </summary>
/// <remarks>
/// This method uses the server-side batch check API endpoint. It automatically:
/// - Generates correlation IDs for checks that don't have one
/// - Validates that correlation IDs are unique
/// - Chunks requests based on maxBatchSize (default: 50)
/// - Executes batches in parallel based on maxParallelRequests (default: 10)
///
/// Best for large batches (≥ 10 checks) as it leverages server-side optimizations.
/// For small batches with specific control needs, use ClientBatchCheck instead.
/// </remarks>
/// <param name="body">The batch check request with a list of checks</param>
/// <param name="options">Optional configuration including MaxBatchSize and MaxParallelRequests</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>ClientBatchCheckResponse with correlation ID mapping to results</returns>
/// <inheritdoc />
public async Task<ClientBatchCheckResponse> BatchCheck(ClientBatchCheckRequest body,
IClientBatchCheckOptions? options = default,
CancellationToken cancellationToken = default) {
Expand Down Expand Up @@ -620,9 +560,7 @@ private async Task ProcessBatchAsync(
}
}

/**
* Expand - Expands the relationships in userset tree format (evaluates)
*/
/// <inheritdoc />
public async Task<ExpandResponse> Expand(IClientExpandRequest body,
IClientExpandOptions? options = default,
CancellationToken cancellationToken = default) =>
Expand All @@ -639,9 +577,7 @@ await api.Expand(
Consistency = options?.Consistency
}, options, cancellationToken);

/**
* ListObjects - List the objects of a particular type that the user has a certain relation to (evaluates)
*/
/// <inheritdoc />
public async Task<ListObjectsResponse> ListObjects(IClientListObjectsRequest body,
IClientListObjectsOptions? options = default,
CancellationToken cancellationToken = default) =>
Expand All @@ -660,9 +596,7 @@ public async Task<ListObjectsResponse> ListObjects(IClientListObjectsRequest bod
}, options, cancellationToken);


/**
* ListRelations - List all the relations a user has with an object (evaluates)
*/
/// <inheritdoc />
public async Task<ListRelationsResponse> ListRelations(IClientListRelationsRequest body,
IClientListRelationsOptions? options = default,
CancellationToken cancellationToken = default) {
Expand Down Expand Up @@ -699,9 +633,7 @@ public async Task<ListRelationsResponse> ListRelations(IClientListRelationsReque
return responses;
}

/**
* ListUsers - List all users of the given type that the object has a relation with (evaluates)
*/
/// <inheritdoc />
public async Task<ListUsersResponse> ListUsers(IClientListUsersRequest body,
IClientListUsersOptions? options = default,
CancellationToken cancellationToken = default) =>
Expand All @@ -719,9 +651,7 @@ public async Task<ListUsersResponse> ListUsers(IClientListUsersRequest body,
* Assertions *
**************/

/**
* ReadAssertions - Read assertions for a particular authorization model
*/
/// <inheritdoc />
public async Task<ReadAssertionsResponse> ReadAssertions(IClientReadAssertionsOptions? options = default,
CancellationToken cancellationToken = default) {
var authorizationModelId = GetAuthorizationModelId(options);
Expand All @@ -732,9 +662,7 @@ public async Task<ReadAssertionsResponse> ReadAssertions(IClientReadAssertionsOp
return await api.ReadAssertions(GetStoreId(options), authorizationModelId, options, cancellationToken);
}

/**
* WriteAssertions - Updates assertions for a particular authorization model
*/
/// <inheritdoc />
public async Task WriteAssertions(List<ClientAssertion> body,
IClientWriteAssertionsOptions? options = default,
CancellationToken cancellationToken = default) {
Expand Down
Loading
Loading