netbox icon indicating copy to clipboard operation
netbox copied to clipboard

GraphQL: Add filter arguments at all levels

Open ryanmerolle opened this issue 4 years ago • 3 comments

NetBox version

v3.1.4

Feature type

New functionality

Proposed functionality

Add filter arguments at all levels for GraphQL. Currently, it's only possible to define filter arguments at the top level.

Currently the below is supported:

{
  device_list(site: "MAD1") {
    id
    name
    site{
      name
    }
    interfaces {
      name
    }
  }
  interface_list(name:"eth0", site:"MAD1") {
    name
  }
}

Proposed functionality currently not supported, but common in most GraphQL setups:

{
  device_list(site: "MAD1") {
    id
    name
    site{
      name
    }
    interfaces(name: "eth0") {
      name
    }
  }
}

Use case

Have a more powerful query engine that will be able to return only the desired results by supporting GraphQL filter functionality commonly found in other deployments.

Database changes

None

External dependencies

None

ryanmerolle avatar Jan 05 '22 15:01 ryanmerolle

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. NetBox is governed by a small group of core maintainers which means not all opened issues may receive direct feedback. Please see our contributing guide.

github-actions[bot] avatar Mar 09 '22 04:03 github-actions[bot]

Before investing any further effort into our implementation of graphene-django, it's worth considering alternative backends, as the project is apparently dead.

jeremystretch avatar Jun 27 '22 16:06 jeremystretch

Blocked by #9856

jeremystretch avatar Jul 27 '22 18:07 jeremystretch

For filtering graphene is tied to Relay, this will make a couple changes to the output scheme and how you do queries:

  1. id's become 64 bit encoded
  2. lists show up as paginated edges with nodes.

For example:

{
  device_type_list {
    id
    instances(site: "dm-camden") {
      edges {
        node {
          id
          name
          site {
            id
            name
          }
        }
      }
    }
  }
}

instead of the current:

{
  device_type_list {
    id
    instances {
          id
          name
          site {
            id
            name
          }
    }
  }
}

output new query:

{
  "data": {
    "device_type_list": [
      {
        "id": "RGV2aWNlVHlwZVR5cGU6OA==",
        "instances": {
          "edges": [
            {
              "node": {
                "id": "RGV2aWNlVHlwZTozNw==",
                "name": "dmi01-camden-pdu01",
                "site": {
                  "id": "U2l0ZVR5cGU6Ng==",
                  "name": "DM-Camden"
                }
              }
            }
          ]
        }
      },
      {
        "id": "RGV2aWNlVHlwZVR5cGU6MTY=",
        "instances": {
          "edges": []
        }
      },

Also, have to debug (probably graphene bug?) it returns items that are empty (edges: []) with what you would normally expect. Changes to codebase are to the types.py files - re-arrange ordering and add an interface line to each type definition.

There is a package graphene-django-extras that we could pull a FilterListField (just pull in that field, not the whole package) that wouldn't require Relay but it would probably need some tweaks as it hasn't been updated for a year. Looking about 600 lines of code we would need to pickup from there in a couple different files.

arthanson avatar Oct 04 '22 14:10 arthanson

We discussed via chat an approach with less impact on the schema. @arthanson is exploring and will come back at his convenience.

As always, thanks @arthanson !

ryanmerolle avatar Oct 04 '22 21:10 ryanmerolle