Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I handle long Int with GraphQL?

As you know that GraphQL has no data type like long int. So, whenever the number is something big like 10000000000, it throws an error like this: Int cannot represent non 32-bit signed integer value: 1000000000000

For that I know two solutions:

  1. Use scalars.
import { GraphQLScalarType } from 'graphql';
import { makeExecutableSchema } from '@graphql-tools/schema';

const myCustomScalarType = new GraphQLScalarType({
  name: 'MyCustomScalar',
  description: 'Description of my custom scalar type',
  serialize(value) {
    let result;
    return result;
  },
  parseValue(value) {
    let result;
    return result;
  },
  parseLiteral(ast) {
    switch (ast.kind) {
    }
  }
});

const schemaString = `

scalar MyCustomScalar

type Foo {
  aField: MyCustomScalar
}

type Query {
  foo: Foo
}

`;

const resolverFunctions = {
  MyCustomScalar: myCustomScalarType
};

const jsSchema = makeExecutableSchema({
  typeDefs: schemaString,
  resolvers: resolverFunctions,
});
  1. Use apollo-type-bigint package.

Both of those solutions convert the big int to string, and I'd rather not use string (I prefer a number type).

like image 820
Harsh Patel Avatar asked Jul 14 '20 11:07

Harsh Patel


People also ask

Is GraphQL strong typing?

Strongly-typed: GraphQL is strongly-typed. Given a query, tooling can ensure that the query is both syntactically correct and valid within the GraphQL type system before execution, i.e. at development time, and the server can make certain guarantees about the shape and nature of the response.

How do you use scalar in GraphQL?

The GraphQL specification includes default scalar types Int , Float , String , Boolean , and ID . Although these scalars cover the majority of use cases, some applications need to support other atomic data types (such as Date ) or add validation to an existing type. To enable this, you can define custom scalar types.

What is scalar type in GraphQL?

GraphQL's Scalar Types Int: A signed 32‐bit integer. Float: A signed double-precision floating-point value. String: A UTF‐8 character sequence. Boolean: true or false. ID: The ID scalar type represents a unique identifier, often used to refetch an object or as the key for a cache.


2 Answers

Correct, there's no concept like bigInt in graphQL.

You can try one of these:

  1. Set type as Float instead of Int - it will handle all large int values and also send them as number [below are technically options, although you stated you don't like string solutions]
  2. Set type as String, as you described
  3. Give (an npm-provided data type, like) BigInt, as you described. It will handle big int, but will convert your values into string

npm bigInt dependency options:

  • https://www.npmjs.com/package/apollo-type-bigint
  • https://www.npmjs.com/package/graphql-bigint
  • https://www.npmjs.com/package/graphql-type-bigint
like image 104
lazzy_ms Avatar answered Oct 22 '22 09:10

lazzy_ms


Graphql has introduced Scalars. I am using Java and so I can provide some solution in Java. You can achieve the same by following the below steps.

in your .graphqls file please define scalar

scalar Long

type Movie{
movieId: String
movieName: String
producer: String
director: String
demoId : Long
}

Now you have to register this scalar in your wiring.

return RuntimeWiring.newRuntimeWiring().type("Query", typeWiring -> typeWiring
                .dataFetcher("allMovies", allMoviesDataFetcher).dataFetcher("movie", movieDataFetcher)
                .dataFetcher("getMovie", getMovieDataFetcher)).scalar(ExtendedScalars.GraphQLLong).build();

Now you have to define the Scalar configuration for Long as below.


@Configuration
public class LongScalarConfiguration {
     @Bean
        public GraphQLScalarType longScalar() {
            return GraphQLScalarType.newScalar()
                .name("Long")
                .description("Java 8 Long as scalar.")
                .coercing(new Coercing<Long, String>() {
                    @Override
                    public String serialize(final Object dataFetcherResult) {
                        if (dataFetcherResult instanceof Long) {
                            return dataFetcherResult.toString();
                        } else {
                            throw new CoercingSerializeException("Expected a Long object.");
                        }
                    }

                    @Override
                    public Long parseValue(final Object input) {
                        try {
                            if (input instanceof String) {
                                return new Long((String) input);
                            } else {
                                throw new CoercingParseValueException("Expected a String");
                            }
                        } catch (Exception e) {
                            throw new CoercingParseValueException(String.format("Not a valid Long: '%s'.", input), e
                            );
                        }
                    }

                    @Override
                    public Long parseLiteral(final Object input) {
                        if (input instanceof StringValue) {
                            try {
                                return new Long(((StringValue) input).getValue());
                            } catch (Exception e) {
                                throw new CoercingParseLiteralException(e);
                            }
                        } else {
                            throw new CoercingParseLiteralException("Expected a StringValue.");
                        }
                    }
                }).build();
        }

}

It should solve your problem. Please give it a try for Java related application.

like image 25
Kushagra Bindal Avatar answered Oct 22 '22 09:10

Kushagra Bindal