Skip to content

Integrating with GraphQL

Apps can optionally expose their models via the GraphQL interface to allow the models to be part of the Graph and to be queried easily. There are two mutually exclusive ways to expose a model to the GraphQL interface.

  • By using the @extras_features decorator
  • By creating your own GraphQL type definition and registering it within graphql/types.py of your app (the decorator should not be used in this case)

All GraphQL model types defined by your app, regardless of which method is chosen, will automatically support some built-in Nautobot features:

  • Support for object permissions based on their associated Model class
  • Include any custom fields defined for their Model
  • Include any relationships defined for their Model
  • Include tags, if the Model supports them

Using the @extras_features Decorator for GraphQL

To expose a model via GraphQL, simply register it using the @extras_features("graphql") decorator. Nautobot will detect this and will automatically create a GraphQL type definition based on the model. Additionally, if a FilterSet is available at <app_name>.filters.<ModelName>FilterSet, Nautobot will automatically use the filterset to generate GraphQL filtering options for this type as well.

# models.py
from django.db import models

from nautobot.apps.models import BaseModel, extras_features


@extras_features("graphql")
class Animal(BaseModel):
    """Base model for animals."""

    name = models.CharField(max_length=50)
    sound = models.CharField(max_length=50)

    def __str__(self):
        return self.name

Creating Your Own GraphQL Type Object

Changed in version 1.6.2

A new base class was introduced for Nautobot GraphQL object types: nautobot.core.graphql.types.OptimizedNautobotObjectType. This class inherits from graphene_django_optimizer.OptimizedDjangoObjectType and adds generic Nautobot specific functionality.

In some cases, such as when a model is using Generic Foreign Keys, or when a model has constructed fields that should also be reflected in GraphQL, the default GraphQL type definition generated by the @extras_features decorator may not work as the developer intends, and it will be preferable to provide custom GraphQL types.

By default, Nautobot looks for custom GraphQL types in an iterable named graphql_types within a graphql/types.py file. (This can be overridden by setting graphql_types to a custom value on the app's NautobotAppConfig.) Each type defined in this way must be a class inheriting from graphene_django.DjangoObjectType, graphene_django_optimizer.OptimizedDjangoObjectType, or nautobot.core.graphql.types.OptimizedNautobotObjectType and must follow the standards defined by graphene-django.

Nautobot uses a library called graphene-django-optimizer to decrease the time queries take to process. By inheriting from graphene_django_optimizer type classes are automatically optimized.

Warning

When defining types this way, do not use the @extras_features("graphql") decorator on the corresponding Model class, as no auto-generated GraphQL type is desired for this model.

# graphql/types.py
import graphene_django_optimizer as gql_optimizer

from nautobot_animal_sounds.models import Animal
from nautobot.core.graphql.types import OptimizedNautobotObjectType


class AnimalType(OptimizedNautobotObjectType):
    """GraphQL Type for Animal"""

    class Meta:
        model = Animal
        exclude = ["sound"]


graphql_types = [AnimalType]

Using GraphQL ORM Utilities

GraphQL utility functions:

  1. execute_query(): Runs string as a query against GraphQL.
  2. execute_saved_query(): Execute a saved query from Nautobot database.

Both functions have the same arguments other than execute_saved_query() which requires a name to identify the saved query rather than a string holding a query.

Changed in version 2.0.0

execute_saved_query() now expects a saved_query_name rather than a saved_query_slug.

For authentication either a request object or user object needs to be passed in. If there is none, the function will error out.

Arguments:

  • execute_query():
    • query (str): String with GraphQL query.
    • variables (dict, optional): If the query has variables they need to be passed in as a dictionary.
    • request (django.test.client.RequestFactory, optional): Used to authenticate.
    • user (django.contrib.auth.models.User, optional): Used to authenticate.
  • execute_saved_query():
    • saved_query_name (str): Name of a saved GraphQL query.
    • variables (dict, optional): If the query has variables they need to be passed in as a dictionary.
    • request (django.test.client.RequestFactory, optional): Used to authenticate.
    • user (django.contrib.auth.models.User, optional): Used to authenticate.

Returned is a GraphQL object which holds the same data as returned from GraphiQL. Use execute_query().to_dict() to get the data back inside of a dictionary.