Skip to content

Support for context sharing between parent and child types/fields #3972

@metatick

Description

@metatick

Feature Request Type

  • Core functionality
  • Alteration (enhancement/optimization) of existing feature(s)
  • New behavior

Description

In some cases it would be helpful if child objects/fields could access information about a parent object, especially for deeply nested types.

For example:

@strawberry.type
class User:
    id: int
    editor: bool
    pages: List[Page]

@strawberry.type
class Page:
   id: int
   title: str
   comments: List[Comment]

@strawberry.type
class Comment:
    id: int
    comment: str
    @strawberry.field()
    def can_edit(self) -> bool:
        # get the user from current context, somehow
        user = get_user_from_context()
        if not user:
            raise Exception("This field is only valid when queried under a User object")
        return user.editor

@strawberry.type
class Query:
    users: List[User]
    pages: List[Page]

query {
    users {
        id
        pages {
            id
            title
            comments {
                id
                comment
                canEdit
            }
        }
    }
}

This can sort-of be achieved by storing information on info.context, but as far I can tell there isn't a safe way for this to be done for (at least) two reasons:

  1. In async context fields may not be resolved deterministically, so the information in info may or may not be valid for the current ancestor of the field
  2. There isn't a straightforward way, at least that I can see, to easily remove information from context after all fields in an object have been resolved

It would be nice if there was some sort of context available on info that could be automatically pushed/popped as fields are resolved, so that something like this could work as expected:

@strawberry.type
class User:
    id: int
    editor: bool
    @strawberry.field()
    def pages(self, info) -> List[Page]:
        # user would be available to all descendants of User.pages, and be removed after User.pages completes
        info.field_context.set('user', self)         
        return get_pages()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions