diff --git a/graphql/graphql-java/payload-examples/createUser.json b/graphql/graphql-java/payload-examples/createUser.json new file mode 100644 index 0000000000..3ade405b16 --- /dev/null +++ b/graphql/graphql-java/payload-examples/createUser.json @@ -0,0 +1,8 @@ +{ + "query": "mutation($name: String! $email: String! $age: String! ){ createUser ( name: $name email: $email age: $age) { id name email age } }", + "parameters": { + "name": "John", + "email": "john@email.com", + "age": 34 + } +} \ No newline at end of file diff --git a/graphql/graphql-java/payload-examples/deleteUser.json b/graphql/graphql-java/payload-examples/deleteUser.json new file mode 100644 index 0000000000..204496f19b --- /dev/null +++ b/graphql/graphql-java/payload-examples/deleteUser.json @@ -0,0 +1,6 @@ +{ + "query": "mutation($name: String! ){ deleteUser ( id: $id) { id name email age} }", + "parameters": { + "id": 2 + } +} \ No newline at end of file diff --git a/graphql/graphql-java/payload-examples/listUsers.json b/graphql/graphql-java/payload-examples/listUsers.json new file mode 100644 index 0000000000..dde887bb07 --- /dev/null +++ b/graphql/graphql-java/payload-examples/listUsers.json @@ -0,0 +1,4 @@ +{ + "query": "{ listUsers{ id name email age}}", + "parameters": {} +} \ No newline at end of file diff --git a/graphql/graphql-java/payload-examples/retrieveUser.json b/graphql/graphql-java/payload-examples/retrieveUser.json new file mode 100644 index 0000000000..27b5f422eb --- /dev/null +++ b/graphql/graphql-java/payload-examples/retrieveUser.json @@ -0,0 +1,6 @@ +{ + "query": "query($id: String!){ retrieveUser ( id: $id) { id name email} }", + "parameters": { + "id": 1 + } +} \ No newline at end of file diff --git a/graphql/graphql-java/payload-examples/searchName.json b/graphql/graphql-java/payload-examples/searchName.json new file mode 100644 index 0000000000..df8f080b86 --- /dev/null +++ b/graphql/graphql-java/payload-examples/searchName.json @@ -0,0 +1,6 @@ +{ + "query": "query($id: String!){ searchName ( id: $id) { id name email} }", + "parameters": { + "id": 2 + } +} \ No newline at end of file diff --git a/graphql/graphql-java/payload-examples/updateUser.json b/graphql/graphql-java/payload-examples/updateUser.json new file mode 100644 index 0000000000..aa68151111 --- /dev/null +++ b/graphql/graphql-java/payload-examples/updateUser.json @@ -0,0 +1,9 @@ +{ + "query": "mutation($id: String! $name: String! $email: String! $age: String! ){ updateUser ( id: $id name: $name email: $email age: $age) { id name email age} }", + "parameters": { + "id": 1, + "name":"John updated", + "email": "johnupdate@email.com", + "age": 50 + } +} \ No newline at end of file diff --git a/graphql/graphql-java/pom.xml b/graphql/graphql-java/pom.xml new file mode 100644 index 0000000000..c031ddc694 --- /dev/null +++ b/graphql/graphql-java/pom.xml @@ -0,0 +1,29 @@ + + 4.0.0 + + com.baeldung.graphql + graphql-java + 1.0 + + graphql-java + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + com.graphql-java + graphql-java-annotations + 3.0.3 + + + io.ratpack + ratpack-core + 1.4.6 + + + \ No newline at end of file diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/Application.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/Application.java new file mode 100644 index 0000000000..6e9b2a5c80 --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/Application.java @@ -0,0 +1,17 @@ +package com.baeldung.graphql; + +import ratpack.server.RatpackServer; + +import com.baeldung.graphql.handler.UserHandler; + +public class Application { + public static void main(String[] args) throws Exception { + new Application(); + } + + private Application() throws Exception { + final RatpackServer server = RatpackServer.of(s -> s.handlers(chain -> chain.post("users", new UserHandler()))); + server.start(); + } + +} diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/entity/User.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/entity/User.java new file mode 100644 index 0000000000..a4a776cfff --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/entity/User.java @@ -0,0 +1,78 @@ +package com.baeldung.graphql.entity; + +import java.util.List; + +import com.baeldung.graphql.handler.UserHandler; +import com.baeldung.graphql.utils.SchemaUtils; + +import graphql.annotations.GraphQLField; +import graphql.annotations.GraphQLName; + +@GraphQLName(SchemaUtils.USER) +public class User { + + @GraphQLField + private Long id; + @GraphQLField + private String name; + @GraphQLField + private String email; + @GraphQLField + private Integer age; + + public User(String name, String email, Integer age) { + this.id = genId(); + this.name = name; + this.email = email; + this.age = age; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getEmail() { + return email; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + public static Long genId() { + Long id = 1L; + try { + List users = new UserHandler().getUsers(); + for (User user : users) + id = (user.getId() > id ? user.getId() : id) + 1; + + } catch (Exception e) { + e.printStackTrace(); + } + return id; + } + + public String toString() { + return "[id=" + id + ", name=" + name + ", email="+email+ ", age="+ age +"]"; + } +} \ No newline at end of file diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/handler/UserHandler.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/handler/UserHandler.java new file mode 100644 index 0000000000..a6d474a70d --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/handler/UserHandler.java @@ -0,0 +1,56 @@ +package com.baeldung.graphql.handler; + +import graphql.ExecutionResult; +import graphql.GraphQL; +import graphql.schema.DataFetchingEnvironment; +import ratpack.handling.Context; +import ratpack.handling.Handler; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; + +import com.baeldung.graphql.entity.User; +import com.baeldung.graphql.schema.UserSchema; +import com.baeldung.graphql.utils.SchemaUtils; + +import static ratpack.jackson.Jackson.json; + +public class UserHandler implements Handler { + private static final Logger LOGGER = Logger.getLogger(UserHandler.class.getSimpleName()); + private GraphQL graphql; + private static List users = new ArrayList<>(); + + public UserHandler() throws Exception { + graphql = new GraphQL(new UserSchema().getSchema()); + } + + @Override + public void handle(Context context) throws Exception { + context.parse(Map.class) + .then(payload -> { + Map parameters = (Map) payload.get("parameters"); + ExecutionResult executionResult = graphql.execute(payload.get(SchemaUtils.QUERY) + .toString(), null, this, parameters); + 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)); + }); + } + + public static List getUsers() { + return users; + } + + public static List getUsers(DataFetchingEnvironment env) { + return ((UserHandler) env.getSource()).getUsers(); + } +} diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/mutation/UserMutation.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/mutation/UserMutation.java new file mode 100644 index 0000000000..3c6f53a382 --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/mutation/UserMutation.java @@ -0,0 +1,57 @@ +package com.baeldung.graphql.mutation; + +import graphql.annotations.GraphQLField; +import graphql.annotations.GraphQLName; +import graphql.schema.DataFetchingEnvironment; + +import javax.validation.constraints.NotNull; + +import com.baeldung.graphql.entity.User; +import com.baeldung.graphql.utils.SchemaUtils; + +import java.util.List; +import java.util.Optional; + +import static com.baeldung.graphql.handler.UserHandler.getUsers; + +@GraphQLName(SchemaUtils.MUTATION) +public class UserMutation { + @GraphQLField + public static User createUser(final DataFetchingEnvironment env, @NotNull @GraphQLName(SchemaUtils.NAME) final String name, @NotNull @GraphQLName(SchemaUtils.EMAIL) final String email, @NotNull @GraphQLName(SchemaUtils.AGE) final String age) { + List users = getUsers(env); + final User user = new User(name, email, Integer.valueOf(age)); + users.add(user); + return user; + } + + @GraphQLField + public static User updateUser(final DataFetchingEnvironment env, @NotNull @GraphQLName(SchemaUtils.ID) final String id, @NotNull @GraphQLName(SchemaUtils.NAME) final String name, @NotNull @GraphQLName(SchemaUtils.EMAIL) final String email, + @NotNull @GraphQLName(SchemaUtils.AGE) final String age) { + final Optional user = getUsers(env).stream() + .filter(c -> c.getId() == Long.parseLong(id)) + .findFirst(); + if (!user.isPresent()) { + return null; + } + user.get() + .setName(name); + user.get() + .setEmail(email); + user.get() + .setAge(Integer.valueOf(age)); + return user.get(); + } + + @GraphQLField + public static User deleteUser(final DataFetchingEnvironment env, @NotNull @GraphQLName(SchemaUtils.ID) final String id) { + final List users = getUsers(env); + final Optional user = users.stream() + .filter(c -> c.getId() == Long.parseLong(id)) + .findFirst(); + if (!user.isPresent()) { + return null; + } + users.removeIf(c -> c.getId() == Long.parseLong(id)); + return user.get(); + } +} diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/query/UserQuery.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/query/UserQuery.java new file mode 100644 index 0000000000..6f1521c5cf --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/query/UserQuery.java @@ -0,0 +1,42 @@ +package com.baeldung.graphql.query; + +import graphql.annotations.GraphQLField; +import graphql.annotations.GraphQLName; +import graphql.schema.DataFetchingEnvironment; + +import javax.validation.constraints.NotNull; + +import com.baeldung.graphql.entity.User; +import com.baeldung.graphql.utils.SchemaUtils; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import static com.baeldung.graphql.handler.UserHandler.getUsers; + +@GraphQLName(SchemaUtils.QUERY) +public class UserQuery { + + @GraphQLField + public static User retrieveUser(final DataFetchingEnvironment env, @NotNull @GraphQLName(SchemaUtils.ID) final String id) { + final Optional any = getUsers(env).stream() + .filter(c -> c.getId() == Long.parseLong(id)) + .findFirst(); + return any.orElse(null); + } + + @GraphQLField + public static List searchName(final DataFetchingEnvironment env, @NotNull @GraphQLName(SchemaUtils.NAME) final String name) { + return getUsers(env).stream() + .filter(c -> c.getName() + .contains(name)) + .collect(Collectors.toList()); + } + + @GraphQLField + public static List listUsers(final DataFetchingEnvironment env) { + return getUsers(env); + } + +} \ No newline at end of file diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/schema/UserSchema.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/schema/UserSchema.java new file mode 100644 index 0000000000..ebb3569aac --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/schema/UserSchema.java @@ -0,0 +1,24 @@ +package com.baeldung.graphql.schema; + +import graphql.annotations.GraphQLAnnotations; +import graphql.schema.GraphQLSchema; + +import static graphql.schema.GraphQLSchema.newSchema; + +import com.baeldung.graphql.mutation.UserMutation; +import com.baeldung.graphql.query.UserQuery; + +public class UserSchema { + + private final GraphQLSchema schema; + + public UserSchema() throws IllegalAccessException, NoSuchMethodException, InstantiationException { + schema = newSchema().query(GraphQLAnnotations.object(UserQuery.class)) + .mutation(GraphQLAnnotations.object(UserMutation.class)) + .build(); + } + + public GraphQLSchema getSchema() { + return schema; + } +} diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/utils/SchemaUtils.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/utils/SchemaUtils.java new file mode 100644 index 0000000000..680d7e3ea9 --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/utils/SchemaUtils.java @@ -0,0 +1,14 @@ +package com.baeldung.graphql.utils; + +public class SchemaUtils { + public static final String USER = "user"; + public static final String ID = "id"; + public static final String NAME = "name"; + public static final String EMAIL = "email"; + public static final String AGE = "age"; + + public static final String MUTATION = "mutation"; + public static final String QUERY = "query"; + public static final String ERRORS = "errors"; + public static final String DATA = "data"; +}