Skip to content

#30 - add graphql support for custom objects#565

Open
arthanson wants to merge 4 commits into
featurefrom
30-graphql
Open

#30 - add graphql support for custom objects#565
arthanson wants to merge 4 commits into
featurefrom
30-graphql

Conversation

@arthanson

@arthanson arthanson commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Fixes: #30

Custom objects are now queryable through NetBox's GraphQL API at /graphql/, alongside built-in NetBox models. Each CustomObjectType gets two root query fields: (single object by id) and _list (paginated list).

How it works

  • A Strawberry type is generated at runtime for each CustomObjectType, mirroring how the models themselves are generated.
  • The plugin contributes its Query via the standard graphql_schema resource, so NetBox merges it into the global schema during ready() — after dynamic models are built.
  • Object-level view permissions are enforced (types inherit NetBox's BaseObjectType).

Field mapping

  • Scalars → natural GraphQL types (String, Int, Decimal, Boolean, Date, DateTime, JSON, [String]).
  • Object / multi-object (incl. polymorphic) → a shared CustomObjectRelatedObjectType (id, object_type, display, url).
  • Base fields: id, display, created, last_updated, tags.

Live schema & caching

Custom object types can be created, edited, and deleted at runtime, so the GraphQL schema can't be built once at boot like NetBox's. A small view patch swaps in a per-request, per-process schema that tracks the database - runtime changes appear without a NetBox restart, across all worker processes, with no cross-process messaging.

  • Change detection: each request computes a cheap signature — row counts + max cache_timestamp/last_updated over CustomObjectType/CustomObjectTypeField (two aggregate queries). cache_timestamp is bumped on every structural change, and counts catch adds/removes, so any worker notices a change on its next request.
  • Schema cache: the assembled schema is cached per process and rebuilt only when the signature changes. The hot path (unchanged) is lock-free; rebuilds are single-flight (one thread rebuilds while others keep serving the current schema instead of blocking).
  • Per-type cache: each COT's Strawberry type is memoized by (id, cache_timestamp), so a rebuild triggered by one type reuses every other type's already-built definition instead of regenerating all of them.
Monosnap GraphiQL | NetBox 2026-06-08 14-45-01

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant