I've configured GraphQL in spring boot application which uses java 17.
To start application you need gradle bootRun.
To try GrapqQL request you can use curl:
curl -X POST http://localhost:8085/graphql \
-H "Content-Type: application/json" \
-d '{"query":"query {\n bookById(id: \"book-1\"){\n id\n name\n pageCount\n productionDate\n authors {\n id\n firstName\n lastName\n }\n }\n}"}'
The current configuration doesn't use custom type LocalDate and no date formatting with pattern"dd/MM/yyyy".
The GraphQL configuration schema.graphqls
type Query {
bookById(id: ID): Book
}
type Book {
id: ID
name: String
pageCount: Int
authors: [Author]!
productionDate: String
# productionDate: LocalDate
}
type Author {
id: ID
firstName: String
lastName: String
}
requires productionDate: LocalDate (in the line 10). The custom java configuration is managed in the ScalarConfiguration.java following spring-boot,
package com.graphqljava.tutorial.bookDetails;
import graphql.language.StringValue;
import graphql.schema.*;
import org.springframework.boot.autoconfigure.graphql.GraphQlSourceBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.graphql.execution.RuntimeWiringConfigurer;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
@Configuration(proxyBeanMethods = false)
public class ScalarConfiguration {
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
@Bean
public GraphQLScalarType dateScalar() {
return GraphQLScalarType.newScalar()
.name("LocalDate")
.description("Java 8 LocalDate as scalar.")
.coercing(new Coercing<Object, Object>() {
@Override
public String serialize(final Object dataFetcherResult) {
if (dataFetcherResult instanceof LocalDate) {
return formatter.format((LocalDate) dataFetcherResult);
} else {
throw new CoercingSerializeException("Expected a LocalDate object.");
}
}
@Override
public LocalDate parseValue(final Object input) {
try {
if (input instanceof String) {
return LocalDate.parse((String) input, formatter);
} else {
throw new CoercingParseValueException("Expected a String");
}
} catch (DateTimeParseException e) {
throw new CoercingParseValueException(String.format("Not a valid date: '%s'.", input), e
);
}
}
@Override
public LocalDate parseLiteral(final Object input) {
if (input instanceof StringValue) {
try {
return LocalDate.parse(((StringValue) input).getValue(), formatter);
} catch (DateTimeParseException e) {
throw new CoercingParseLiteralException(e);
}
} else {
throw new CoercingParseLiteralException("Expected a StringValue.");
}
}
}).build();
}
// https://docs.spring.io/spring-graphql/docs/1.1.0-RC1/reference/html/#execution-graphqlsource-runtimewiring-configurer
@Bean
RuntimeWiringConfigurer runtimeWiringConfigurer() {
GraphQLScalarType scalarType = dateScalar();
return wiringBuilder -> wiringBuilder.scalar(scalarType);
}
/*
// https://docs.spring.io/spring-graphql/docs/1.1.0-RC1/reference/html/#execution-graphqlsource
@Bean
public GraphQlSourceBuilderCustomizer sourceBuilderCustomizer() {
GraphQLScalarType scalarType = dateScalar();
return (builder) ->
builder.configureGraphQl(graphQlBuilder ->
graphQlBuilder.executionIdProvider((query, operationName, context) -> null));
}
*/
}
so runtimeWiringConfigurer loads correctly, but LocalDate doesn't work in my schema.graphqls and I'm looking for help and solution with described issue.
LocalDate.The issue can be resolved declaring correspond scalar type in graphqls file scalar LocalDate.
So schema.graphqls looks like:
scalar LocalDate
type Query {
bookById(id: ID): Book
}
type Book {
id: ID
name: String
pageCount: Int
authors: [Author]!
productionDate: LocalDate
}
type Author {
id: ID
firstName: String
lastName: String
}
The fix is published to the git also.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With