Skip to content

Commit fe7cc8c

Browse files
authored
Closes #16224 GraphQL Pagination (#18903)
* 16244 add pagination * 16244 add pagination * 16244 fix order_by pagination * 16224 document pagination * 16224 remove extraneous code * 16224 missing core types * 16224 review changes * 16224 review changes * 16224 review changes
1 parent 80440fd commit fe7cc8c

File tree

14 files changed

+277
-117
lines changed

14 files changed

+277
-117
lines changed

docs/integrations/graphql-api.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,18 @@ Certain queries can return multiple types of objects, for example cable terminat
131131
```
132132
The field "class_type" is an easy way to distinguish what type of object it is when viewing the returned data, or when filtering. It contains the class name, for example "CircuitTermination" or "ConsoleServerPort".
133133

134+
## Pagination
135+
136+
Queries can be paginated by specifying pagination in the query and supplying an offset and optionaly a limit in the query. If no limit is given, a default of 100 is used. Queries are not paginated unless requested in the query. An example paginated query is shown below:
137+
138+
```
139+
query {
140+
device_list(pagination: { offset: 0, limit: 20 }) {
141+
id
142+
}
143+
}
144+
```
145+
134146
## Authentication
135147

136148
NetBox's GraphQL API uses the same API authentication tokens as its REST API. Authentication tokens are included with requests by attaching an `Authorization` HTTP header in the following form:

netbox/circuits/graphql/types.py

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
@strawberry_django.type(
3333
models.Provider,
3434
fields='__all__',
35-
filters=ProviderFilter
35+
filters=ProviderFilter,
36+
pagination=True
3637
)
3738
class ProviderType(NetBoxObjectType, ContactsMixin):
3839

@@ -45,7 +46,8 @@ class ProviderType(NetBoxObjectType, ContactsMixin):
4546
@strawberry_django.type(
4647
models.ProviderAccount,
4748
fields='__all__',
48-
filters=ProviderAccountFilter
49+
filters=ProviderAccountFilter,
50+
pagination=True
4951
)
5052
class ProviderAccountType(NetBoxObjectType):
5153
provider: Annotated["ProviderType", strawberry.lazy('circuits.graphql.types')]
@@ -56,7 +58,8 @@ class ProviderAccountType(NetBoxObjectType):
5658
@strawberry_django.type(
5759
models.ProviderNetwork,
5860
fields='__all__',
59-
filters=ProviderNetworkFilter
61+
filters=ProviderNetworkFilter,
62+
pagination=True
6063
)
6164
class ProviderNetworkType(NetBoxObjectType):
6265
provider: Annotated["ProviderType", strawberry.lazy('circuits.graphql.types')]
@@ -67,7 +70,8 @@ class ProviderNetworkType(NetBoxObjectType):
6770
@strawberry_django.type(
6871
models.CircuitTermination,
6972
exclude=['termination_type', 'termination_id', '_location', '_region', '_site', '_site_group', '_provider_network'],
70-
filters=CircuitTerminationFilter
73+
filters=CircuitTerminationFilter,
74+
pagination=True
7175
)
7276
class CircuitTerminationType(CustomFieldsMixin, TagsMixin, CabledObjectMixin, ObjectType):
7377
circuit: Annotated["CircuitType", strawberry.lazy('circuits.graphql.types')]
@@ -86,7 +90,8 @@ def termination(self) -> Annotated[Union[
8690
@strawberry_django.type(
8791
models.CircuitType,
8892
fields='__all__',
89-
filters=CircuitTypeFilter
93+
filters=CircuitTypeFilter,
94+
pagination=True
9095
)
9196
class CircuitTypeType(OrganizationalObjectType):
9297
color: str
@@ -97,7 +102,8 @@ class CircuitTypeType(OrganizationalObjectType):
97102
@strawberry_django.type(
98103
models.Circuit,
99104
fields='__all__',
100-
filters=CircuitFilter
105+
filters=CircuitFilter,
106+
pagination=True
101107
)
102108
class CircuitType(NetBoxObjectType, ContactsMixin):
103109
provider: ProviderType
@@ -113,7 +119,8 @@ class CircuitType(NetBoxObjectType, ContactsMixin):
113119
@strawberry_django.type(
114120
models.CircuitGroup,
115121
fields='__all__',
116-
filters=CircuitGroupFilter
122+
filters=CircuitGroupFilter,
123+
pagination=True
117124
)
118125
class CircuitGroupType(OrganizationalObjectType):
119126
tenant: TenantType | None
@@ -122,7 +129,8 @@ class CircuitGroupType(OrganizationalObjectType):
122129
@strawberry_django.type(
123130
models.CircuitGroupAssignment,
124131
exclude=['member_type', 'member_id'],
125-
filters=CircuitGroupAssignmentFilter
132+
filters=CircuitGroupAssignmentFilter,
133+
pagination=True
126134
)
127135
class CircuitGroupAssignmentType(TagsMixin, BaseObjectType):
128136
group: Annotated["CircuitGroupType", strawberry.lazy('circuits.graphql.types')]
@@ -138,7 +146,8 @@ def member(self) -> Annotated[Union[
138146
@strawberry_django.type(
139147
models.VirtualCircuitType,
140148
fields='__all__',
141-
filters=VirtualCircuitTypeFilter
149+
filters=VirtualCircuitTypeFilter,
150+
pagination=True
142151
)
143152
class VirtualCircuitTypeType(OrganizationalObjectType):
144153
color: str
@@ -149,7 +158,8 @@ class VirtualCircuitTypeType(OrganizationalObjectType):
149158
@strawberry_django.type(
150159
models.VirtualCircuitTermination,
151160
fields='__all__',
152-
filters=VirtualCircuitTerminationFilter
161+
filters=VirtualCircuitTerminationFilter,
162+
pagination=True
153163
)
154164
class VirtualCircuitTerminationType(CustomFieldsMixin, TagsMixin, ObjectType):
155165
virtual_circuit: Annotated[
@@ -165,7 +175,8 @@ class VirtualCircuitTerminationType(CustomFieldsMixin, TagsMixin, ObjectType):
165175
@strawberry_django.type(
166176
models.VirtualCircuit,
167177
fields='__all__',
168-
filters=VirtualCircuitFilter
178+
filters=VirtualCircuitFilter,
179+
pagination=True
169180
)
170181
class VirtualCircuitType(NetBoxObjectType):
171182
provider_network: ProviderNetworkType = strawberry_django.field(select_related=["provider_network"])

netbox/core/graphql/types.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
@strawberry_django.type(
2020
models.DataFile,
2121
exclude=['data',],
22-
filters=DataFileFilter
22+
filters=DataFileFilter,
23+
pagination=True
2324
)
2425
class DataFileType(BaseObjectType):
2526
source: Annotated["DataSourceType", strawberry.lazy('core.graphql.types')]
@@ -28,7 +29,8 @@ class DataFileType(BaseObjectType):
2829
@strawberry_django.type(
2930
models.DataSource,
3031
fields='__all__',
31-
filters=DataSourceFilter
32+
filters=DataSourceFilter,
33+
pagination=True
3234
)
3335
class DataSourceType(NetBoxObjectType):
3436

@@ -38,12 +40,17 @@ class DataSourceType(NetBoxObjectType):
3840
@strawberry_django.type(
3941
models.ObjectChange,
4042
fields='__all__',
41-
filters=ObjectChangeFilter
43+
filters=ObjectChangeFilter,
44+
pagination=True
4245
)
4346
class ObjectChangeType(BaseObjectType):
4447
pass
4548

4649

47-
@strawberry_django.type(DjangoContentType, fields='__all__')
50+
@strawberry_django.type(
51+
DjangoContentType,
52+
fields='__all__',
53+
pagination=True
54+
)
4855
class ContentType:
4956
pass

0 commit comments

Comments
 (0)