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.