-
Notifications
You must be signed in to change notification settings - Fork 179
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
Adding contrib for GraphQL Relay #1214
base: main
Are you sure you want to change the base?
Conversation
Based on the request from #1213 (comment) I introduced the following way to provide utility for Query.node object resolving: By default the query = RelayQueryType()
...
@query.node.node_resolver("Ship") # special node_resolver decorator
async def resolve_ship(_, info, bid: str):
ships = [{"__typename": "Ship", **ship} for ship in SHIPS if ship["id"] == bid]
return ships[0] The above would be the minimal one need to do to achieve a Others will have the ability to provide means for a more customized behavior, like having a custom global ID field: def decode_global_id(kwargs) -> GlobalIDTuple:
return GlobalIDTuple(*b64decode(kwargs["bid"]).decode().split(":"))
node = RelayNodeInterfaceType(
global_id_decoder=decode_global_id,
)
query = RelayQueryType(
node=node,
) Finally one can just reset the query = RelayQueryType()
@query.field("node") # standard Aridane field decorator
async def resolve_node(_, info, bid: str):
ships = [{"__typename": "Ship", **ship} for ship in SHIPS if ship["id"] == bid]
return ships[0] |
…the option to use connections, add unit tests
…resolver used by the node query
dd0f0c9
to
e5ee27b
Compare
This newest version allows one to use the query = RelayQueryType(
global_id_decoder=decode_global_id,
)
ship = RelayObjectType("Ship")
@ship.node_resolver
async def resolve_ship(_, info, bid: str):
ships = [{"__typename": "Ship", **ship} for ship in SHIPS if ship["id"] == bid]
return ships[0] Thanks @reallistic! |
Related to #1213.
Important
The schema used for this example comes from https://relay.dev/docs/guides/graphql-server-specification/#schema
Doc strings with examples are yet to come so here's a brief manual on how to use this:
RelayQueryType
Use the QueryType that enforces the
node
GQL logic while providing some utility:or if you have the node resolvers already:
You can map to a different
id
field if yourNode
interface specifies something else thanid
, likebid
:RelayObjectType and RelayConnection
There's the
RelayObjectType
which is similar to the standardObjectType
but has the relay "pagination" logic encapsulated in theconnection
decorator. The decorator takes a resolver that will later be invoked with an additionalconnection_arguments
argument that holds yourfirst
,last
,after
,before
. The resolver is expected to fetch a slide of data from the resource's storage and return it, encapsulated in aRelayConnection
instance with additional pagination data - in gist - the resolver is responsible for the page calculations.RelayConnection
is something one would want to overload to provide some repeatable utility, maybe you'd like aDjangoRelayConnection
to operate on a Django ORM QuerySet and maybe calculate the paging there to reduce the work that's needed to be done in the resolver. Overloadingget_cursor
,get_page_info
,get_edges
onRelayConnection
should enable one to achieve a lot but here it's important to listen to the use cases people might have.I'm open to feedback, thanks :)