Arguments

GraphQL arguments let clients pass values to individual fields. In Hot Chocolate, each parameter on a resolver method becomes a field argument in the schema, unless it is a recognized service type (like CancellationToken or a registered service).

GraphQL schema

GraphQL
type Query {
user(id: ID!): User
users(role: UserRole, limit: Int = 10): [User!]!
}

Client query

GraphQL
{
user(id: "UHJvZHVjdAppMQ==") {
name
}
}

Arguments are frequently provided through variables, which separate the static query structure from the dynamic runtime values:

GraphQL
query ($userId: ID!) {
user(id: $userId) {
name
}
}

Defining Arguments

Method parameters on a resolver become GraphQL arguments.

C#
// Types/UserQueries.cs
[QueryType]
public static partial class UserQueries
{
public static User? GetUser(string username, UserService users)
=> users.FindByName(username);
}

The username parameter becomes a username: String! argument. The UserService parameter is recognized as a service and is not exposed in the schema.

Renaming Arguments

Use [GraphQLName] to change the argument name in the schema while keeping the C# parameter name unchanged.

C#
// Types/UserQueries.cs
[QueryType]
public static partial class UserQueries
{
public static User? GetUser(
[GraphQLName("name")] string username,
UserService users)
=> users.FindByName(username);
}

This produces user(name: String!): User in the schema.

Optional Arguments

An argument is required when its C# type is non-nullable. Make an argument optional by using a nullable type.

C#
// Types/ProductQueries.cs
[QueryType]
public static partial class ProductQueries
{
public static List<Product> GetProducts(string? category, int? limit)
{
// Both arguments are optional
// ...
}
}

This produces:

GraphQL
type Query {
products(category: String, limit: Int): [Product!]!
}

When using nullable reference types (recommended), string maps to String! and string? maps to String. See Non-Null for details.

Default Values

Use [DefaultValue] to assign a default to an argument. The default appears in the schema and is used when the client omits the argument.

C#
// Types/ProductQueries.cs
[QueryType]
public static partial class ProductQueries
{
public static List<Product> GetProducts(
[DefaultValue(10)] int limit)
{
// ...
}
}

This produces products(limit: Int! = 10): [Product!]!.

C# default parameter values also work:

C#
public static List<Product> GetProducts(int limit = 10)

The ID Attribute

The [ID] attribute marks a parameter as a GraphQL ID scalar. When combined with global object identification, it also deserializes the opaque global ID back to the underlying value.

C#
// Types/ProductQueries.cs
[QueryType]
public static partial class ProductQueries
{
public static Product? GetProduct([ID] int id, CatalogContext db)
=> db.Products.Find(id);
}

To restrict the ID to a specific type (ensuring only IDs serialized for Product are accepted):

C#
public static Product? GetProduct(
[ID(nameof(Product))] int id,
CatalogContext db)
=> db.Products.Find(id);

In v16, you can also use the generic form [ID<Product>] which infers the type name automatically.

Complex Arguments

When an argument needs multiple fields, use an input object type instead of multiple scalar arguments.

C#
// Types/BookFilterInput.cs
public record BookFilterInput(string? Title, string? Author, int? Year);
// Types/BookQueries.cs
[QueryType]
public static partial class BookQueries
{
public static List<Book> GetBooks(BookFilterInput filter, CatalogContext db)
{
// ...
}
}

This produces:

GraphQL
input BookFilterInput {
title: String
author: String
year: Int
}
type Query {
books(filter: BookFilterInput!): [Book!]!
}

Next Steps

Last updated on April 13, 2026 by Michael Staib