mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-14 20:39:35 -06:00
#20603: Split GraphQL API into v1 & v2
This commit is contained in:
parent
77c08b7bf9
commit
7d82493052
@ -1,5 +1,15 @@
|
||||
# GraphQL API Parameters
|
||||
|
||||
## GRAPHQL_DEFAULT_VERSION
|
||||
|
||||
!!! note "This parameter was introduced in NetBox v4.5."
|
||||
|
||||
Default: `1`
|
||||
|
||||
Designates the default version of the GraphQL API served by `/graphql/`. To access a specific version, append the version number to the URL, e.g. `/graphql/v2/`.
|
||||
|
||||
---
|
||||
|
||||
## GRAPHQL_ENABLED
|
||||
|
||||
!!! tip "Dynamic Configuration Parameter"
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import strawberry
|
||||
from django.conf import settings
|
||||
from strawberry_django.optimizer import DjangoOptimizerExtension
|
||||
from strawberry.extensions import MaxAliasesLimiter # , SchemaExtension
|
||||
from strawberry.extensions import MaxAliasesLimiter
|
||||
from strawberry.schema.config import StrawberryConfig
|
||||
|
||||
from circuits.graphql.schema import CircuitsQuery
|
||||
@ -16,9 +16,17 @@ from virtualization.graphql.schema import VirtualizationQuery
|
||||
from vpn.graphql.schema import VPNQuery
|
||||
from wireless.graphql.schema import WirelessQuery
|
||||
|
||||
__all__ = (
|
||||
'Query',
|
||||
'QueryV1',
|
||||
'QueryV2',
|
||||
'schema_v1',
|
||||
'schema_v2',
|
||||
)
|
||||
|
||||
|
||||
@strawberry.type
|
||||
class Query(
|
||||
class QueryV1(
|
||||
UsersQuery,
|
||||
CircuitsQuery,
|
||||
CoreQuery,
|
||||
@ -31,11 +39,44 @@ class Query(
|
||||
WirelessQuery,
|
||||
*registry['plugins']['graphql_schemas'], # Append plugin schemas
|
||||
):
|
||||
"""Query class for GraphQL API v1"""
|
||||
pass
|
||||
|
||||
|
||||
schema = strawberry.Schema(
|
||||
query=Query,
|
||||
@strawberry.type
|
||||
class QueryV2(
|
||||
UsersQuery,
|
||||
CircuitsQuery,
|
||||
CoreQuery,
|
||||
DCIMQuery,
|
||||
ExtrasQuery,
|
||||
IPAMQuery,
|
||||
TenancyQuery,
|
||||
VirtualizationQuery,
|
||||
VPNQuery,
|
||||
WirelessQuery,
|
||||
*registry['plugins']['graphql_schemas'], # Append plugin schemas
|
||||
):
|
||||
"""Query class for GraphQL API v2"""
|
||||
pass
|
||||
|
||||
|
||||
# Expose a default Query class for the configured default GraphQL version
|
||||
class Query(QueryV2 if settings.GRAPHQL_DEFAULT_VERSION == 2 else QueryV1):
|
||||
pass
|
||||
|
||||
|
||||
# Generate schemas for both versions of the GraphQL API
|
||||
schema_v1 = strawberry.Schema(
|
||||
query=QueryV1,
|
||||
config=StrawberryConfig(auto_camel_case=False),
|
||||
extensions=[
|
||||
DjangoOptimizerExtension(prefetch_custom_queryset=True),
|
||||
MaxAliasesLimiter(max_alias_count=settings.GRAPHQL_MAX_ALIASES),
|
||||
]
|
||||
)
|
||||
schema_v2 = strawberry.Schema(
|
||||
query=QueryV2,
|
||||
config=StrawberryConfig(auto_camel_case=False),
|
||||
extensions=[
|
||||
DjangoOptimizerExtension(prefetch_custom_queryset=True),
|
||||
|
||||
16
netbox/netbox/graphql/utils.py
Normal file
16
netbox/netbox/graphql/utils.py
Normal file
@ -0,0 +1,16 @@
|
||||
from django.conf import settings
|
||||
|
||||
from netbox.graphql.schema import schema_v1, schema_v2
|
||||
|
||||
__all__ = (
|
||||
'get_default_schema',
|
||||
)
|
||||
|
||||
|
||||
def get_default_schema():
|
||||
"""
|
||||
Returns the GraphQL schema corresponding to the value of the NETBOX_GRAPHQL_DEFAULT_SCHEMA setting.
|
||||
"""
|
||||
if settings.GRAPHQL_DEFAULT_VERSION == 2:
|
||||
return schema_v2
|
||||
return schema_v1
|
||||
@ -137,6 +137,7 @@ EVENTS_PIPELINE = getattr(configuration, 'EVENTS_PIPELINE', [
|
||||
EXEMPT_VIEW_PERMISSIONS = getattr(configuration, 'EXEMPT_VIEW_PERMISSIONS', [])
|
||||
FIELD_CHOICES = getattr(configuration, 'FIELD_CHOICES', {})
|
||||
FILE_UPLOAD_MAX_MEMORY_SIZE = getattr(configuration, 'FILE_UPLOAD_MAX_MEMORY_SIZE', 2621440)
|
||||
GRAPHQL_DEFAULT_VERSION = getattr(configuration, 'GRAPHQL_DEFAULT_VERSION', 1)
|
||||
GRAPHQL_MAX_ALIASES = getattr(configuration, 'GRAPHQL_MAX_ALIASES', 10)
|
||||
HOSTNAME = getattr(configuration, 'HOSTNAME', platform.node())
|
||||
HTTP_PROXIES = getattr(configuration, 'HTTP_PROXIES', {})
|
||||
|
||||
@ -6,7 +6,8 @@ from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, Spec
|
||||
|
||||
from account.views import LoginView, LogoutView
|
||||
from netbox.api.views import APIRootView, StatusView
|
||||
from netbox.graphql.schema import schema
|
||||
from netbox.graphql.schema import schema_v1, schema_v2
|
||||
from netbox.graphql.utils import get_default_schema
|
||||
from netbox.graphql.views import NetBoxGraphQLView
|
||||
from netbox.plugins.urls import plugin_patterns, plugin_api_patterns
|
||||
from netbox.views import HomeView, MediaView, StaticMediaFailureView, SearchView, htmx
|
||||
@ -40,7 +41,7 @@ _patterns = [
|
||||
# HTMX views
|
||||
path('htmx/object-selector/', htmx.ObjectSelectorView.as_view(), name='htmx_object_selector'),
|
||||
|
||||
# API
|
||||
# REST API
|
||||
path('api/', APIRootView.as_view(), name='api-root'),
|
||||
path('api/circuits/', include('circuits.api.urls')),
|
||||
path('api/core/', include('core.api.urls')),
|
||||
@ -54,6 +55,7 @@ _patterns = [
|
||||
path('api/wireless/', include('wireless.api.urls')),
|
||||
path('api/status/', StatusView.as_view(), name='api-status'),
|
||||
|
||||
# REST API schema
|
||||
path(
|
||||
"api/schema/",
|
||||
cache_page(timeout=86400, key_prefix=f"api_schema_{settings.RELEASE.version}")(
|
||||
@ -64,8 +66,10 @@ _patterns = [
|
||||
path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='api_docs'),
|
||||
path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='api_redocs'),
|
||||
|
||||
# GraphQL
|
||||
path('graphql/', NetBoxGraphQLView.as_view(schema=schema), name='graphql'),
|
||||
# GraphQL API
|
||||
path('graphql/', NetBoxGraphQLView.as_view(schema=get_default_schema()), name='graphql'),
|
||||
path('graphql/v1/', NetBoxGraphQLView.as_view(schema=schema_v1), name='graphql_v1'),
|
||||
path('graphql/v2/', NetBoxGraphQLView.as_view(schema=schema_v2), name='graphql_v2'),
|
||||
|
||||
# Serving static media in Django to pipe it through LoginRequiredMiddleware
|
||||
path('media/<path:path>', MediaView.as_view(), name='media'),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user