Creating Model Resolvers
A model resolver controller is a class decorated with@ModelResolvers()
that specifies the GraphQL type to extend, and contains methods decorated with @ModelResolver()
to define fields on that type:
@ModelResolvers()
decorator takes the schema that represents your GraphQL type. Each method decorated with @ModelResolver()
adds a new field to that type.
Model Resolver Methods
Model resolver methods receive the parent object as their first parameter, followed by any parameters, the viewer, and GraphQL info:Method Parameters
- Parent Object: The first parameter is always the parent object (the instance of the type you’re adding the field to)
- Params: If you specify
params
, this will be the parameters passed to the field - Viewer: The viewer object (contains authentication context)
- Info: The GraphQL info object for query optimization
Model Resolver Options
The@ModelResolver()
decorator accepts options to customize the field:
Available Options
Option | Type | Description |
---|---|---|
name | string | Custom name for the GraphQL field (defaults to method name) |
description | string | Description for the field in GraphQL schema documentation |
Configuring Return Types
Specify the return type in thereturns
property of createModelResolver
:
Field Parameters
You can define parameters for your model resolver fields:Field Middleware
You can apply middleware to model resolvers using@UseMiddleware()
:
Custom Model Names
By default, the@ModelResolvers()
decorator uses the class name of the provided schema. You can specify a custom name:
Handling Relationships
Model resolvers are ideal for handling relationships between your GraphQL types:One-to-Many Relationships
Many-to-Many Relationships
DataLoader for Performance
For optimal performance, use DataLoader with your model resolvers to batch and cache database queries:Best Practices
- Use for Computed Fields: Add fields that aren’t directly stored in your database.
- Handle Relationships: Define one-to-many and many-to-many relationships.
- Optimize with DataLoader: Use DataLoader to batch and cache similar requests.
- Keep it Simple: Each resolver should have a single responsibility.
- Apply Authorization: Use middleware to protect access to sensitive fields.
- Separate by Type: Create separate controller classes for each GraphQL type.
- Avoid Circular Dependencies: Be careful with bidirectional relationships to avoid circular dependencies.
- Consider Field Complexity: For computationally expensive fields, consider using query complexity analysis.
- Document Your Fields: Add descriptions to help API consumers understand your schema.
- Keep Consistent Naming: Follow a consistent naming convention for related fields.