torchbox / wagtail-grapple

A Wagtail app that makes building GraphQL endpoints a breeze!

Home Page:https://wagtail-grapple.readthedocs.io/en/latest/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support passing `deprecation_reason` and `description` Graphene type arguments.

Morsey187 opened this issue · comments

Description
Graphene supports the Scalar type argument deprecation_reason and description, this can be useful for maintaining a public endpoint as it provides metadata for tools using schema.json such as GraphiQL.

Theres currently some overlap with the arguments passed from wagtail_grapple's field types to graphenes, i.e name and required, however, deprecation_reason and description aren't supported or possible to pass in as keyword arguments, mainly due to how the GraphQLField constructor and subsequent utility methods
(get_field_type()) pass in arguments and constuct Graphene types.

Proposal
I'd like to propose either supporting passing in all arguments as kwargs to graphene, popping wagtail_grapple specific arguments in the constructor for example something similar to the below:

# models.py
class GraphQLField:
    field_name: str
    field_type: str
    field_source: str

    def __init__(
        self, field_name: str, field_type: type = None, required: bool = None, **kwargs
    ):
        # Initiate and get specific field info.
        self.field_name = field_name
        self.field_type = field_type
        self.field_source = kwargs.pop("source", field_name)

        # # Add support for NonNull/required fields
        # if required:
        #     self.field_type = graphene.NonNull(field_type)

        # Legacy collection API (Allow lists):
        self.extract_key = kwargs.pop("key", None)
        is_list = kwargs.pop("is_list", False)
        if is_list:
            self.field_type = graphene.List(field_type)

        self.field_kwargs = kwargs

---
# actions.py
def get_field_type(field):
    # If a tuple is returned then obj[1] wraps obj[0]
    field_wrapper = None
    if isinstance(field, tuple):
        field, field_wrapper = field
        if callable(field):
            field = field()
    print("field.field_kwargs", field.field_kwargs)

    field_type = field.field_type

    if field_type is not None:
        if field_wrapper:
            return field, field_wrapper(field_type, **field.field_kwargs)
        else:
            return field, graphene.Field(field_type, **field.field_kwargs)

Otherwise if this approach isn't ideal, as I'd imagine we don't want to support graphene's default_value argument or potential issues with allowing any values to being passed in, I'd suggest we expand the GraphQLField constructor and related code to support description and deprecation_reason fields specifically.

        self.field_description = kwargs.get("description")
        self.field_deprecation_reason = kwargs.get("deprecation_reason")

With some guidance on the above, I could open a pull request with additional test coverage.

@Morsey187 this sounds like a sensible proposal. A PR is most welcome