diff --git a/oap-server/pom.xml b/oap-server/pom.xml
index 4c57bdc2f..21455a3b2 100644
--- a/oap-server/pom.xml
+++ b/oap-server/pom.xml
@@ -36,6 +36,7 @@
server-storage-plugin
server-library
server-starter
+ server-query-plugin
@@ -56,6 +57,8 @@
6.3.1
2.9.9
2.0.0
+ 8.0
+ 5.2.3
@@ -231,6 +234,16 @@
client-java
${kubernetes.version}
+
+ com.graphql-java
+ graphql-java
+ ${graphql-java.version}
+
+
+ com.graphql-java
+ graphql-java-tools
+ ${graphql-java-tools.version}
+
\ No newline at end of file
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/QueryModule.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/QueryModule.java
new file mode 100644
index 000000000..bbba7314a
--- /dev/null
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/QueryModule.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.oap.server.core.query;
+
+import org.apache.skywalking.oap.server.library.module.ModuleDefine;
+
+/**
+ * The root module of Query plugin.
+ *
+ * @author gaohongtao
+ */
+public class QueryModule extends ModuleDefine {
+
+ private static final String NAME = "query";
+
+ @Override public String name() {
+ return NAME;
+ }
+
+ @Override public Class[] services() {
+ return new Class[] {};
+ }
+}
diff --git a/oap-server/server-core/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleDefine b/oap-server/server-core/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleDefine
index d0a876f7c..af910c0f3 100644
--- a/oap-server/server-core/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleDefine
+++ b/oap-server/server-core/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleDefine
@@ -18,4 +18,5 @@
org.apache.skywalking.oap.server.core.storage.StorageModule
org.apache.skywalking.oap.server.core.cluster.ClusterModule
-org.apache.skywalking.oap.server.core.CoreModule
\ No newline at end of file
+org.apache.skywalking.oap.server.core.CoreModule
+org.apache.skywalking.oap.server.core.query.QueryModule
\ No newline at end of file
diff --git a/oap-server/server-query-plugin/pom.xml b/oap-server/server-query-plugin/pom.xml
new file mode 100644
index 000000000..2d388c424
--- /dev/null
+++ b/oap-server/server-query-plugin/pom.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+ oap-server
+ org.apache.skywalking
+ 6.0.0-alpha-SNAPSHOT
+
+ 4.0.0
+
+ server-query-plugin
+ pom
+
+ query-graphql-plugin
+
+
+
\ No newline at end of file
diff --git a/oap-server/server-query-plugin/query-graphql-plugin/pom.xml b/oap-server/server-query-plugin/query-graphql-plugin/pom.xml
new file mode 100644
index 000000000..5bf921f4d
--- /dev/null
+++ b/oap-server/server-query-plugin/query-graphql-plugin/pom.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+ server-query-plugin
+ org.apache.skywalking
+ 6.0.0-alpha-SNAPSHOT
+
+ 4.0.0
+
+ query-graphql-plugin
+
+
+
+ org.apache.skywalking
+ library-module
+ ${project.version}
+
+
+ org.apache.skywalking
+ library-util
+ ${project.version}
+
+
+ org.apache.skywalking
+ server-core
+ ${project.version}
+
+
+ org.apache.skywalking
+ apm-ui-protocol
+ ${project.version}
+
+
+ com.graphql-java
+ graphql-java
+
+
+ com.graphql-java
+ graphql-java-tools
+
+
+ com.google.code.gson
+ gson
+
+
+
\ No newline at end of file
diff --git a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/GraphQLQueryConfig.java b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/GraphQLQueryConfig.java
new file mode 100644
index 000000000..328dd0972
--- /dev/null
+++ b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/GraphQLQueryConfig.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.oap.query.graphql;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.skywalking.oap.server.library.module.ModuleConfig;
+
+/**
+ * The config of {@code query.graphql}.
+ *
+ * @author gaohongtao
+ */
+@Getter(AccessLevel.PACKAGE)
+@Setter(AccessLevel.PUBLIC)
+public class GraphQLQueryConfig extends ModuleConfig {
+ private String path;
+}
diff --git a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/GraphQLQueryHandler.java b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/GraphQLQueryHandler.java
new file mode 100644
index 000000000..d98cd3b0f
--- /dev/null
+++ b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/GraphQLQueryHandler.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.oap.query.graphql;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.reflect.TypeToken;
+import graphql.ExecutionInput;
+import graphql.ExecutionResult;
+import graphql.GraphQL;
+import graphql.GraphQLError;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.List;
+import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import org.apache.skywalking.oap.server.library.server.jetty.ArgumentsParseException;
+
+import org.apache.skywalking.oap.server.library.server.jetty.JettyJsonHandler;
+import org.apache.skywalking.oap.server.library.util.CollectionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@RequiredArgsConstructor
+public class GraphQLQueryHandler extends JettyJsonHandler {
+
+ private static final Logger logger = LoggerFactory.getLogger(GraphQLQueryHandler.class);
+
+ private static final String QUERY = "query";
+ private static final String VARIABLES = "variables";
+ private static final String DATA = "data";
+ private static final String ERRORS = "errors";
+ private static final String MESSAGE = "message";
+
+ private final Gson gson = new Gson();
+
+ private final String path;
+
+ private final GraphQL graphQL;
+
+
+ @Override public String pathSpec() {
+ return path;
+ }
+
+ @Override protected JsonElement doGet(HttpServletRequest req) throws ArgumentsParseException {
+ throw new UnsupportedOperationException("GraphQL only supports POST method");
+ }
+
+ @Override protected JsonElement doPost(HttpServletRequest req) throws ArgumentsParseException, IOException {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(req.getInputStream()));
+ String line;
+ StringBuilder request = new StringBuilder();
+ while ((line = reader.readLine()) != null) {
+ request.append(line);
+ }
+
+ JsonObject requestJson = gson.fromJson(request.toString(), JsonObject.class);
+
+ return execute(requestJson.get(QUERY).getAsString(), gson.fromJson(requestJson.get(VARIABLES), new TypeToken