We are planning use Graphql as backend server in our application. We choose Graphql-Java to develop our POC. We came across a stituation to create our own scalartype to handle java.util.Map object type.
we havent found any documentation regarding creating a custom scalar type.
In example code as below
RuntimeWiring buildRuntimeWiring() {
return RuntimeWiring.newRuntimeWiring()
.scalar(CustomScalar)
how to was the implementation done for CustomScalar object.
need help.
To get a general idea how to make a scalar, just take a look into the existing ones and do something similar.
For a dynamic object scalar, take a look at graphql-spqr's object scalar implementation and do something similar:
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());
}
});
}
In code first approach (SPQR v0.9.6) adding @GraphQLScalar is enough.
Or, as alternative, add scalar definition to GraphQLSchemaGenerator:
new GraphQLSchemaGenerator()
.withScalarMappingStrategy(new MyScalarStrategy())
And define MyScalarStrategy:
class MyScalarStrategy extends DefaultScalarStrategy {
@Override
public boolean supports(AnnotatedType type) {
return super.supports(type) || GenericTypeReflector.isSuperType(MyScalarStrategy.class, type.getType());
}
}