website/src/docs/hotchocolate/v16/server/global-state.md
Global State lets you define properties on a per-request basis and makes them available to all resolvers and middleware.
Add Global State using the SetProperty method on the OperationRequestBuilder. This method takes a key and a value as arguments. The key must be a string, and the value can be of any type.
Using an interceptor lets you initialize Global State before the request is executed.
public class HttpRequestInterceptor : DefaultHttpRequestInterceptor
{
public override ValueTask OnCreateAsync(HttpContext context,
IRequestExecutor requestExecutor, OperationRequestBuilder requestBuilder,
CancellationToken cancellationToken)
{
string userId =
context.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
requestBuilder.SetProperty("UserId", userId);
// requestBuilder.SetProperty("IntegerValue", int.Parse(userId));
// requestBuilder.SetProperty("ObjectValue", new User { Id = userId });
return base.OnCreateAsync(context, requestExecutor, requestBuilder,
cancellationToken);
}
}
Access Global State in your resolvers as follows.
<ExampleTabs> <Implementation>public class Query
{
public string Example1([GlobalState("UserId")] string userId)
{
// Omitted code for brevity
}
public string Example2([GlobalState("ObjectValue")] User user)
{
// Omitted code for brevity
}
}
The GlobalStateAttribute accepts the key of the Global State value as an argument. An exception is thrown if no Global State value exists for the specified key or if the value cannot be coerced to the type of the argument.
Creating a custom attribute that inherits from GlobalStateAttribute is a good practice:
public class UserIdAttribute : GlobalStateAttribute
{
public UserIdAttribute() : base("UserId")
{
}
}
public class Query
{
public string Example([UserId] string userId)
{
// Omitted code for brevity
}
}
public class QueryType : ObjectType
{
protected override void Configure(IObjectTypeDescriptor descriptor)
{
descriptor
.Field("example")
.Resolve(context =>
{
var userId = context.GetGlobalValue<string>("UserId");
// Omitted code for brevity
});
}
}
Warning: If no value exists for the specified
key, a default value is returned and no exception is thrown.
You can also access Global State through the ContextData dictionary on the IResolverContext:
descriptor
.Field("example")
.Resolve(context =>
{
if (!context.ContextData.TryGetValue("UserId", out var value)
|| value is not string userId)
{
// handle failed assertion
}
// Omitted code for brevity
});
Take a look at the implementation-first or code-first example.
</Schema> </ExampleTabs>