Пользовательский скаляр в Graphql-Java

Мы планируем использовать Graphql в качестве внутреннего сервера в нашем приложении. Мы выбираем Graphql-Java для разработки нашего POC. Мы столкнулись с ситуацией, когда создали собственный скалярный тип для обработки типа объекта java.util.Map.

мы не нашли никакой документации относительно создания пользовательского скалярного типа. В примере кода, как показано ниже

RuntimeWiring buildRuntimeWiring() {
    return RuntimeWiring.newRuntimeWiring()
            .scalar(CustomScalar)

как была реализована реализация объекта CustomScalar. нужна помощь.

2 ответа

Решение

Чтобы получить общее представление о том, как сделать скаляр, просто взгляните на существующие и сделайте что-то подобное.

Для динамического скалярного объекта, взгляните на реализацию скалярного объекта graphql-spqr и сделайте что-то похожее:

public static GraphQLScalarType graphQLObjectScalar(String name) {
        return new GraphQLScalarType(name, "Built-in object scalar", new Coercing() {

            @Override
            public Object serialize(Object input) {
                return input;
            }

            @Override
            public Object parseValue(Object input) {
                return input;
            }

            @Override
            public Object parseLiteral(Object input) {
                return parseFieldValue((Value) input);
            }

            //recursively parse the input into a Map
            private Object parseFieldValue(Value value) {
                if (value instanceof StringValue) {
                    return ((StringValue) value).getValue();
                }
                if (value instanceof IntValue) {
                    return ((IntValue) value).getValue();
                }
                if (value instanceof FloatValue) {
                    return ((FloatValue) value).getValue();
                }
                if (value instanceof BooleanValue) {
                    return ((BooleanValue) value).isValue();
                }
                if (value instanceof EnumValue) {
                    return ((EnumValue) value).getName();
                }
                if (value instanceof NullValue) {
                    return null;
                }
                if (value instanceof ArrayValue) {
                    return ((ArrayValue) value).getValues().stream()
                            .map(this::parseFieldValue)
                            .collect(Collectors.toList());
                }
                if (value instanceof ObjectValue) {
                    return ((ObjectValue) value).getObjectFields().stream()
                            .collect(Collectors.toMap(ObjectField::getName, field -> parseFieldValue(field.getValue())));
                }
                //Should never happen, as it would mean the variable was not replaced by the parser
                throw new IllegalArgumentException("Unsupported scalar value type: " + value.getClass().getName());
            }
        });
    }

При первом подходе к коду (SPQR v0.9.6) достаточно добавить @GraphQLScalar. Или, в качестве альтернативы, добавьте скалярное определение в GraphQLSchemaGenerator:

new GraphQLSchemaGenerator()
.withScalarMappingStrategy(new MyScalarStrategy())

И определить MyScalarStrategy:

class MyScalarStrategy extends DefaultScalarStrategy {

@Override
public boolean supports(AnnotatedType type) {
  return super.supports(type) || GenericTypeReflector.isSuperType(MyScalarStrategy.class, type.getType());
}
}
Другие вопросы по тегам