feat(dotnet-sdk): per-request custom headers#640
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughAdds per-request custom header support across the .NET client templates: new Headers properties on request option classes, header validation in ClientConfiguration, extraction in Client, propagation through generated API methods, and merged header handling in ApiClient. Updates tests to cover validation, precedence, and propagation across operations. Changes
Sequence Diagram(s)sequenceDiagram
participant App as SDK Consumer
participant Client as OpenFGA Client
participant GenApi as Generated API Method
participant ApiClient as ApiClient.SendRequestAsync
participant Auth as OAuth Provider
participant Server as OpenFGA Service
App->>Client: Call Operation(options with Headers)
Client->>Client: ExtractHeaders(options)<br/>(ValidateHeaders)
Client->>GenApi: Operation(..., headers, cancellationToken)
GenApi->>ApiClient: SendRequestAsync(..., perRequestHeaders=headers)
alt OAuth configured
ApiClient->>Auth: Get access token (if needed)
Auth-->>ApiClient: oauthToken
else No OAuth
ApiClient-->>ApiClient: oauthToken = null
end
ApiClient->>ApiClient: BuildHeaders(oauthToken, perRequestHeaders)
ApiClient->>Server: HTTP request with merged headers
Server-->>ApiClient: Response
ApiClient-->>GenApi: Response
GenApi-->>Client: Result
Client-->>App: Result
note over ApiClient: Per-request headers take precedence over auth/default.
sequenceDiagram
participant App as SDK Consumer
participant Client as OpenFGA Client
App->>Client: Call with invalid Headers<br/>(e.g., reserved name or CR/LF)
Client->>Client: ExtractHeaders -> ValidateHeaders
Client-->>App: Throw ArgumentException
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
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 |
|
I will have a follow-up PR with documentation coverage for this feature. |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
config/clients/dotnet/template/Client/Model/ClientReadAuthorizaionModelOptions.mustache (1)
1-23: Critical: Filename typo - "Authorizaion" should be "Authorization".The filename
ClientReadAuthorizaionModelOptions.mustachecontains a typo ("Authorizaion"), but the class name inside is correctly spelledClientReadAuthorizationModelOptions("Authorization"). This mismatch could cause template generation issues, confusion, or build problems.Rename the file from:
ClientReadAuthorizaionModelOptions.mustacheto:
ClientReadAuthorizationModelOptions.mustache
♻️ Duplicate comments (4)
config/clients/dotnet/template/Client/Model/ClientListObjectsOptions.mustache (1)
20-22: Same interface inheritance concern as ClientExpandOptions.Verify that the base interface defines the Headers property to ensure the
/// <inheritdoc />comment is valid.config/clients/dotnet/template/Client/Model/ClientReadChangesOptions.mustache (1)
23-25: Same interface inheritance verification needed.Verify that the base interface defines the Headers property for the
/// <inheritdoc />comment to be valid.config/clients/dotnet/template/Client/Model/ClientReadAssertionsOptions.mustache (1)
20-22: Same interface inheritance verification needed.Verify that the base interface defines the Headers property for the
/// <inheritdoc />comment to be valid.config/clients/dotnet/template/Client/Model/ClientListRelationsOptions.mustache (1)
25-27: Same interface inheritance verification needed.Verify that the base interface defines the Headers property for the
/// <inheritdoc />comment to be valid.
🧹 Nitpick comments (2)
config/clients/dotnet/template/Client/ClientConfiguration.mustache (1)
110-140: Solid header validation with good security practices.The validation logic correctly handles:
- Empty/null key prevention
- Null value detection
- CR/LF injection prevention (important security measure)
- Reserved header protection with clear error messages
Consider whether empty string header values (non-null but empty) should also be rejected for clarity:
if (header.Value == null) { throw new ArgumentException($"Header '{header.Key}' has a null value. Header values cannot be null.", paramName); } + +if (string.IsNullOrWhiteSpace(header.Value)) { + throw new ArgumentException($"Header '{header.Key}' has an empty or whitespace-only value. Header values should contain meaningful data.", paramName); +}config/clients/dotnet/template/api.mustache (1)
48-48: Minor: Unnecessary explicit empty dictionary initialization.The initialization
new Dictionary<string, string> { }can be simplified tonew Dictionary<string, string>()or use implicit initialization. However, this is a very minor style preference.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (22)
config/clients/dotnet/template/Client/Client.mustache(25 hunks)config/clients/dotnet/template/Client/ClientConfiguration.mustache(4 hunks)config/clients/dotnet/template/Client/Model/ClientBatchCheckOptions.mustache(2 hunks)config/clients/dotnet/template/Client/Model/ClientCheckOptions.mustache(2 hunks)config/clients/dotnet/template/Client/Model/ClientConsistencyOptions.mustache(2 hunks)config/clients/dotnet/template/Client/Model/ClientCreateStoreOptions.mustache(1 hunks)config/clients/dotnet/template/Client/Model/ClientExpandOptions.mustache(2 hunks)config/clients/dotnet/template/Client/Model/ClientListObjectsOptions.mustache(2 hunks)config/clients/dotnet/template/Client/Model/ClientListRelationsOptions.mustache(2 hunks)config/clients/dotnet/template/Client/Model/ClientListStoresOptions.mustache(2 hunks)config/clients/dotnet/template/Client/Model/ClientListUsersOptions.mustache(2 hunks)config/clients/dotnet/template/Client/Model/ClientReadAssertionsOptions.mustache(2 hunks)config/clients/dotnet/template/Client/Model/ClientReadAuthorizaionModelOptions.mustache(2 hunks)config/clients/dotnet/template/Client/Model/ClientReadAuthorizaionModelsOptions.mustache(2 hunks)config/clients/dotnet/template/Client/Model/ClientReadChangesOptions.mustache(2 hunks)config/clients/dotnet/template/Client/Model/ClientReadOptions.mustache(2 hunks)config/clients/dotnet/template/Client/Model/ClientRequestOptions.mustache(1 hunks)config/clients/dotnet/template/Client/Model/ClientWriteAssertionsOptions.mustache(2 hunks)config/clients/dotnet/template/Client/Model/ClientWriteOptions.mustache(2 hunks)config/clients/dotnet/template/Client_ApiClient.mustache(4 hunks)config/clients/dotnet/template/OpenFgaClientTests.mustache(6 hunks)config/clients/dotnet/template/api.mustache(3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
config/**/*.mustache
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Validate mustache syntax and variable references across all template files, including CHANGELOG.md.mustache
Files:
config/clients/dotnet/template/Client/Model/ClientReadAssertionsOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientReadChangesOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientExpandOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientRequestOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientReadAuthorizaionModelsOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientListUsersOptions.mustacheconfig/clients/dotnet/template/api.mustacheconfig/clients/dotnet/template/Client/Model/ClientWriteOptions.mustacheconfig/clients/dotnet/template/Client/ClientConfiguration.mustacheconfig/clients/dotnet/template/Client/Model/ClientBatchCheckOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientListObjectsOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientReadAuthorizaionModelOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientListStoresOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientReadOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientCreateStoreOptions.mustacheconfig/clients/dotnet/template/Client_ApiClient.mustacheconfig/clients/dotnet/template/Client/Model/ClientWriteAssertionsOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientListRelationsOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientCheckOptions.mustacheconfig/clients/dotnet/template/Client/Client.mustacheconfig/clients/dotnet/template/OpenFgaClientTests.mustacheconfig/clients/dotnet/template/Client/Model/ClientConsistencyOptions.mustache
config/**/*.{json,mustache}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Never hardcode API keys or credentials in configuration or template files
Files:
config/clients/dotnet/template/Client/Model/ClientReadAssertionsOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientReadChangesOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientExpandOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientRequestOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientReadAuthorizaionModelsOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientListUsersOptions.mustacheconfig/clients/dotnet/template/api.mustacheconfig/clients/dotnet/template/Client/Model/ClientWriteOptions.mustacheconfig/clients/dotnet/template/Client/ClientConfiguration.mustacheconfig/clients/dotnet/template/Client/Model/ClientBatchCheckOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientListObjectsOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientReadAuthorizaionModelOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientListStoresOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientReadOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientCreateStoreOptions.mustacheconfig/clients/dotnet/template/Client_ApiClient.mustacheconfig/clients/dotnet/template/Client/Model/ClientWriteAssertionsOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientListRelationsOptions.mustacheconfig/clients/dotnet/template/Client/Model/ClientCheckOptions.mustacheconfig/clients/dotnet/template/Client/Client.mustacheconfig/clients/dotnet/template/OpenFgaClientTests.mustacheconfig/clients/dotnet/template/Client/Model/ClientConsistencyOptions.mustache
🪛 Gitleaks (8.28.0)
config/clients/dotnet/template/OpenFgaClientTests.mustache
[high] 2373-2373: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build-and-test-java-sdk
- GitHub Check: build-and-test-dotnet-sdk
- GitHub Check: build-and-test-go-sdk
🔇 Additional comments (40)
config/clients/dotnet/template/Client/Model/ClientReadAuthorizaionModelOptions.mustache (1)
3-3: LGTM! Headers property correctly added.The addition of the
System.Collections.Genericusing directive and theHeadersproperty follows the consistent pattern established across all option model templates in this PR. Theinheritdoccomment is appropriate sinceHeadersis defined in the parentIClientRequestOptionsinterface (transitively inherited viaIClientRequestOptionsWithStoreId).Also applies to: 20-22
config/clients/dotnet/template/Client/Model/ClientListUsersOptions.mustache (2)
3-4: LGTM! Using directives are correctly updated.The template-driven namespace
{{packageName}}.Modeland the addition ofSystem.Collections.GenericforIDictionarysupport are appropriate for the new Headers property.
20-22: LGTM! Headers property correctly added.The
IDictionary<string, string>?type is appropriate for custom headers, and the nullable annotation allows optional per-request headers. The<inheritdoc />comment correctly indicates that the property is inherited from a parent interface in the hierarchy, consistent with the pattern used for other properties in this class.config/clients/dotnet/template/Client/Model/ClientListStoresOptions.mustache (1)
1-27: LGTM! Implementation correctly follows the PR pattern.The changes properly add per-request header support to
ClientListStoresOptions:
- The
using System.Collections.Generic;directive is correctly added for theIDictionarytype- The nullable
Headersproperty appropriately implements the interface contract fromClientRequestOptions- Mustache template syntax is valid
- No hardcoded credentials present
The implementation is consistent with the broader PR changes described in the objectives and AI summary.
config/clients/dotnet/template/Client/Model/ClientWriteOptions.mustache (2)
3-4: LGTM!The using directive is correctly added to support the
IDictionary<string, string>type used in the Headers property.
59-61: Correctly implement Headers property TheIClientRequestOptionsinterface (in ClientRequestOptions.mustache) declaresIDictionary<string, string>? Headers { get; set; }, so<inheritdoc />is valid here.config/clients/dotnet/template/Client/Model/ClientReadOptions.mustache (3)
3-4: LGTM: Improved template consistency.The change from hardcoded
using OpenFga.Sdk.Modeltousing {{packageName}}.Modelaligns with the templated namespace pattern used elsewhere (line 6). The addition ofusing System.Collections.Generic;is necessary for the newIDictionary<string, string>Headers property.
26-27: LGTM: Minor formatting adjustment.The formatting change to the Consistency property is consistent with the overall code style.
28-29: Inheritdoc valid: Headers declared in base interface
TheHeadersproperty is defined in theClientRequestOptionsinterface (extended byIClientRequestOptionsWithStoreId), so the<inheritdoc />onClientReadOptions.Headersis correct.config/clients/dotnet/template/Client/Model/ClientConsistencyOptions.mustache (1)
3-3: LGTM!The namespace import correctly uses the
{{packageName}}template variable for consistency with the broader template structure.config/clients/dotnet/template/Client/Model/ClientReadAuthorizaionModelsOptions.mustache (2)
24-25: LGTM!The Headers property addition follows the established pattern across all option classes and correctly implements the nullable IDictionary type.
3-4: Verify 'Authorization' spelling in template filenames
The typo "Authorizaion" appears in two config/clients/dotnet template files; if pre-existing, file a separate issue to rename them for consistency.config/clients/dotnet/template/Client/Model/ClientCreateStoreOptions.mustache (1)
3-4: LGTM!The addition of the
Headersproperty and required using directive follows the consistent pattern established across all option classes.Also applies to: 10-11
config/clients/dotnet/template/Client/Model/ClientWriteAssertionsOptions.mustache (1)
3-4: LGTM!The Headers property implementation is consistent with other option classes and correctly uses
/// <inheritdoc />for documentation.Also applies to: 22-23
config/clients/dotnet/template/Client/ClientConfiguration.mustache (2)
3-4: LGTM!The integration of header validation into
EnsureValid()ensures that invalid default headers are caught early during configuration initialization. The updated XML documentation correctly documents the new exception type.Also applies to: 63-63, 76-77
95-102: LGTM!The reserved headers list appropriately protects critical HTTP headers from being overridden. The explicit note about User-Agent exclusion is helpful, as it allows SDK users to customize the user agent while preventing override of authentication and content-related headers.
config/clients/dotnet/template/Client/Model/ClientCheckOptions.mustache (1)
3-4: LGTM!The namespace import correctly uses the template variable, and the Headers property implementation is consistent with the pattern across all option classes.
Also applies to: 21-22
config/clients/dotnet/template/Client/Model/ClientRequestOptions.mustache (1)
3-4: LGTM! Clear documentation of merge semantics.The base interface definition is well-documented with clear precedence rules: per-request headers override default headers when keys conflict. This establishes the contract that all implementing classes follow.
Also applies to: 11-16
config/clients/dotnet/template/Client/Model/ClientBatchCheckOptions.mustache (1)
3-4: LGTM!Consistent implementation of the Headers property following the established pattern. The namespace import correctly uses the template variable.
Also applies to: 30-31
config/clients/dotnet/template/Client/Model/ClientExpandOptions.mustache (2)
3-4: LGTM! Clean template updates.The using directives are correctly templated and System.Collections.Generic is properly added to support the new Headers property.
20-22: No action — base interface already defines Headers.
ClientRequestOptions declares IDictionary<string, string>? Headers (config/clients/dotnet/template/Client/Model/ClientRequestOptions.mustache); inheritdoc is correct.config/clients/dotnet/template/Client/Model/ClientListObjectsOptions.mustache (1)
3-4: LGTM! Consistent with other option models.The using directives follow the same pattern as other updated option models.
config/clients/dotnet/template/api.mustache (3)
3-5: LGTM! Necessary using directives added.The new using directives support the updated API method signatures and exception handling.
37-37: Clean API surface updates for header support.The headers parameter is correctly positioned before
cancellationTokenand properly documented. The nullable type with default null allows for optional header specification.Also applies to: 41-41, 47-47
91-91: LGTM! Headers properly propagated to SendRequestAsync.The headers parameter is correctly passed through to the underlying API client method.
config/clients/dotnet/template/Client_ApiClient.mustache (3)
65-72: LGTM! Consistent parameter additions.The
perRequestHeadersparameter is consistently added to both SendRequestAsync overloads with appropriate documentation.Also applies to: 104-109
75-85: Clean refactoring to support header merging.The OAuth token is now stored in a variable and passed to BuildHeaders, which enables proper merging of OAuth and per-request headers. This is a good separation of concerns.
Also applies to: 112-122
175-195: Ensure reserved headers (e.g., Authorization) cannot be overridden by per-request headers
Confirm that ClientConfiguration.ValidateHeaders (invoked in Client.mustache line 65) enforces blocking or removing reserved headers before BuildHeaders merges them.config/clients/dotnet/template/Client/Model/ClientReadChangesOptions.mustache (1)
3-4: LGTM! Consistent pattern.config/clients/dotnet/template/Client/Model/ClientReadAssertionsOptions.mustache (1)
3-4: LGTM! Consistent pattern.config/clients/dotnet/template/Client/Model/ClientListRelationsOptions.mustache (1)
3-4: LGTM! Consistent pattern.config/clients/dotnet/template/Client/Client.mustache (3)
57-67: LGTM! Clean helper method for header extraction and validation.The ExtractHeaders method provides a centralized way to extract and validate headers from options objects. The cast to ClientRequestOptions interface is appropriate since all option classes implement it (or should, per the
/// <inheritdoc />comments).
236-236: LGTM! Consistent header propagation across all API operations.The ExtractHeaders helper is consistently used across all API calls (except CreateStore, flagged separately), ensuring uniform header validation and extraction.
Also applies to: 250-250, 256-256, 268-268, 276-276, 289-289, 318-318, 336-336, 362-362, 438-438, 472-472, 492-492, 548-548, 564-564, 593-593
299-299: Correct header propagation in derived operations.The headers are properly extracted and passed through to derived operations (ReadLatestAuthorizationModel, clientWriteOpts), ensuring that per-request headers are preserved across nested calls.
Also applies to: 375-375
config/clients/dotnet/template/OpenFgaClientTests.mustache (6)
5-5: LGTM: Required import for LINQ operations.The
System.Linqimport is necessary for the new helper methods and test assertions that use.First().
31-38: LGTM: Clean test data organization.Using a static class for test header constants improves maintainability and reduces magic strings throughout the tests.
61-91: LGTM: Well-designed test helpers.The helper methods
CreateTestClientForHeadersandAssertHeaderPresentprovide clean abstractions for:
- Setting up test clients with configurable request validation
- Verifying header presence and values in requests
This reduces duplication across the extensive header tests that follow.
144-291: LGTM: Comprehensive DefaultHeaders validation coverage.Excellent test coverage for configuration-time validation:
- Reserved headers (Content-Type, Authorization, etc.) with case-insensitive checking
- Empty header names and null values
- CRLF injection prevention
- Valid custom headers
The case-insensitivity tests (lines 259-272) correctly align with HTTP header semantics.
2014-2860: LGTM: Outstanding comprehensive test coverage for custom headers feature.This test region provides exceptional coverage of the per-request custom headers functionality:
Strengths:
- Tests all major API methods (Check, Write, Read, Expand, ListObjects, ListUsers, CreateStore, etc.)
- Validates header propagation end-to-end
- Tests null headers gracefully (lines 2086-2103)
- Validates CRLF injection prevention (lines 2108-2131)
- Tests reserved header protection (lines 2484-2515)
- Verifies header precedence across all layers: per-request > OAuth > default (lines 2565-2734)
- Includes concurrent request testing (lines 2520-2560)
- Comprehensive integration tests ensuring reserved headers are blocked in all paths (lines 2768-2858)
Note on concurrent test (lines 2520-2560):
The test validates that concurrent requests with different headers complete successfully, which is the primary goal. Individual header isolation per request is already validated in other tests, so the current approach is appropriate.The extensive test suite gives high confidence that the feature works correctly across all scenarios.
2373-2373: Static analysis false positive - not a real secret.The value
01GXSA8YR785C4FYS3C0RTG7B1flagged by static analysis is a test authorization model ID in ULID format, not an actual API key. This is used consistently throughout the test file as test data.
d5392a7 to
3a2488d
Compare
There was a problem hiding this comment.
Pull Request Overview
Adds per-request custom headers support to the .NET SDK templates, including validation and precedence handling between default, OAuth, and per-request headers.
- Introduces IRequestOptions/IClientRequestOptions with Headers and wires options through API and client layers
- Adds header validation (reserved headers, null/CRLF) and case-insensitive merge with defined precedence
- Updates docs and adds comprehensive tests for propagation, precedence, and validation
Reviewed Changes
Copilot reviewed 28 out of 29 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| config/clients/dotnet/template/modelRequestOptions.mustache | Adds IRequestOptions and RequestOptions for API-level headers. |
| config/clients/dotnet/template/api.mustache | Adds IRequestOptions? options parameter to API methods and forwards to ApiClient. |
| config/clients/dotnet/template/README_initializing.mustache | Documents default and per-request custom headers usage. |
| config/clients/dotnet/template/OpenFgaClientTests.mustache | Adds tests for headers validation, propagation, and precedence. |
| config/clients/dotnet/template/Configuration_Configuration.mustache | Adds reserved headers list and ValidateHeaders; validates DefaultHeaders in EnsureValid. |
| config/clients/dotnet/template/Client_ApiClient.mustache | Builds merged headers (default, OAuth, per-request) and forwards to BaseClient. |
| config/clients/dotnet/template/Client/Model/ClientWriteOptions.mustache | Adds Headers property to write options. |
| config/clients/dotnet/template/Client/Model/ClientWriteAssertionsOptions.mustache | Adds Headers property to write assertions options. |
| config/clients/dotnet/template/Client/Model/ClientRequestOptsWithStoreId.mustache | Switches to IClientRequestOptions base interface. |
| config/clients/dotnet/template/Client/Model/ClientRequestOptions.mustache | Introduces IClientRequestOptions and implementation with Headers. |
| config/clients/dotnet/template/Client/Model/ClientReadOptions.mustache | Adds Headers property to read options. |
| config/clients/dotnet/template/Client/Model/ClientReadChangesOptions.mustache | Adds Headers property to read changes options. |
| config/clients/dotnet/template/Client/Model/ClientReadAuthorizaionModelsOptions.mustache | Adds Headers property to read auth models options. |
| config/clients/dotnet/template/Client/Model/ClientReadAuthorizaionModelOptions.mustache | Adds Headers property to read auth model options. |
| config/clients/dotnet/template/Client/Model/ClientReadAssertionsOptions.mustache | Adds Headers property to read assertions options. |
| config/clients/dotnet/template/Client/Model/ClientListUsersOptions.mustache | Adds Headers property to list users options. |
| config/clients/dotnet/template/Client/Model/ClientListStoresOptions.mustache | Adds Headers property and updates base interface. |
| config/clients/dotnet/template/Client/Model/ClientListRelationsOptions.mustache | Adds Headers property to list relations options. |
| config/clients/dotnet/template/Client/Model/ClientListObjectsOptions.mustache | Adds Headers property to list objects options. |
| config/clients/dotnet/template/Client/Model/ClientExpandOptions.mustache | Adds Headers property to expand options. |
| config/clients/dotnet/template/Client/Model/ClientCreateStoreOptions.mustache | Adds Headers property to create store options. |
| config/clients/dotnet/template/Client/Model/ClientConsistencyOptions.mustache | Switches to package variable for model namespace. |
| config/clients/dotnet/template/Client/Model/ClientCheckOptions.mustache | Adds Headers property to check options. |
| config/clients/dotnet/template/Client/Model/ClientBatchCheckOptions.mustache | Adds Headers property to batch check options. |
| config/clients/dotnet/template/Client/ClientConfiguration.mustache | Adds usings needed for headers dictionary usage. |
| config/clients/dotnet/template/Client/Client.mustache | Threads options through high-level client calls and preserves Headers in chunked writes. |
| config/clients/dotnet/config.overrides.json | Maps new RequestOptions template into generated Model folder. |
| config/clients/dotnet/CHANGELOG.md.mustache | Documents breaking changes and new headers functionality. |
Description
This pull request introduces support for per-request custom headers to the .NET SDK.
DefaultHeadersproperty toClientConfigurationthat applies to all requestsEnsureValid()Headersproperty to theClientRequestOptionsinterface and all implementing classes (e.g.ClientCheckOptions,ClientWriteOptions, etc.)The core changes were implemented in
ClientConfiguration.cs,ClientRequestOptions.cs,ApiClient.cs,Client.cs. Options models were also updated to support the newHeadersproperty. Tests were also added for comprehensive coverage of the changes.Example of Changes
Before
Previously, there was no way to add custom headers to individual requests.
Developers had to use workarounds like wrapping the HttpClient:
The previous
ClientConfigurationimplementation ofDefaultHeadersonly allowed theUser-Agentstring to be changed:After
Per-request custom headers are supported on individual requests:
DefaultHeadersonClientConfigurationnow allows broad customization:References
Generates → openfga/dotnet-sdk#133
Review Checklist
mainSummary by CodeRabbit