I try to parse a date, e.g. "2022-02-02" as java.time.LocalDate.
Why the values passed to the scalar class are wrapped into curly braces? And how do I fix this?
I configured the scalar for java.time.LocalDate:
@Component
public class DateScalar extends GraphQLScalarType {
public DateScalar() {
super("Date", "java.time.LocalDate", new Coercing() {
@Override
public Object serialize(Object o) throws CoercingSerializeException {
return DateTimeFormatter.ofPattern("yyyy-MM-dd").format((LocalDate) o);
}
@Override
public Object parseValue(Object o) throws CoercingParseValueException {
return LocalDate.parse(o.toString());
}
@Override
public Object parseLiteral(Object o) throws CoercingParseLiteralException {
if (o == null) {
return null;
}
return parseValue(o.toString());
}
});
}
}
This is the query:
mutation {
createEvent(createEventRequest: {
name: "test",
description: "test description",
userId: 1,
participants: [{
firstName: "first",
lastName: "last"
}],
location: {
street: "street",
streetNumber: "streetNumber",
country: "country"
},
duration: {
entireDay: false,
recurringDate: false,
start: "2018-09-03"
}
}) {
id
name
description
participantResponses {
id
firstName
lastName
}
locationResponse {
id
street
streetNumber
country
}
durationResponse {
id
start
end
entireDay
recurringDate
}
userResponse {
id
firstName
lastName
email
}
}
}
The error says that Text 'StringValue{value='2018-09-03'}' could not be parsed at index 0. I do not really understand why this is still wrapped into curly brackets.
java.time.format.DateTimeParseException: Text 'StringValue{value='2018-09-03'}' could not be parsed at index 0 at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2052) ~[na:na] at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1954) ~[na:na] at java.base/java.time.LocalDate.parse(LocalDate.java:430) ~[na:na] at java.base/java.time.LocalDate.parse(LocalDate.java:415) ~[na:na] at com.projects.calendar.scalar.DateScalar$1.parseValue(DateScalar.java:21) ~[classes/:na] at com.projects.calendar.scalar.DateScalar$1.parseLiteral(DateScalar.java:29) ~[classes/:na] at graphql.validation.ValidationUtil.parseLiteral(ValidationUtil.java:113) ~[graphql-java-9.2.jar:na] at graphql.validation.ValidationUtil.isValidLiteralValue(ValidationUtil.java:90) ~[graphql-java-9.2.jar:na] at graphql.validation.ValidationUtil.isValidLiteralValue(ValidationUtil.java:141) ~[graphql-java-9.2.jar:na] at graphql.validation.ValidationUtil.isValidLiteralValue(ValidationUtil.java:107) ~[graphql-java-9.2.jar:na] at graphql.validation.ValidationUtil.isValidLiteralValue(ValidationUtil.java:141) ~[graphql-java-9.2.jar:na] at graphql.validation.ValidationUtil.isValidLiteralValue(ValidationUtil.java:107) ~[graphql-java-9.2.jar:na] at graphql.validation.rules.ArgumentsOfCorrectType.checkArgument(ArgumentsOfCorrectType.java:23) ~[graphql-java-9.2.jar:na] at graphql.validation.RulesVisitor.checkArgument(RulesVisitor.java:98) ~[graphql-java-9.2.jar:na] at graphql.validation.RulesVisitor.enter(RulesVisitor.java:65) ~[graphql-java-9.2.jar:na] at graphql.validation.LanguageTraversal.traverseImpl(LanguageTraversal.java:33) ~[graphql-java-9.2.jar:na] at graphql.validation.LanguageTraversal.traverseImpl(LanguageTraversal.java:38) ~[graphql-java-9.2.jar:na] at graphql.validation.LanguageTraversal.traverseImpl(LanguageTraversal.java:38) ~[graphql-java-9.2.jar:na] at graphql.validation.LanguageTraversal.traverseImpl(LanguageTraversal.java:38) ~[graphql-java-9.2.jar:na] at graphql.validation.LanguageTraversal.traverseImpl(LanguageTraversal.java:38) ~[graphql-java-9.2.jar:na] at graphql.validation.LanguageTraversal.traverse(LanguageTraversal.java:28) ~[graphql-java-9.2.jar:na] at graphql.validation.Validator.validateDocument(Validator.java:42) ~[graphql-java-9.2.jar:na] at graphql.GraphQL.validate(GraphQL.java:539) ~[graphql-java-9.2.jar:na] at graphql.GraphQL.parseAndValidate(GraphQL.java:509) ~[graphql-java-9.2.jar:na] at graphql.GraphQL.lambda$parseValidateAndExecute$3(GraphQL.java:490) ~[graphql-java-9.2.jar:na] at graphql.execution.preparsed.NoOpPreparsedDocumentProvider.get(NoOpPreparsedDocumentProvider.java:11) ~[graphql-java-9.2.jar:na] at graphql.GraphQL.parseValidateAndExecute(GraphQL.java:486) ~[graphql-java-9.2.jar:na] at graphql.GraphQL.executeAsync(GraphQL.java:470) ~[graphql-java-9.2.jar:na] at graphql.GraphQL.execute(GraphQL.java:401) ~[graphql-java-9.2.jar:na] at graphql.servlet.GraphQLQueryInvoker.query(GraphQLQueryInvoker.java:92) ~[graphql-java-servlet-6.1.2.jar:na] at graphql.servlet.GraphQLQueryInvoker.query(GraphQLQueryInvoker.java:88) ~[graphql-java-servlet-6.1.2.jar:na] at graphql.servlet.GraphQLQueryInvoker.query(GraphQLQueryInvoker.java:39) ~[graphql-java-servlet-6.1.2.jar:na] at graphql.servlet.AbstractGraphQLHttpServlet.query(AbstractGraphQLHttpServlet.java:265) ~[graphql-java-servlet-6.1.2.jar:na] at graphql.servlet.AbstractGraphQLHttpServlet.lambda$new$2(AbstractGraphQLHttpServlet.java:183) ~[graphql-java-servlet-6.1.2.jar:na] at graphql.servlet.AbstractGraphQLHttpServlet.doRequest(AbstractGraphQLHttpServlet.java:236) ~[graphql-java-servlet-6.1.2.jar:na] at graphql.servlet.AbstractGraphQLHttpServlet.doRequestAsync(AbstractGraphQLHttpServlet.java:227) ~[graphql-java-servlet-6.1.2.jar:na] at graphql.servlet.AbstractGraphQLHttpServlet.doPost(AbstractGraphQLHttpServlet.java:257) ~[graphql-java-servlet-6.1.2.jar:na] at javax.servlet.http.HttpServlet.service(HttpServlet.java:681) ~[tomcat-embed-core-9.0.56.jar:4.0.FR] at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.56.jar:4.0.FR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.56.jar:9.0.56] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) ~[spring-web-5.3.15.jar:5.3.15] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.15.jar:5.3.15] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.15.jar:5.3.15] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.15.jar:5.3.15] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.15.jar:5.3.15] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.15.jar:5.3.15] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.15.jar:5.3.15] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.15.jar:5.3.15] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1732) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
This is the graphqls file if needed:
type Query {
user(id : Int) : UserResponse,
userByEmail(email : String) : [UserResponse]
}
type Mutation {
createUser(createUserRequest: CreateUserRequest) : UserResponse
createEvent(createEventRequest: CreateEventRequest) : EventResponse
}
input CreateEventRequest {
name: String,
description: String,
participants: [Participant],
location: Location,
duration: Duration,
userId: Int
}
input Duration {
start:Date,
end:Date,
entireDay:Boolean ,
recurringDate:Boolean
}
input Location {
street:String ,
streetNumber:String,
country:String
}
input Participant {
firstName: String,
lastName: String
}
type UserResponse {
id: Int,
firstName: String,
lastName: String,
email: String
}
type EventResponse {
id: Int,
name: String,
description: String,
participantResponses: [ParticipantResponse],
locationResponse: LocationResponse,
durationResponse: DurationResponse,
userResponse: UserResponse
}
type DurationResponse {
id: Int
start: Date
end: Date
entireDay: Boolean
recurringDate: Boolean
}
type LocationResponse {
id: Int,
street: String ,
streetNumber: String ,
country: String
}
type ParticipantResponse {
id: Int,
firstName: String,
lastName: String
}
input CreateUserRequest {
firstName: String!,
lastName: String!,
email: String!
}
scalar Date
CodePudding user response:
The GraphQL is sending the date string as full text as you have declared this as Date. Alternatively, you can declare start as String and parse the string to Date at Java end.
input Duration {
start: String,
end: String,
entireDay:Boolean ,
recurringDate:Boolean
}
CodePudding user response:
The parseLiteral
method parameter is actually a node of the abstract syntax tree produced from parsing the GraphQL query. The method implementation should extract the literal value from the node:
@Override
public LocalDate parseLiteral(Object input) throws CoercingParseLiteralException {
if (input instanceof StringValue) {
try {
return LocalDate.parse(((StringValue) input).getValue());
} catch (DateTimeParseException e) {
throw new CoercingParseLiteralException("Cannot parse [" input "] to LocalDate", e);
}
} else {
throw new CoercingParseLiteralException(
"Expected literal of type StringValue but was " input.getClass());
}
}