Strawberry GraphQL return dict

5.1k views Asked by At

I want to create a mutation which takes a dict as an argument. There are implementation-specific reasons to want to do this, instead of creating a type/schema for the dict object.

Object

# types.py
import typing


@strawberry.type
class Thing:
    data: typing.Dict

Resolver

# resolvers.py
import typing
from .types import Thing


def create_config(data: typing.Dict) -> Thing:
    pass

Mutation Schema

# mutations.py
import strawberry

from .types import Thing
from .resolvers import create_thing


@strawberry.type
class Mutations:
    create_thing: Thing = strawberry.mutation(resolver=create_thing)

Desired Example Query

mutation {
    createThing(data: {}) {}
}

From reading the documentation, there's no GraphQL scalar equivalent for a dict. This is evidenced by this compilation error when I try to test:

TypeError: Thing fields cannot be resolved. Unexpected type 'typing.Dict'

My instinct is to flatten the dict into a JSON string and pass it that way. This seems un-elegant, which makes me think there's a more idiomatic approach. Where should I go from here?

2

There are 2 answers

2
A. Coady On BEST ANSWER

Instead of a serialized JSON string, JSON itself can be a scalar.

from strawberry.scalars import JSON

@strawberry.type
class Thing:
    data: JSON

def create_config(data: JSON) -> Thing:
    pass
0
Jordy Mendoza On

Adding to A. Coady's answer above and noting the need of escaping quotes, if you have a dictionary that you would want to pass into the create_config, you can convert it into a string and do a json.dump to convert it to a json object like so:

import json
data = {{"key1":"name1"},{"key2":"name2"},{"key3":"name3"}}
data = json.dump(str(data))
create_config(data)

You just have to be pretty careful that you are putting a valid string cast dictionary in there because it will take anything, so it would be pretty easy to break.