This is documentation for v16, which is currently in preview.
See the latest stable version instead.

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 23, 2026 by Rafael Staib