Skip to main content
Model resolvers in Orionjs provide a way to define computed fields and relationships on your GraphQL types. Unlike regular resolvers which define root queries and mutations, model resolvers add fields to specific GraphQL types.

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:
The @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

  1. Parent Object: The first parameter is always the parent object (the instance of the type you’re adding the field to)
  2. Params: If you specify params, this will be the parameters passed to the field
  3. Viewer: The viewer object (contains authentication context)
  4. Info: The GraphQL info object for query optimization

Model Resolver Options

The @ModelResolver() decorator accepts options to customize the field:

Available Options

Configuring Return Types

Specify the return type in the returns 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

  1. Use for Computed Fields: Add fields that aren’t directly stored in your database.
  2. Handle Relationships: Define one-to-many and many-to-many relationships.
  3. Optimize with DataLoader: Use DataLoader to batch and cache similar requests.
  4. Keep it Simple: Each resolver should have a single responsibility.
  5. Apply Authorization: Use middleware to protect access to sensitive fields.
  6. Separate by Type: Create separate controller classes for each GraphQL type.
  7. Avoid Circular Dependencies: Be careful with bidirectional relationships to avoid circular dependencies.
  8. Consider Field Complexity: For computationally expensive fields, consider using query complexity analysis.
  9. Document Your Fields: Add descriptions to help API consumers understand your schema.
  10. Keep Consistent Naming: Follow a consistent naming convention for related fields.