Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add url field to GraphQL types #3913

Closed
1 of 12 tasks
jamesharr opened this issue Jun 13, 2023 · 2 comments · Fixed by #4163 or #4317
Closed
1 of 12 tasks

Add url field to GraphQL types #3913

jamesharr opened this issue Jun 13, 2023 · 2 comments · Fixed by #4163 or #4317
Assignees
Labels
type: feature Introduction of new or enhanced functionality to the application

Comments

@jamesharr
Copy link
Contributor

As ...

Tammy - Tools Integrator

I want ...

Add url to supported fields in GraphQL.

So that ...

This field would support an easy way to locate the object for future updates without hand-written URLs.

For instance: I have a script that needs to query and update a set of objects of varying types. I construct a GraphQL query to retrieve all the data I want. I determine there's some changes that need to be made, so I need to construct a URL for this object to submit an HTTP PATCH. If the url field was already something I could request via GraphQL, the error-prone process of constructing the URL could be avoided.

I know this is done when...

  • Most or all object types in GraphQL have a url field that can be included in the query.
  • Any objects that don't have a url field have a reason for to not include it. For example, if the REST API does not include a URL field.

Optional - Feature groups this request pertains to.

  • Automation
  • Circuits
  • DCIM
  • IPAM
  • Misc (including Data Sources)
  • Organization
  • Plugins (and other Extensibility)
  • Security (Secrets, etc)
  • Image Management
  • UI/UX
  • Documentation
  • Other (not directly a platform feature)

Database Changes

No changes to database required

External Dependencies

unsure

@jamesharr jamesharr added the type: feature Introduction of new or enhanced functionality to the application label Jun 13, 2023
@glennmatthews glennmatthews changed the title Add Add url field to GraphQL types Jun 13, 2023
@glennmatthews
Copy link
Contributor

This looks like it wouldn't be too difficult to do - here's a diff that starts things in what appear to be the right general direction:

diff --git a/nautobot/core/graphql/types.py b/nautobot/core/graphql/types.py
index d68518cd4..15403d2e0 100644
--- a/nautobot/core/graphql/types.py
+++ b/nautobot/core/graphql/types.py
@@ -1,8 +1,29 @@
 from django.contrib.contenttypes.models import ContentType
 
+import graphene
+from graphene_django import DjangoObjectType
 import graphene_django_optimizer as gql_optimizer
 
 
+class NautobotObjectType(DjangoObjectType):
+    url = graphene.String()
+
+    def resolve_url(self, args):
+        return self.get_absolute_url(api=True)
+
+    class Meta:
+        abstract = True
+
+
+class OptimizedNautobotObjectType(gql_optimizer.OptimizedDjangoObjectType):
+    url = graphene.String()
+
+    def resolve_url(self, args):
+        return self.get_absolute_url(api=True)
+
+    class Meta:
+        abstract = True
+
 class ContentTypeType(gql_optimizer.OptimizedDjangoObjectType):
     """
     Graphene-Django object type for ContentType records.
diff --git a/nautobot/core/graphql/generators.py b/nautobot/core/graphql/generators.py
index 4a2e46494..47473fb2f 100644
--- a/nautobot/core/graphql/generators.py
+++ b/nautobot/core/graphql/generators.py
@@ -7,6 +7,7 @@ import graphene_django_optimizer as gql_optimizer
 from graphql import GraphQLError
 from graphene_django import DjangoObjectType
 
+from nautobot.core.graphql.types import NautobotObjectType
 from nautobot.core.graphql.utils import str_to_var_name, get_filtering_args_from_filterset
 from nautobot.core.utils.lookup import get_filterset_for_model
 from nautobot.extras.choices import RelationshipSideChoices
@@ -205,7 +206,7 @@ def generate_relationship_resolver(name, resolver_name, relationship, side, peer
     return resolve_relationship
 
 
-def generate_schema_type(app_name: str, model: object) -> DjangoObjectType:
+def generate_schema_type(app_name: str, model: object) -> NautobotObjectType:
     """
     Take a Django model and generate a Graphene Type class definition.
 
@@ -216,7 +217,7 @@ def generate_schema_type(app_name: str, model: object) -> DjangoObjectType:
     Example:
         For a model with a name of "Device", the following class definition is generated:
 
-        class DeviceType(DjangoObjectType):
+        class DeviceType(NautobotObjectType):
             Meta:
                 model = Device
                 fields = ["__all__"]
@@ -225,7 +226,7 @@ def generate_schema_type(app_name: str, model: object) -> DjangoObjectType:
         '<app_name>.filters.<ModelName>FilterSet' the filterset will be stored in
         filterset_class as follows:
 
-        class DeviceType(DjangoObjectType):
+        class DeviceType(NautobotObjectType):
             Meta:
                 model = Device
                 fields = ["__all__"]
@@ -241,7 +242,7 @@ def generate_schema_type(app_name: str, model: object) -> DjangoObjectType:
 
     main_attrs["Meta"] = type("Meta", (object,), meta_attrs)
 
-    schema_type = type(f"{model.__name__}Type", (DjangoObjectType,), main_attrs)
+    schema_type = type(f"{model.__name__}Type", (NautobotObjectType,), main_attrs)
     return schema_type
 
 

image

Remaining work would be to convert any custom types (nautobot/*/graphql/types.py) to inherit from the new NautobotObjectType or OptimizedNautobotObjectType base class, testing, documentation, error handling, etc. :-)

@jamesharr
Copy link
Contributor Author

I have a first-pass at this in PR #4163, based on your example above. I'd like someone else to look at it before I run through the rest of the PR checklist.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type: feature Introduction of new or enhanced functionality to the application
Projects
No open projects
Archived in project
3 participants