我如何使用 GraphQL 处理 long Int?
How can I handle long Int with GraphQL?
如您所知,GraphQL 没有像 long int 这样的数据类型。因此,每当数字大到 10000000000
时,它就会抛出这样的错误:Int cannot represent non 32-bit signed integer value: 1000000000000
为此我知道两个解决方案:
- 使用标量。
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,
});
这两个解决方案都将 big int 转换为 string
,我宁愿不使用字符串(我更喜欢数字类型)。
在这种情况下,我建议使用 graphql-bigint 包。此实现为您提供 53 位整数。任何高于 52 位的类似整数的数字都会截断其较低的值。所以如果你需要52位以上,使用字符串会更安全。
正确,graphQL
中没有像 bigInt
这样的概念。
您可以尝试以下方法之一:
- 将类型设置为
Float
而不是 Int
- 它将处理所有大的 int 值并将它们作为 number
发送
[下面是技术上的选择,虽然你说你不喜欢 string
解决方案]
- 按照您的描述将类型设置为
String
- 按照您的描述提供(npm 提供的数据类型,例如)
BigInt
。它将处理大整数,但会将您的值转换为 string
npm bigInt 依赖选项:
Graphql 引入了标量。我正在使用 Java,所以我可以在 Java 中提供一些解决方案。您可以按照以下步骤实现相同的目的。
请在您的 .graphqls 文件中定义标量
scalar Long
type Movie{
movieId: String
movieName: String
producer: String
director: String
demoId : Long
}
现在您必须在布线中注册此标量。
return RuntimeWiring.newRuntimeWiring().type("Query", typeWiring -> typeWiring
.dataFetcher("allMovies", allMoviesDataFetcher).dataFetcher("movie", movieDataFetcher)
.dataFetcher("getMovie", getMovieDataFetcher)).scalar(ExtendedScalars.GraphQLLong).build();
现在您必须如下定义 Long 的标量配置。
@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();
}
}
应该可以解决你的问题。请试一试 Java 相关应用。
如您所知,GraphQL 没有像 long int 这样的数据类型。因此,每当数字大到 10000000000
时,它就会抛出这样的错误:Int cannot represent non 32-bit signed integer value: 1000000000000
为此我知道两个解决方案:
- 使用标量。
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,
});
这两个解决方案都将 big int 转换为 string
,我宁愿不使用字符串(我更喜欢数字类型)。
在这种情况下,我建议使用 graphql-bigint 包。此实现为您提供 53 位整数。任何高于 52 位的类似整数的数字都会截断其较低的值。所以如果你需要52位以上,使用字符串会更安全。
正确,graphQL
中没有像 bigInt
这样的概念。
您可以尝试以下方法之一:
- 将类型设置为
Float
而不是Int
- 它将处理所有大的 int 值并将它们作为number
发送 [下面是技术上的选择,虽然你说你不喜欢string
解决方案] - 按照您的描述将类型设置为
String
- 按照您的描述提供(npm 提供的数据类型,例如)
BigInt
。它将处理大整数,但会将您的值转换为string
npm bigInt 依赖选项:
Graphql 引入了标量。我正在使用 Java,所以我可以在 Java 中提供一些解决方案。您可以按照以下步骤实现相同的目的。
请在您的 .graphqls 文件中定义标量
scalar Long
type Movie{
movieId: String
movieName: String
producer: String
director: String
demoId : Long
}
现在您必须在布线中注册此标量。
return RuntimeWiring.newRuntimeWiring().type("Query", typeWiring -> typeWiring
.dataFetcher("allMovies", allMoviesDataFetcher).dataFetcher("movie", movieDataFetcher)
.dataFetcher("getMovie", getMovieDataFetcher)).scalar(ExtendedScalars.GraphQLLong).build();
现在您必须如下定义 Long 的标量配置。
@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();
}
}
应该可以解决你的问题。请试一试 Java 相关应用。