Search code examples
pythongraphene-pythonstrawberry-graphqlariadne-graphqlgraphql-python

Setting **kwargs like parameter in resolver function


I'm using Strawberry for GraphQL with FastAPI and SQLAlchemy. I have about 20 tables in MySQL. I'm using SQLAlchemy for models (inherit DeclarativeBase). For strawberry models I'm using strawberry-sqlalchemy-mapper. I could write a third layer of models as filters (@strawberry.input), but that doesn't sound good.

I've encountered the following problems:

  • Can't use undetermined parameters in client-side queries without setting up each parameter at Strawberry resolver (server-side Query);
  • Couldn't create universal Filter class (based on @strawberry.input -> GPT Generated Example).

I need something similar to the code in the picture above so I can write GraphQL query with some parameters and get response without error. I want to retrieve a dictionary-like data of client request parameters and process it, instead of defining each parameter manually. I can work with Info object, however Strawberry still won't skip undefined parameters

I haven't looked at how Graphene or Ariadne works, is there a way to solve this problem there?


Solution

  • This is possible in strawberry. It requires working with lower-level APIs, simulating what strawberry.field does with parameters. Here's a minimal example:

    import strawberry
    from strawberry.annotation import StrawberryAnnotation
    from strawberry.arguments import StrawberryArgument
    
    
    # no @strawberry.type yet
    class Query:
        @strawberry.field
        def dynamic(self, **kwargs: object) -> list[str]:
            return list(kwargs)
    
    
    fields = {'x': int, 'y': str}  # from a dynamic schema
    Query.dynamic.base_resolver.arguments = [
        StrawberryArgument(name, name, StrawberryAnnotation(fields[name])) for name in fields
    ]
    schema = strawberry.Schema(strawberry.type(Query))
    
    % strawberry export-schema ...
    type Query {
      dynamic(x: Int!, y: String!): [String!]!
    }