Пользовательский скаляр в 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());
}
}