Configuring Headers
You can set headers with static or dynamic values and with clear or redacted logged values (if logging is enabled with headers included).
First, add the request options parameter [RequestOptions] IApizrRequestOptions options
to your api methods to ensure your headers will be applied and don't forget to pass the options to your api methods at request time.
Static headers
You can set headers with static values at design time by decorating interfaces or methods with the Headers
attribute provided by Refit.
[Headers("HeaderKey1: HeaderValue1", "HeaderKey2: HeaderValue2")]
public interface IYourApi
{
[Headers("HeaderKey3: HeaderValue3")]
[Get("/your-endpoint")]
Task<YourData> GetYourDataAsync([RequestOptions] IApizrRequestOptions options);
}
Note
Please refer to Refit official documentation about Headers attribute with static values. Note that decorating assembly to share headers between several api interfaces is not available with Refit's Headers attribute, but you can do it with fluent configuration at register time.
You’ll find some more header attributes but dedicated to CRUD apis (the ones starting with Read
, ReadAll
, Create
, Update
or Delete
prefix), so you could define header settings at method/request level for CRUD apis too.
Here is CRUD api an example:
namespace Apizr.Sample.Models
{
[BaseAddress("https://reqres.in/api/users")]
[ReadHeaders("HeaderKey1: HeaderValue1", "HeaderKey2: HeaderValue2")]
[ReadAllHeaders("HeaderKey3: HeaderValue3")]
public record User
{
[JsonPropertyName("id")]
public int Id { get; init; }
[JsonPropertyName("first_name")]
public string FirstName { get; init; }
[JsonPropertyName("last_name")]
public string LastName { get; init; }
[JsonPropertyName("avatar")]
public string Avatar { get; init; }
[JsonPropertyName("email")]
public string Email { get; init; }
}
}
You definitly can mix it all as Apiz will merge your headers at the very end while sending the request.
Dynamic headers
Setting dynamic headers
You can set headers with dynamic values at design time by:
- Decorating an api method parameter with the
Header
orHeaderCollection
attribute - Decorating interfaces or methods with the
Headers
attribute using key matching
Parameter header
You can set headers with dynamic values at design time by decorating an api method parameter with the Header
attribute:
public interface IYourApi
{
[Get("/your-endpoint")]
Task<YourData> GetYourDataAsync([Header("HeaderKey1")] string headerValue1, [RequestOptions] IApizrRequestOptions options);
}
or HeaderCollection
attribute:
public interface IYourApi
{
[Get("/your-endpoint")]
Task<YourData> GetYourDataAsync([HeaderCollection] IDictionary<string, string> headers, [RequestOptions] IApizrRequestOptions options);
}
Please refer to Refit official documentation about Header
and HeaderCollection
attributes with dynamic values.
Key matching header
You can set headers with dynamic values at design time by decorating interfaces or methods with the Headers
attribute and using key matching:
[Headers("HeaderKey1: {0}", "HeaderKey2: {0}")]
public interface IYourApi
{
[Headers("HeaderKey3: {0}")]
[Get("/your-endpoint")]
Task<YourData> GetYourFirstDataAsync([RequestOptions] IApizrRequestOptions options);
[Get("/your-endpoint")]
Task<YourData> GetYourSecondDataAsync([RequestOptions] IApizrRequestOptions options);
}
Here we are asking Apizr to set headers 1, 2 and 3 to GetYourFirstDataAsync
and the same but 3 to GetYourSecondDataAsync
.
It's here to let you choose at design time which request needs which headers, but provide values later in another place.
So we don't provide any value here but the {0}
string placeholder and let Apizr set it at request time from its headers store if keys match.
Tip
CRUD api headers could be set using provided dedicted method headers attributes (ReadAllHeaders, ...
)
Warning
Key matching headers need you to provide values fluently at register time with Store
registration mode (see Registering tab).
You definitly can mix it all as Apiz will merge your headers at the very end while sending the request.
Refreshing dynamic header values
You may want to refresh your dynamic header values on each request.
If so, you can set your header values at register time with the Request
lifetime scope (instead of the Api
default one):
// expression factory configuration
options => options.WithHeaders(settingsService, [settings => settings.Header1,
settings => settings.Header2],
scope: ApizrLifetimeScope.Request)
// OR extended expression factory configuration
options => options.WithHeaders<IOptions<TestSettings>>([settings => settings.Value.Header1,
settings => settings.Value.Header2],
scope: ApizrLifetimeScope.Request)
Redacting logged header values
You may want to log http traces, including headers, but be concerned about its values sensitivity.
In such ssenario, you should redact header values so that logs would never contain any header sensitive value but a *
replacement.
You can tell Apizr to do so by surrounding values with a *
and *
star symbol into the Headers
attribute:
[Headers("HeaderKey1: *HeaderValue1*", "HeaderKey2: HeaderValue2")]
public interface IYourApi
{
[Headers("HeaderKey3: *HeaderValue3*", "HeaderKey4: *{0}*)]
[Get("/your-endpoint")]
Task<YourData> GetYourDataAsync([RequestOptions] IApizrRequestOptions options);
}
Here we are asking Apizr to redact both headers 1 and 3 values, but also key matching header 4 value.
Tip
CRUD api headers could be set using provided dedicted method headers attributes (ReadAllHeaders, ...
)