10

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.

KrishnaFJ
  • 155
  • 1
  • 2
  • 8

2 Answers2

8

To get a general idea how to make a scalar, just take a look into the existing ones and do something similar.

graphql-java also has a separate project for extra scalars: graphql-java-extended-scalars. And there you can find the object scalar (a.k.a. JSON scalar), that can be used for dynamic structures, like Maps.

Register it via:

RuntimeWiring.newRuntimeWiring().scalar(ExtendedScalars.Object)
kaqqao
  • 12,984
  • 10
  • 64
  • 118
  • 1
    how do I utilize above scaler into my code? I've a Spring-boot application and it'll help if you could provide an example. – Simple-Solution Dec 07 '17 at 09:37
  • @Simple-Solution How do you use any built-in scalar, like String or Integer? There's no difference. – kaqqao Dec 07 '17 at 10:14
  • Not sure I understand what you mean. But those; String and Integer are built in and it all happens automatically. So above scalar is for object and I would need to create one for Map, right? Do you've an example. Also what is the significant of the `name` argument? Is that the name of the type we defined in the schema? – Simple-Solution Dec 07 '17 at 11:40
  • @Simple-Solution Happens automatically? Does that mean you're using GraphQL-SPQR? If so, annotate the type at the place of use with `@GraphQLScalar` (e.g. annotated a method argument) or use a different `ScalarMappingStrategy` (e.g. `gen.withScalarMappingStrategy(new MapScalarStrategy())`). Without SPQR, there's no automatic mapping. You set a type of each field, e.g. `newFieldDefinition().type(Scalars.GraphQLString)`, so you can use `newFieldDefinition().type(Scalars.graphQLObjectScalar("typeName"))` instead. You'll get a `Map` just like for any object input, but with a dynamic structure. – kaqqao Dec 07 '17 at 12:45
  • 1
    @Simple-Solution If using schema-first with graphql-java directly, you can use a custom scalar via `RuntimeWiring.newRuntimeWiring().scalar(Scalars.graphQLObjectScalar("typeN‌​ame"))`. Mind you, in the 2nd and the 3rd example `Scalars` is `io.leangen.graphql.util.Scalars` not `graphql.Scalars`. Or just copy the SPQR code into your own class. – kaqqao Dec 07 '17 at 12:51
  • Never knew `GraphQL-SPQR` existed, I'm using Code-first approach, where I've a `schema.graphqls` file which holds my type/api definition. Do you know how does that fit into my approach? Here is another question i asked yesterday: https://stackoverflow.com/questions/47677140/graphql-schema-equivalent-of-this-json/47691101?noredirect=1#comment82347617_47691101 – Simple-Solution Dec 07 '17 at 13:00
  • @Simple-Solution If you have a schema in a file, that's a schema-first approach. And I've given you the exact literal code you need to add. I can't help you further. You seem to need some more reading of the docs first. – kaqqao Dec 07 '17 at 13:02
  • Where do you guys declare this class. I follow the example of http://graphql-java.readthedocs.io/en/latest/scalars.html where `public static class EmailScalar` is declared but the compiler fails because it is not allowed to just declare a static class anywhere. I cannot find the explaination where to declare this class actually – xetra11 May 14 '18 at 09:33
  • @xetra11 It's an instance of `GraphQLScalarType`, not a class. And who says it needs to be static? – kaqqao May 14 '18 at 22:34
0

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());
}
}
Olga
  • 3,705
  • 1
  • 20
  • 23