diff --git a/graphql/graphql-java/pom.xml b/graphql/graphql-java/pom.xml
index 5808dd17fb..068cb04ea8 100644
--- a/graphql/graphql-java/pom.xml
+++ b/graphql/graphql-java/pom.xml
@@ -36,6 +36,21 @@
graphql-java-annotations
${graphql-java-annotations.version}
+
+ io.ratpack
+ ratpack-core
+ ${ratpack-core.version}
+
+
+ com.github.americanexpress.nodes
+ nodes
+ 0.5.0
+
+
+ com.graphql-java
+ graphql-java
+ 11.0
+
com.graphql-java
graphql-java-tools
@@ -95,6 +110,14 @@
${mockserver-client-java.version}
test
+
+
+ com.graphql-java
+ graphql-java-extended-scalars
+ ${graphql-java-extended-scalars.version}
+
+
+
@@ -133,6 +156,13 @@
false
false
true
+
+
+ JSON
+ java.util.Map
+ com.baeldung.graphqlreturnmap.ExtendedGraphQLScalarType
+
+
@@ -154,6 +184,8 @@
1.8
1.8
+ 1.18
+ 2022-04-06T00-10-27-a70541e
-
\ No newline at end of file
+
diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/server/GraphQLQuery.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/server/GraphQLQuery.java
index 8ba9fa25c5..f2ac792e80 100644
--- a/graphql/graphql-java/src/main/java/com/baeldung/graphql/server/GraphQLQuery.java
+++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/server/GraphQLQuery.java
@@ -2,6 +2,7 @@ package com.baeldung.graphql.server;
import com.baeldung.graphql.data.Book;
import com.baeldung.graphql.data.BookRepository;
+import com.baeldung.graphqlreturnmap.entity.Product;
import com.coxautodev.graphql.tools.GraphQLQueryResolver;
import java.util.List;
@@ -18,4 +19,12 @@ public class GraphQLQuery implements GraphQLQueryResolver {
return repository.getAllBooks();
}
+ public List getProducts(int pageSize, int pageNumber) {
+ return null;
+ }
+
+ public Product getProduct(int id) {
+ return null;
+ }
+
}
diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/AppHandler.java b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/AppHandler.java
new file mode 100644
index 0000000000..26ad0eef2c
--- /dev/null
+++ b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/AppHandler.java
@@ -0,0 +1,52 @@
+package com.baeldung.graphqlreturnmap;
+
+import com.baeldung.graphql.utils.SchemaUtils;
+import com.baeldung.graphqlreturnmap.resolver.ProductResolver;
+import com.baeldung.graphqlreturnmap.resolver.Query;
+import com.coxautodev.graphql.tools.SchemaParser;
+import graphql.ExecutionResult;
+import graphql.GraphQL;
+import graphql.scalars.ExtendedScalars;
+import graphql.schema.GraphQLSchema;
+import ratpack.handling.Context;
+import ratpack.handling.Handler;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import static ratpack.jackson.Jackson.json;
+
+public class AppHandler implements Handler {
+ private static final Logger LOGGER = Logger.getLogger(AppHandler.class.getSimpleName());
+ private GraphQL graphql;
+
+ public AppHandler() throws Exception {
+ GraphQLSchema schema = SchemaParser.newParser()
+ .resolvers(new Query(), new ProductResolver())
+ .scalars(ExtendedScalars.Json)
+ .file("schema.graphqls")
+ .build()
+ .makeExecutableSchema();
+ graphql = GraphQL.newGraphQL(schema).build();
+ }
+
+ @Override
+ public void handle(Context context) throws Exception {
+ context.parse(Map.class)
+ .then(payload -> {
+ ExecutionResult executionResult = graphql.execute(payload.get(SchemaUtils.QUERY)
+ .toString(), null, this, Collections.emptyMap());
+ Map result = new LinkedHashMap<>();
+ if (executionResult.getErrors()
+ .isEmpty()) {
+ result.put(SchemaUtils.DATA, executionResult.getData());
+ } else {
+ result.put(SchemaUtils.ERRORS, executionResult.getErrors());
+ LOGGER.warning("Errors: " + executionResult.getErrors());
+ }
+ context.render(json(result));
+ });
+ }
+}
diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/ExtendedGraphQLScalarType.java b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/ExtendedGraphQLScalarType.java
new file mode 100644
index 0000000000..5cdc72b13d
--- /dev/null
+++ b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/ExtendedGraphQLScalarType.java
@@ -0,0 +1,24 @@
+package com.baeldung.graphqlreturnmap;
+
+import graphql.language.ScalarTypeDefinition;
+import graphql.schema.Coercing;
+import graphql.schema.GraphQLDirective;
+import graphql.schema.GraphQLScalarType;
+
+import java.util.List;
+
+public class ExtendedGraphQLScalarType extends GraphQLScalarType {
+
+ public ExtendedGraphQLScalarType(){
+ super("","",null);
+
+ }
+
+ public ExtendedGraphQLScalarType(String name, String description, Coercing coercing) {
+ super(name, description, coercing);
+ }
+
+ public ExtendedGraphQLScalarType(String name, String description, Coercing coercing, List directives, ScalarTypeDefinition definition) {
+ super(name, description, coercing, directives, definition);
+ }
+}
diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/GraphqlReturnMap.java b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/GraphqlReturnMap.java
new file mode 100644
index 0000000000..8717fcb722
--- /dev/null
+++ b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/GraphqlReturnMap.java
@@ -0,0 +1,12 @@
+package com.baeldung.graphqlreturnmap;
+
+import ratpack.server.RatpackServer;
+
+public class GraphqlReturnMap {
+
+ public static void main(String[] args) throws Exception {
+ final RatpackServer server = RatpackServer.of(s -> s.handlers(chain -> chain.post("product", new AppHandler())));
+ server.start();
+ }
+
+}
\ No newline at end of file
diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/entity/Attribute.java b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/entity/Attribute.java
new file mode 100644
index 0000000000..dd2766afa5
--- /dev/null
+++ b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/entity/Attribute.java
@@ -0,0 +1,46 @@
+package com.baeldung.graphqlreturnmap.entity;
+
+public class Attribute {
+ private String name;
+ private String description;
+ private String unit;
+
+ public Attribute(String name, String description, String unit){
+ this.name = name;
+ this.description = description;
+ this.unit = unit;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getUnit() {
+ return unit;
+ }
+
+ public void setUnit(String unit) {
+ this.unit = unit;
+ }
+
+ @Override
+ public String toString() {
+ return "Attribute{" +
+ "name='" + name + '\'' +
+ ", description='" + description + '\'' +
+ ", unit='" + unit + '\'' +
+ '}';
+ }
+}
diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/entity/Product.java b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/entity/Product.java
new file mode 100644
index 0000000000..db39d763de
--- /dev/null
+++ b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/entity/Product.java
@@ -0,0 +1,48 @@
+package com.baeldung.graphqlreturnmap.entity;
+
+
+import java.util.Map;
+
+public class Product {
+ private Integer id;
+ private String name;
+ private String description;
+ private Map attributes;
+
+
+ public Product(){
+
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Map getAttributes() {
+ return attributes;
+ }
+
+ public void setAttributes(Map attributes) {
+ this.attributes = attributes;
+ }
+}
diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/model/AttributeKeyValueModel.java b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/model/AttributeKeyValueModel.java
new file mode 100644
index 0000000000..bb7641143b
--- /dev/null
+++ b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/model/AttributeKeyValueModel.java
@@ -0,0 +1,30 @@
+package com.baeldung.graphqlreturnmap.model;
+
+
+import com.baeldung.graphqlreturnmap.entity.Attribute;
+
+public class AttributeKeyValueModel {
+ private String key;
+ private Attribute value;
+
+ public AttributeKeyValueModel(String key, Attribute value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public Attribute getValue() {
+ return value;
+ }
+
+ public void setValue(Attribute value) {
+ this.value = value;
+ }
+}
diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/repository/ProductRepository.java b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/repository/ProductRepository.java
new file mode 100644
index 0000000000..c751efc183
--- /dev/null
+++ b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/repository/ProductRepository.java
@@ -0,0 +1,12 @@
+package com.baeldung.graphqlreturnmap.repository;
+
+
+import com.baeldung.graphqlreturnmap.entity.Product;
+
+import java.util.List;
+
+public interface ProductRepository {
+ List getProducts(Integer pageSize, Integer pageNumber);
+ Product getProduct(Integer id);
+
+}
diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/repository/impl/ProductRepositoryImpl.java b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/repository/impl/ProductRepositoryImpl.java
new file mode 100644
index 0000000000..466a2149f4
--- /dev/null
+++ b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/repository/impl/ProductRepositoryImpl.java
@@ -0,0 +1,43 @@
+package com.baeldung.graphqlreturnmap.repository.impl;
+
+import com.baeldung.graphqlreturnmap.entity.Attribute;
+import com.baeldung.graphqlreturnmap.entity.Product;
+import com.baeldung.graphqlreturnmap.repository.ProductRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Repository
+public class ProductRepositoryImpl implements ProductRepository {
+
+ private static List productList = new ArrayList<>();
+
+ public ProductRepositoryImpl() {
+ for (int i = 1; i <= 10; i++){
+ Product product = new Product();
+ product.setId(i);
+ product.setName(String.format("Product %d", i));
+ product.setDescription(String.format("Product %d description", i));
+ product.setAttributes(createAttributes(i));
+ productList.add(product);
+ }
+ }
+
+ private Map createAttributes(int i) {
+ Map attributeMap = new HashMap<>();
+ attributeMap.put(String.format("attribute_%d",i), new Attribute(String.format("Attribute%d name",i),"This is custom attribute description","This is custom attribute unit"));
+ attributeMap.put("size", new Attribute((i & 1) == 0 ? "Small" : "Large","This is custom attribute description","This is custom attribute unit"));
+ return attributeMap;
+ }
+
+ @Override
+ public List getProducts(Integer pageSize, Integer pageNumber) {
+ return productList.stream().skip(pageSize*pageNumber).limit(pageSize).collect(Collectors.toList());
+ }
+
+ @Override
+ public Product getProduct(Integer id) {
+ return productList.stream().filter(product -> product.getId().equals(id)).findFirst().orElse(null);
+ }
+}
diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/resolver/ProductResolver.java b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/resolver/ProductResolver.java
new file mode 100644
index 0000000000..d9789ea0c6
--- /dev/null
+++ b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/resolver/ProductResolver.java
@@ -0,0 +1,30 @@
+package com.baeldung.graphqlreturnmap.resolver;
+
+import com.baeldung.graphqlreturnmap.entity.Product;
+import com.baeldung.graphqlreturnmap.model.AttributeKeyValueModel;
+import com.coxautodev.graphql.tools.GraphQLResolver;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class ProductResolver implements GraphQLResolver {
+ public ProductResolver(){
+ }
+
+ public List getAttribute_list(Product product){
+ List attributeModelList = new LinkedList<>();
+ product.getAttributes().forEach((key, val) -> attributeModelList.add(new AttributeKeyValueModel(key, val)));
+ return attributeModelList;
+ }
+
+ public String getAttribute_string(Product product){
+ try {
+ return new ObjectMapper().writeValueAsString(product.getAttributes());
+ } catch (JsonProcessingException e) {
+ e.printStackTrace();
+ return "";
+ }
+ }
+}
diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/resolver/Query.java b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/resolver/Query.java
new file mode 100644
index 0000000000..cbcff6056b
--- /dev/null
+++ b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/resolver/Query.java
@@ -0,0 +1,33 @@
+package com.baeldung.graphqlreturnmap.resolver;
+
+import com.baeldung.graphql.data.Book;
+import com.baeldung.graphqlreturnmap.entity.Product;
+import com.baeldung.graphqlreturnmap.repository.ProductRepository;
+import com.baeldung.graphqlreturnmap.repository.impl.ProductRepositoryImpl;
+import com.coxautodev.graphql.tools.GraphQLQueryResolver;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.List;
+
+public class Query implements GraphQLQueryResolver {
+
+ @Autowired
+ private ProductRepository productRepository;
+ public Query(){
+ productRepository = new ProductRepositoryImpl();
+ }
+
+ public List getProducts(int pageSize, int pageNumber) {
+ return productRepository.getProducts(pageSize, pageNumber);
+ }
+
+ public Product getProduct(int id) {
+ return productRepository.getProduct(id);
+ }
+
+ public List allBooks() {
+ return null;
+ }
+
+
+}
diff --git a/graphql/graphql-java/src/main/resources/schema.graphqls b/graphql/graphql-java/src/main/resources/schema.graphqls
index b0834e04b7..da10cd18bd 100644
--- a/graphql/graphql-java/src/main/resources/schema.graphqls
+++ b/graphql/graphql-java/src/main/resources/schema.graphqls
@@ -10,8 +10,34 @@ type Author {
type Query {
allBooks: [Book]
+ products(size: Int, page: Int): [Product]!
+ product(id: Int): Product!
}
+
+
+type Product {
+ id: ID
+ name: String!
+ description: String
+ attribute_string:String
+ attribute_list:[AttributeKeyValuePair]
+ attributes: JSON
+}
+
+type AttributeKeyValuePair {
+ key:String
+ value:Attribute
+}
+
+type Attribute {
+ name:String
+ description:String
+ unit:String
+}
+scalar JSON
+
+
schema {
query: Query
}
\ No newline at end of file