Spring Boot 如何在graphql中定义Java Map?

wgeznvg7  于 2023-06-22  发布在  Spring
关注(0)|答案(2)|浏览(237)

我有一个filterModel,它是一个Map Map<String, ColumnFilter> filterModel,以便过滤我的Actor数据。当我试图过滤我的数据时,我从客户端获得一个filterModel对象。如何在graphql查询中定义此Java Map?
来自客户端的filterModel对象:

filterModel: {
               firstname: {filterType: 'text', type: 'contains', filter: 'Tom'}, ...
              }

模式:

type Actor {
    actorId: ID!,
    firstName: String,
    lastName: String,
}

type Query {
    rows(
        filterModel: [filterModel]
    ): [Actor]
}

input filterModel {
    key: String,
    value: ColumnFilter
}

input ColumnFilter {
    filterType: String,
    type: String,
    filter: String
}
hyrbngr7

hyrbngr71#

GraphQL中没有map类型。因为map基本上包含动态键和,所以它们不能很好地适应GraphQL所期望的静态类型。
如果您真的不确定Map中的数据将是什么类型,您可以始终将动态信息存储为String。这是我个人会做的事情。
所以你的filterModel将变成filterModel:String,而这个字符串将是对象的JSON表示。您可以在代码中执行JSON解析,将其转换回Map

fnx2tebb

fnx2tebb2#

0输入

mutation{ xxxx(employeeBean:{ xxxxx , attributes: {\"key\":\"value\"}" }) {
xxxxxxx attributes }}

1.模式文件

scalar JSON
type Employee {
   
   ........
   attributes: JSON
}

1.configuration

@Bean
public RuntimeWiringConfigurer runtimeWiringConfigurer() {
    return wiringBuilder -> wiringBuilder
            .scalar(jsonScalar());
}

public GraphQLScalarType jsonScalar() {
    ObjectMapper objectMapper = new ObjectMapper();
    return GraphQLScalarType.newScalar()
            .name("JSON") //graphql type define in the schema file
            .description("Java MAP as scalar.")
            .coercing(new Coercing<Map<String, String>, String>() {
                @Override
                public String serialize(final Object dataFetcherResult) {
                    if (dataFetcherResult instanceof Map) {
                        try {
                            return objectMapper.writeValueAsString(dataFetcherResult);
                        } catch (JsonProcessingException e) {
                            throw new RuntimeException(e);
                        }
                    } else {
                        throw new CoercingSerializeException("Expected a Map object.");
                    }
                }

                @Override
                public Map<String, String> parseValue(final Object input) {

                    if (input instanceof StringValue) {
                        try {
                            return objectMapper.readValue(input.toString()
                                    , new TypeReference<Map<String, String>>() {
                                    });

                        } catch (JsonProcessingException e) {
                            throw new CoercingParseLiteralException(e);
                        }
                    } else {
                        throw new CoercingParseValueException("Expected a String");
                    }
                }

                @Override
                public Map<String, String> parseLiteral(final Object input) {
                    if (input instanceof StringValue) {
                        try {
                            return objectMapper.readValue(((StringValue) input).getValue()
                                    , new TypeReference<Map<String, String>>() {
                                    });
                        } catch (JsonProcessingException e) {
                            throw new CoercingParseLiteralException(e);
                        }
                    } else {
                        throw new CoercingParseLiteralException("Expected a StringValue.");
                    }
                }
            }).build();

}

3豆

public class EmployeeBean {

private Map<String,String> attributes;
}

注意事项

GraphQlArgumentBinder-> public Object bind(DataFetchingEnvironment environment,@Nullable String argumentName,ResolvableType targetType)抛出BindException {}无法将值绑定到map对象,因为它使用了在模式中定义的map名称,然后将点和第一个键名放在bean中搜索该名称以找到map,并且它目前无法工作

相关问题