From 981a7f665a5927fc779223d72dfe6f9a1a04f36a Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Wed, 18 May 2016 21:27:55 -0700 Subject: [PATCH] Updated docs adding resolver page with @with_context instructions. Fixed #164 --- docs/config.toml | 53 ++++++++++----------- docs/pages/docs/django/authorization.md | 17 ++++--- docs/pages/docs/resolvers.md | 62 +++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 33 deletions(-) create mode 100644 docs/pages/docs/resolvers.md diff --git a/docs/config.toml b/docs/config.toml index 2a031de9..74b843ea 100644 --- a/docs/config.toml +++ b/docs/config.toml @@ -2,35 +2,36 @@ siteTitle = "Graphene" ga = "UA-12613282-7" [docs.quickstart] - name = "Quickstart" - pages = [ - "/docs/quickstart/", - ] + name = "Quickstart" + pages = [ + "/docs/quickstart/", + ] [docs.walkthrough] - name = "Walkthrough" - pages = [ - "/docs/interfaces/", - "/docs/objecttypes/", - "/docs/mutations/", - "/docs/basic-types/", - "/docs/enums/", - "/docs/relay/", - ] + name = "Walkthrough" + pages = [ + "/docs/interfaces/", + "/docs/objecttypes/", + "/docs/resolvers/", + "/docs/mutations/", + "/docs/basic-types/", + "/docs/enums/", + "/docs/relay/", + ] [docs.django] - name = "Django" - pages = [ - "/docs/django/tutorial/", - "/docs/django/filtering/", - "/docs/django/authorization/", - "/docs/django/introspection-schema/", - "/docs/django/debug/", - ] + name = "Django" + pages = [ + "/docs/django/tutorial/", + "/docs/django/filtering/", + "/docs/django/authorization/", + "/docs/django/introspection-schema/", + "/docs/django/debug/", + ] [docs.sqlalchemy] - name = "SQLAlchemy" - pages = [ - "/docs/sqlalchemy/tutorial/", - "/docs/sqlalchemy/tips/", - ] + name = "SQLAlchemy" + pages = [ + "/docs/sqlalchemy/tutorial/", + "/docs/sqlalchemy/tips/", + ] diff --git a/docs/pages/docs/django/authorization.md b/docs/pages/docs/django/authorization.md index 3bc54ed1..cf288a21 100644 --- a/docs/pages/docs/django/authorization.md +++ b/docs/pages/docs/django/authorization.md @@ -58,7 +58,7 @@ class Query(ObjectType): ## User-based Queryset Filtering If you are using `graphql-django-view` you can access Django's request object -via `info.request_context`. +via `with_context` decorator. ```python from graphene import ObjectType @@ -71,18 +71,20 @@ class Query(ObjectType): class Meta: abstract = True - def resolve_my_posts(self, args, info): - if not info.request_context.user.is_authenticated(): + @with_context + def resolve_my_posts(self, args, context, info): + # context will reference to the Django request + if not context.user.is_authenticated(): return [] else: - return Post.objects.filter(owner=info.request_context.user) + return Post.objects.filter(owner=context.user) ``` If you're using your own view, passing the request context into the schema is simple. ```python -result = schema.execute(query, request_context=request) +result = schema.execute(query, context_value=request) ``` ## Filtering ID-based node access @@ -100,13 +102,14 @@ class PostNode(DjangoNode): only_fields = ('title', 'content') @classmethod - def get_node(Cls, id, info): + @with_context + def get_node(Cls, id, context, info): try: post = Cls._meta.model.objects.get(id=id) except Cls._meta.model.DoesNotExist: return None - if post.published or info.request_context.user is post.owner: + if post.published or context.user is post.owner: return Cls(instance) else: return None diff --git a/docs/pages/docs/resolvers.md b/docs/pages/docs/resolvers.md new file mode 100644 index 00000000..073fac99 --- /dev/null +++ b/docs/pages/docs/resolvers.md @@ -0,0 +1,62 @@ +--- +title: Resolvers +description: Walkthrough Resolvers +--- + +# Resolvers + +A resolver is a method that resolves certain field within a `ObjectType`. +The resolver of a field will be, if not specified otherwise, the `resolve_{field_name}` within the `ObjectType`. + +By default a resolver will take the `args`, and `info` arguments. +*This is likely to be simplified in the future*. + + +## Quick example + +This example model defines a `Query` type, which has a reverse field that reverses the given `word` +argument using the `resolve_reverse` method in the class. + +```python +import graphene + +class Query(graphene.ObjectType): + reverse = graphene.String(word=graphene.String()) + + def resolve_reverse(self, args, info): + word = args.get('word') + return word[::-1] +``` + +## Resolvers outside the class + +A field could also specify a custom resolver outside the class: + +```python +import graphene + +def reverse(root, args, info): + word = args.get('word') + return word[::-1] + +class Query(graphene.ObjectType): + reverse = graphene.String(word=graphene.String(), resolver=reverse) +``` + + +## Context + +A query in a GraphQL schema could have some context that we can use in any resolver. +In this case we need to decorate the resolver function with `with_context`. + +```python +class Query(graphene.ObjectType): + name = graphene.String() + + @with_context + def resolve_name(self, args, context, info): + return context['name'] + + +result = schema.execute(query, context_value={'name': 'Peter'}) +```