name
이라면 resolver 메소드의 이름은 resolve_full_name
이 되어야 한다.Parent Value Object (parent)
Query
필드와 같은 상위 필드(parent field)가 없는 경우, 상위 값(parent value)은 쿼리를 실행하는 동안 구성된 root_value
로 설정 된다(default=None).아래의 예시로 살펴보는 것이 더 쉽다.
from graphene import ObjectType, String, Field
class Person(ObjectType):
full_name = String()
def resolve_full_name(parent, info):
return f"{parent.first_name} {parent.last_name}"
class Query(ObjectType):
me = Field(Person)
def resolve_me(parent, info):
# returns an object that represents a Person
return get_human(name="Luke Skywalker")
parent
: 쿼리 실행의 root_value로 설정 된다.Query.resolve_me
: 인자로 parent=None
이 들어가며 이 때 객체인 Person("Luke", "Skywalker")
가 반환 된다.Person.resolve_full_name
메소드가 호출될 때 parent
의 값으로 들어 간다.resolve_full_name
은 스칼라를 반환하며 반환되는 String은 "Luke Skywalker"이다.parent
인자의 value로 들어가는 Parent Value Object
를 반환하며 이 객체는 다음 resolver의 실행에 사용 된다.parent
는 obj
, source
라는 이름으로 사용될 수 있다.root
, Person value object의 경우 person
GraphQL Execution Info(info)
info
인자는 현재 GraphQL 쿼리 실행에 대한 메타 정보 참조용(fields, schema, parsed query 등)으로 사용 된다.info
인자를 통해 사용자 인증, 데이터 로더 인스턴스 또는 쿼리를 해결하기 위해 유용한 모든 것을 저장하는 데 사용할 수 있는 요청별 컨텍스트에 접근이 가능하다.GraphQL Arguments(kwargs)
아래의 예시를 보면, name이 **kwargs
에 해당한다.
from graphene import ObjectType, Field, String
class Query(ObjectType):
human_by_name = Field(Human, name=String(required=True))
def resolve_human_by_name(parent, info, name):
return get_human(name=name)
또는 아래와 같이 타입의 속성으로 args
를 사용해 정의된 값을 전달할 수도 있다.
- 여기서는 description
from graphene import ObjectType, Field, String
class Query(ObjectType):
answer = String(args={'description': String()})
def resolve_answer(parent, info, description):
return description
Implicit staticmethod
self
가 아니다.parent
이다.parent value object
를 사용할 지에 더 집중하기 때문일 것이다.from graphene import ObjectType, String
class Person(ObjectType):
first_name = String()
last_name = String()
@staticmethod
def resolve_first_name(parent, info):
'''
실제로 resolve method를 사용하기 위해 @staticmethod 데코레이터를
명시적으로 사용할 필요는 없다!
'''
return parent.first_name
Default Resolver
parent
인자의 타입이 dictionary라면 resolver는 field name과 일치하는 dictionary key를 알아서 찾는다.required=True
를 넘겨주어야 한다.[문제 상황]
스키마
from graphene import ObjectType, String
class Query(ObjectType):
hello = String(required=True, name=String())
def resolve_hello(parent, info, name):
return name if name else 'World'
쿼리
query {
hello
}
에러
TypeError: resolve_hello() missing 1 required positional argument: 'name'
[해결책]
1. 모든 keyword argument를 dict로(**kwargs 이용) 묶는다.
from graphene import ObjectType, String
class Query(ObjectType):
hello = String(required=True, name=String())
def resolve_hello(parent, info, **kwargs):
name = kwargs.get('name', 'World')
return f'Hello, {name}!'
from graphene import ObjectType, String
class Query(ObjectType):
hello = String(required=True, name=String())
def resolve_hello(parent, info, name='World'):
return f'Hello, {name}!'
from graphene import ObjectType, String
class Query(ObjectType):
hello = String(
required=True,
name=String(default_value='World')
)
def resolve_hello(parent, info, name):
return f'Hello, {name}!'
from graphene import ObjectType, String
def resolve_full_name(person, info):
return f"{person.first_name} {person.last_name}"
class Person(ObjectType):
first_name = String()
last_name = String()
full_name = String(resolver=resolve_full_name)
ObjectType
에 대한 schema description은 docstring 또는 Meta class에 정의된 description을 이용할 수 있다.from graphene import ObjectType
class MyGraphQlSong(ObjectType):
''' We can set the schema description for an Object Type here on a docstring '''
class Meta:
name = 'Song'
description = 'But if we set the description in Meta, this value is used instead'
interfaces
: 해당 객체가 구현하는 GraphQL interfaces를 정의한다.possible_types
: interfaces 또는 Union과 같은 애매한 타입을 resolve 하는 데 도움을 줄 수 있다. from graphene import ObjectType, Node
Song = namedtuple('Song', ('title', 'artist'))
class MyGraphQlSong(ObjectType):
class Meta:
interfaces = (Node, )
possible_types = (Song, )