You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hugegraph.apache.org by vg...@apache.org on 2025/05/18 13:41:08 UTC

(incubator-hugegraph-toolchain) branch master updated: fix(client): Patch up missing classes and methods for hubble (#657)

This is an automated email from the ASF dual-hosted git repository.

vgalaxies pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-hugegraph-toolchain.git


The following commit(s) were added to refs/heads/master by this push:
     new 50a83946 fix(client): Patch up missing classes and methods for hubble (#657)
50a83946 is described below

commit 50a839469b1ad779115e371d0df378116638e9e1
Author: John <th...@qq.com>
AuthorDate: Sun May 18 21:41:03 2025 +0800

    fix(client): Patch up missing classes and methods for hubble (#657)
    
    ---------
    
    Co-authored-by: imbajin <ji...@apache.org>
---
 .github/workflows/client-ci.yml                    |   9 +-
 .github/workflows/codeql-analysis.yml              |   2 +-
 .github/workflows/spark-connector-ci.yml           |   2 +-
 hugegraph-client/pom.xml                           |  12 +-
 .../org/apache/hugegraph/api/auth/ManagerAPI.java  |  91 ++++++
 .../org/apache/hugegraph/api/auth/UserAPI.java     |   9 +
 .../org/apache/hugegraph/api/graph/EdgeAPI.java    |   6 +
 .../hugegraph/api/graph/GraphMetricsAPI.java       | 185 +++++++++++
 .../org/apache/hugegraph/api/graph/VertexAPI.java  |   7 +
 .../org/apache/hugegraph/api/graphs/GraphsAPI.java | 111 +++++++
 .../hugegraph/api/gremlin/GremlinRequest.java      |   5 +-
 .../SchemaAPI.java => ip/WhiteIpListAPI.java}      |  43 +--
 .../EdgesAPI.java => kvstore/KvStoreAPI.java}      |  40 ++-
 .../hugegraph/api/schema/PropertyKeyAPI.java       |   8 +
 .../org/apache/hugegraph/api/schema/SchemaAPI.java |  27 +-
 .../apache/hugegraph/api/task/ComputerDisAPI.java  | 104 ++++++
 .../apache/hugegraph/api/task/TasksWithPage.java   |   1 -
 ...accardSimilarityAPI.java => AdamicAdarAPI.java} |  41 +--
 .../api/traverser/AllShortestPathsAPI.java         |  15 +-
 .../apache/hugegraph/api/traverser/CountAPI.java   |  28 +-
 .../hugegraph/api/traverser/CrosspointsAPI.java    |  17 +-
 .../api/traverser/CustomizedCrosspointsAPI.java    |   4 +-
 .../api/traverser/CustomizedPathsAPI.java          |   4 +-
 .../hugegraph/api/traverser/EdgeExistenceAPI.java  |   4 +-
 .../apache/hugegraph/api/traverser/EdgesAPI.java   |   4 +-
 .../{CustomizedPathsAPI.java => EgonetAPI.java}    |  17 +-
 .../api/traverser/FusiformSimilarityAPI.java       |   4 +-
 .../api/traverser/JaccardSimilarityAPI.java        |  33 +-
 .../hugegraph/api/traverser/KneighborAPI.java      |  14 +-
 .../apache/hugegraph/api/traverser/KoutAPI.java    |  15 +-
 .../api/traverser/MultiNodeShortestPathAPI.java    |   4 +-
 .../hugegraph/api/traverser/NeighborRankAPI.java   |  22 +-
 .../apache/hugegraph/api/traverser/PathsAPI.java   |  17 +-
 .../hugegraph/api/traverser/PersonalRankAPI.java   |  29 +-
 .../apache/hugegraph/api/traverser/RaysAPI.java    |  13 +-
 ...eighborsAPI.java => ResourceAllocationAPI.java} |  38 ++-
 .../apache/hugegraph/api/traverser/RingsAPI.java   |  15 +-
 .../hugegraph/api/traverser/SameNeighborsAPI.java  |  14 +-
 ...milarityAPI.java => SameNeighborsBatchAPI.java} |  18 +-
 .../hugegraph/api/traverser/ShortestPathAPI.java   |  16 +-
 .../api/traverser/SingleSourceShortestPathAPI.java |   6 +-
 .../hugegraph/api/traverser/TemplatePathsAPI.java  |   4 +-
 .../hugegraph/api/traverser/TraversersAPI.java     |   8 +-
 .../traverser/{EdgesAPI.java => VariablesAPI.java} |  38 +--
 .../hugegraph/api/traverser/VerticesAPI.java       |   4 +-
 .../api/traverser/WeightedShortestPathAPI.java     |   4 +-
 .../apache/hugegraph/api/vermeer/VermeerAPI.java   |  86 +++++
 .../org/apache/hugegraph/client/RestClient.java    |  11 +
 .../org/apache/hugegraph/driver/AuthManager.java   |  57 ++++
 .../{TaskManager.java => ComputerManager.java}     |  52 ++-
 .../org/apache/hugegraph/driver/GraphManager.java  |  51 +++
 .../org/apache/hugegraph/driver/GraphsManager.java |  59 +++-
 .../{VersionManager.java => HStoreManager.java}    |  41 ++-
 .../org/apache/hugegraph/driver/HugeClient.java    |  48 ++-
 .../org/apache/hugegraph/driver/JobManager.java    |   4 +-
 .../apache/hugegraph/driver/MetricsManager.java    |   2 +-
 .../TasksWithPage.java => driver/PDManager.java}   |  23 +-
 .../org/apache/hugegraph/driver/SchemaManager.java |  65 +++-
 .../hugegraph/driver/SchemaTemplateManager.java    |  59 ++++
 .../apache/hugegraph/driver/ServiceManager.java    | 108 +++++++
 .../org/apache/hugegraph/driver/TaskManager.java   |   2 +-
 .../apache/hugegraph/driver/TraverserManager.java  | 352 +++++++++++++--------
 .../apache/hugegraph/driver/VermeerManager.java    |  61 ++++
 .../apache/hugegraph/driver/VersionManager.java    |   2 +-
 ...VersionManager.java => WhiteIpListManager.java} |  29 +-
 .../driver/factory/PDHugeClientFactory.java        | 227 +++++++++++++
 .../exception/NotAllCreatedException.java          |   2 +-
 .../serializer/direct/HBaseSerializer.java         |  21 +-
 .../serializer/direct/struct/HugeType.java         |   2 +-
 .../serializer/direct/util/BytesBuffer.java        |   4 +-
 .../java/org/apache/hugegraph/structure/Task.java  |  15 +
 .../apache/hugegraph/structure/auth/Access.java    |  16 +-
 .../hugegraph/structure/auth/AuthElement.java      |  10 +-
 .../apache/hugegraph/structure/auth/Belong.java    |  35 +-
 .../hugegraph/structure/auth/HugePermission.java   |   7 +-
 .../org/apache/hugegraph/structure/auth/Login.java |  11 +
 .../structure/auth/{Access.java => Role.java}      |  87 ++---
 .../apache/hugegraph/structure/auth/Target.java    |  28 +-
 .../org/apache/hugegraph/structure/auth/User.java  |  31 ++
 .../auth/{AuthElement.java => UserManager.java}    |  39 ++-
 .../structure/graph/BatchEdgeRequest.java          |   2 +-
 .../structure/graph/BatchOlapPropertyRequest.java  |   4 +-
 .../structure/graph/BatchVertexRequest.java        |   2 +-
 .../apache/hugegraph/structure/graph/Graph.java    |   4 +-
 .../apache/hugegraph/structure/gremlin/Result.java |   2 +-
 .../hugegraph/structure/schema/BuilderProxy.java   |   8 +-
 .../hugegraph/structure/schema/EdgeLabel.java      |   8 +
 .../hugegraph/structure/schema/IndexLabel.java     |  12 +-
 .../hugegraph/structure/schema/PropertyKey.java    |  38 ++-
 .../hugegraph/structure/schema/VertexLabel.java    |  12 +-
 .../hugegraph/structure/space/HStoreNodeInfo.java  |   6 +-
 .../structure/traverser/CountRequest.java          |   4 +-
 .../traverser/CountResponse.java}                  |  23 +-
 .../structure/traverser/CrosspointsRequest.java    |  22 +-
 .../traverser/CustomizedPathsRequest.java          |  14 +-
 .../{JaccardSimilarity.java => Egonet.java}        |  45 ++-
 .../{KneighborRequest.java => EgonetRequest.java}  |  86 ++---
 .../traverser/FusiformSimilarityRequest.java       |   4 +-
 .../structure/traverser/JaccardSimilarity.java     |   9 +
 .../structure/traverser/KneighborRequest.java      |  36 +--
 .../hugegraph/structure/traverser/KoutRequest.java |  34 +-
 .../traverser/MultiNodeShortestPathRequest.java    |   4 +-
 ...{JaccardSimilarity.java => PathOfVertices.java} |  36 ++-
 .../structure/traverser/PathWithMeasure.java       |  75 +++++
 .../structure/traverser/PathsRequest.java          |   6 +-
 .../{JaccardSimilarity.java => Prediction.java}    |  31 +-
 ...accardSimilarity.java => RanksWithMeasure.java} |  33 +-
 .../traverser/SameNeighbors.java}                  |  22 +-
 .../traverser/SameNeighborsBatch.java}             |  24 +-
 .../traverser/SameNeighborsBatchRequest.java       | 111 +++++++
 .../SingleSourceJaccardSimilarityRequest.java      |   2 +-
 .../hugegraph/structure/traverser/Steps.java       | 142 +++++++++
 .../structure/traverser/TemplatePathsRequest.java  |   8 +-
 .../java/org/apache/hugegraph/util/TaskCache.java  |   4 +-
 .../java/org/apache/hugegraph/api/EdgeApiTest.java |   1 -
 .../org/apache/hugegraph/api/GraphsApiTest.java    |   2 +-
 .../apache/hugegraph/api/auth/LoginApiTest.java    |   5 +-
 .../apache/hugegraph/api/auth/TargetApiTest.java   |   6 +-
 ...milarityApiTest.java => AdamicAdarAPITest.java} | 127 ++++----
 .../api/traverser/AllShortestPathsApiTest.java     |  34 +-
 .../api/traverser/CommonTraverserApiTest.java      |  30 +-
 .../hugegraph/api/traverser/CountApiTest.java      |  68 ++--
 .../api/traverser/FusiformSimilarityApiTest.java   | 109 +++++--
 .../api/traverser/JaccardSimilarityApiTest.java    |  67 ++--
 .../hugegraph/api/traverser/KneighborApiTest.java  |  48 +--
 .../hugegraph/api/traverser/KoutApiTest.java       |  59 ++--
 .../traverser/MultiNodeShortestPathApiTest.java    |   7 +-
 .../api/traverser/NeighborRankApiTest.java         |  25 +-
 .../hugegraph/api/traverser/PathsApiTest.java      |  13 +-
 .../api/traverser/PersonalRankApiTest.java         |  43 ++-
 .../hugegraph/api/traverser/RingsRaysApiTest.java  | 100 +++---
 .../api/traverser/SameNeighborsApiTest.java        |  71 +++--
 .../api/traverser/SameNeighborsBatchApiTest.java   | 331 +++++++++++++++++++
 .../api/traverser/ShortestPathApiTest.java         |  42 ++-
 .../hugegraph/api/traverser/TraverserApiTest.java  |  54 ++--
 .../hugegraph/functional/AuthManagerTest.java      |   1 +
 .../hugegraph/functional/BatchInsertTest.java      |   6 +-
 .../apache/hugegraph/functional/EdgeLabelTest.java |   2 +-
 .../hugegraph/functional/GraphManagerTest.java     |   2 +-
 .../hugegraph/functional/IndexLabelTest.java       |   2 +-
 .../hugegraph/functional/PropertyKeyTest.java      |   2 +-
 .../hugegraph/functional/TraverserManagerTest.java |   6 +-
 .../hugegraph/functional/VertexLabelTest.java      |   2 +-
 .../apache/hugegraph/functional/VertexTest.java    |   2 +-
 .../org/apache/hugegraph/unit/RestResultTest.java  |   6 +-
 .../scripts/dependency/known-dependencies.txt      |  30 +-
 .../service/algorithm/OltpAlgoService.java         |   2 +-
 .../apache/hugegraph/loader/util/DataTypeUtil.java |   4 +-
 pom.xml                                            |   2 +-
 149 files changed, 3785 insertions(+), 1158 deletions(-)

diff --git a/.github/workflows/client-ci.yml b/.github/workflows/client-ci.yml
index 3f24c938..4fa52b06 100644
--- a/.github/workflows/client-ci.yml
+++ b/.github/workflows/client-ci.yml
@@ -20,17 +20,18 @@ on:
 
 jobs:
   client-ci:
-    runs-on: ubuntu-20.04
+    runs-on: ubuntu-latest
     env:
       USE_STAGE: 'true' # Whether to include the stage repository.
       TRAVIS_DIR: hugegraph-client/assembly/travis
       # TODO: replace it with the (latest - n) commit id (n >= 15)
-      # hugegraph commit date: 2024-12-09
-      COMMIT_ID: f838897
+      # hugegraph commit date: 2025-05-05
+      COMMIT_ID: 8c1ee71
     strategy:
       fail-fast: false
       matrix:
-        JAVA_VERSION: [ '8' ]
+        # released pd package is compiled in version 55.0, which requires java 11 to use
+        JAVA_VERSION: [ '11' ]
 
     steps:
       - name: Fetch code
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index c3a27051..314b54df 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -44,7 +44,7 @@ jobs:
       uses: actions/setup-java@v3
       with:
         distribution: 'zulu'
-        java-version: '8'
+        java-version: '11'
 
     - name: use staged maven repo settings
       if: ${{ env.USE_STAGE == 'true' }}
diff --git a/.github/workflows/spark-connector-ci.yml b/.github/workflows/spark-connector-ci.yml
index 0be6b098..32192800 100644
--- a/.github/workflows/spark-connector-ci.yml
+++ b/.github/workflows/spark-connector-ci.yml
@@ -30,7 +30,7 @@ jobs:
     strategy:
       matrix:
         JAVA_VERSION: [ '11' ]
-      
+
     steps:
       - name: Fetch Code
         uses: actions/checkout@v4
diff --git a/hugegraph-client/pom.xml b/hugegraph-client/pom.xml
index d9b95e93..745a3737 100644
--- a/hugegraph-client/pom.xml
+++ b/hugegraph-client/pom.xml
@@ -49,8 +49,6 @@
         <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
-            <!-- TODO: current version(2.8.48) will meet error when using java11 to test unit/RestResultTest,
-            switch to 2.25.1 will temporarily solve this problem -->
             <version>${mockito.version}</version>
             <scope>test</scope>
         </dependency>
@@ -60,6 +58,16 @@
             <version>${lombok.version}</version>
             <optional>true</optional>
         </dependency>
+        <dependency>
+            <groupId>org.apache.hugegraph</groupId>
+            <artifactId>hg-pd-client</artifactId>
+            <version>1.5.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.hugegraph</groupId>
+            <artifactId>hg-pd-grpc</artifactId>
+            <version>1.5.0</version>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/auth/ManagerAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/auth/ManagerAPI.java
new file mode 100644
index 00000000..db13bacd
--- /dev/null
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/auth/ManagerAPI.java
@@ -0,0 +1,91 @@
+/*
+ * 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.hugegraph.api.auth;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.hugegraph.client.RestClient;
+import org.apache.hugegraph.rest.RestResult;
+import org.apache.hugegraph.structure.auth.HugePermission;
+import org.apache.hugegraph.structure.auth.UserManager;
+import org.apache.hugegraph.structure.constant.HugeType;
+
+public class ManagerAPI extends AuthAPI {
+
+    public ManagerAPI(RestClient client, String graph) {
+        super(client, graph);
+    }
+
+    public UserManager create(UserManager userManager) {
+        RestResult result = this.client.post(this.path(), userManager);
+        return result.readObject(UserManager.class);
+    }
+
+    public void delete(String user, HugePermission type, String graphSpace) {
+        Map<String, Object> params = new HashMap<>();
+        params.put("user", user);
+        params.put("type", type);
+        params.put("graphspace", graphSpace);
+        this.client.delete(this.path(), params);
+    }
+
+    public List<String> list(HugePermission type, String graphSpace) {
+
+        Map<String, Object> params = new HashMap<>();
+        params.put("type", type);
+        params.put("graphspace", graphSpace);
+
+        RestResult result = this.client.get(this.path(), params);
+
+        return result.readList("admins", String.class);
+    }
+
+    public boolean checkPermission(HugePermission type, String graphSpace) {
+
+        Map<String, Object> params = new HashMap<>();
+        params.put("type", type);
+        params.put("graphspace", graphSpace);
+
+        String path = this.path() + PATH_SPLITOR + "check";
+        RestResult result = this.client.get(path, params);
+
+        return (boolean) result.readObject(Map.class).getOrDefault("check", false);
+    }
+
+    public boolean checkDefaultRole(String graphSpace, String role,
+                                    String graph) {
+        String path = joinPath(this.path(), "default");
+        Map<String, Object> params = new HashMap<>();
+        params.put("graphspace", graphSpace);
+        params.put("role", role);
+        if (StringUtils.isNotEmpty(graph)) {
+            params.put("graph", graph);
+        }
+        RestResult result = this.client.get(path, params);
+        return (boolean) result.readObject(Map.class).getOrDefault("check",
+                                                                   false);
+    }
+
+    @Override
+    protected String type() {
+        return HugeType.MANAGER.string();
+    }
+}
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/auth/UserAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/auth/UserAPI.java
index 3c1c1d0c..33dee0dd 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/auth/UserAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/auth/UserAPI.java
@@ -44,6 +44,15 @@ public class UserAPI extends AuthAPI {
         return result.readObject(User.class);
     }
 
+    public Map<String, List<Map<String, String>>> createBatch(List<Map<String,
+            String>> data) {
+        String path = String.join("/", this.path(), "batch");
+        RestResult result = this.client.post(path, data);
+        Map<String, List<Map<String, String>>> resultList =
+                (Map<String, List<Map<String, String>>>) result.readObject(Map.class);
+        return resultList;
+    }
+
     public User get(Object id) {
         RestResult result = this.client.get(this.path(), formatEntityId(id));
         return result.readObject(User.class);
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/graph/EdgeAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/graph/EdgeAPI.java
index 64f02593..b0139bd8 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/graph/EdgeAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/graph/EdgeAPI.java
@@ -69,6 +69,12 @@ public class EdgeAPI extends GraphAPI {
         return result.readList(this.type(), Edge.class);
     }
 
+    public Edge update(String edgeid, Edge edge) {
+        Map<String, Object> params = ImmutableMap.of("action", "append");
+        RestResult result = this.client.put(this.path(), edgeid, edge, params);
+        return result.readObject(Edge.class);
+    }
+
     public Edge append(Edge edge) {
         String id = edge.id();
         Map<String, Object> params = ImmutableMap.of("action", "append");
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/graph/GraphMetricsAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/graph/GraphMetricsAPI.java
new file mode 100644
index 00000000..01e6d5fc
--- /dev/null
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/graph/GraphMetricsAPI.java
@@ -0,0 +1,185 @@
+/*
+ * 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.hugegraph.api.graph;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.hugegraph.rest.RestResult;
+
+import org.apache.hugegraph.client.RestClient;
+import org.apache.hugegraph.api.API;
+import org.apache.hugegraph.exception.ServerException;
+import org.apache.hugegraph.structure.constant.HugeType;
+import org.apache.hugegraph.util.JsonUtil;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableMap;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class GraphMetricsAPI extends API {
+
+    private static final String GRAPH_METRICS_PATH = "graphspaces/%s/graphs" +
+                                                     "/%s/%s";
+
+    private final String elementCountPath = "elementcount";
+    private final String typeCountPath = "typecount";
+
+    private final String evPath;
+    private final String evPathByMonth;
+    private final String typePath;
+    private final String typePathByMonth;
+
+    public GraphMetricsAPI(RestClient client, String graphSpace, String graph) {
+        super(client);
+        this.path(GRAPH_METRICS_PATH, graphSpace, graph, this.type());
+
+        evPath = String.format("%s/%s", this.path(), elementCountPath);
+        evPathByMonth = String.format("%s/%s/month", this.path(),
+                                      elementCountPath);
+        typePath = String.format("%s/%s", this.path(), typeCountPath);
+        typePathByMonth = String.format("%s/%s/month", this.path(),
+                                        typeCountPath);
+    }
+
+    @Override
+    protected String type() {
+        return HugeType.METRICS.string();
+    }
+
+    public long createEVCountJob() {
+        RestResult result = this.client.post(evPath, ImmutableMap.of());
+        return ((Number) result.readObject(Map.class).get("task_id")).longValue();
+    }
+
+    public ElementCount getEVCount(String dateStr) {
+        try {
+            RestResult result = this.client.get(evPath, dateStr);
+            return result.readObject(ElementCount.class);
+        } catch (ServerException e) {
+            log.warn(e.exception());
+            return null;
+        }
+    }
+
+    public Map<String, ElementCount> getEVCountByMonth(String monthStr) {
+        Map<String, ElementCount> result = new HashMap<>();
+
+        RestResult resp = this.client.get(evPathByMonth, monthStr);
+
+        // convert json to Map<String, TypeCount>
+        Map<String, Object> elementCounts = resp.readObject(Map.class);
+        for(Map.Entry<String, Object> entry : elementCounts.entrySet()) {
+            String strDate = entry.getKey();
+            Object elementCountMap = entry.getValue();
+            ElementCount elementCount =
+                    JsonUtil.fromJson(JsonUtil.toJson(elementCountMap), ElementCount.class);
+
+            result.put(strDate, elementCount);
+        }
+
+        return result;
+    }
+
+    public long createTypeCountJob() {
+        this.client.post(typePath, ImmutableMap.of());
+        return 0L;
+    }
+
+    public TypeCount getTypeCount(String dateStr) {
+        try {
+            RestResult result = this.client.get(typePath, dateStr);
+            return result.readObject(TypeCount.class);
+        } catch (ServerException e) {
+            log.warn(e.exception());
+            return null;
+        }
+    }
+
+    /**
+     * @param from Start time
+     * @param to   End time
+     */
+    public TypeCounts getTypeCounts(String from, String to) {
+        try {
+            RestResult result = this.client.get(typePath,
+                                                ImmutableMap.of("from", from, "to", to));
+            return result.readObject(TypeCounts.class);
+        } catch (ServerException e) {
+            log.warn(e.exception());
+            return null;
+        }
+    }
+
+    public Map<String, TypeCount> getTypeCountByMonth(String monthStr) {
+        Map<String, TypeCount> result = new HashMap<>();
+
+        RestResult resp = this.client.get(typePathByMonth, monthStr);
+
+        // convert json to Map<String, TypeCount>
+        Map<String, Object> typeCounts = resp.readObject(Map.class);
+        for(Map.Entry<String, Object> entry : typeCounts.entrySet()) {
+            String strDate = entry.getKey();
+            Object typeCountMap = entry.getValue();
+            TypeCount typeCount =
+                    JsonUtil.fromJson(JsonUtil.toJson(typeCountMap), TypeCount.class);
+
+            result.put(strDate, typeCount);
+        }
+
+        return result;
+    }
+
+    @Data
+    public static class ElementCount {
+        // Result statistics time
+        String datetime;
+        long vertices;
+        long edges;
+    }
+
+    @Data
+    @Builder
+    @AllArgsConstructor
+    @NoArgsConstructor
+    public static class TypeCounts {
+        @JsonProperty("type_counts")
+        Map<String, TypeCount> typeCounts;
+    }
+
+    @Data
+    @Builder
+    @AllArgsConstructor
+    @NoArgsConstructor
+    public static class TypeCount {
+        // Result statistics time
+        @JsonProperty("datetime")
+        String datetime;
+        @JsonProperty("vertices")
+        Map<String, Long> vertices;
+        @JsonProperty("edges")
+        Map<String, Long> edges;
+        @JsonProperty("schemas")
+        Map<String, Long> schemas;
+    }
+}
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/graph/VertexAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/graph/VertexAPI.java
index 734757bb..90ecf8a3 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/graph/VertexAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/graph/VertexAPI.java
@@ -82,6 +82,13 @@ public class VertexAPI extends GraphAPI {
         return (int) size;
     }
 
+    public Vertex update(String vertexid, Vertex vertex) {
+        String id = GraphAPI.formatVertexId(vertexid);
+        Map<String, Object> params = ImmutableMap.of("action", "append");
+        RestResult result = this.client.put(this.path(), id, vertex, params);
+        return result.readObject(Vertex.class);
+    }
+
     public Vertex append(Vertex vertex) {
         String id = GraphAPI.formatVertexId(vertex.id());
         Map<String, Object> params = ImmutableMap.of("action", "append");
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/graphs/GraphsAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/graphs/GraphsAPI.java
index 1abf54b7..17d0a537 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/graphs/GraphsAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/graphs/GraphsAPI.java
@@ -17,6 +17,9 @@
 
 package org.apache.hugegraph.api.graphs;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -29,6 +32,8 @@ import org.apache.hugegraph.rest.RestResult;
 import org.apache.hugegraph.structure.constant.GraphMode;
 import org.apache.hugegraph.structure.constant.GraphReadMode;
 import org.apache.hugegraph.structure.constant.HugeType;
+import org.apache.hugegraph.util.E;
+import org.apache.hugegraph.util.JsonUtil;
 
 import com.google.common.collect.ImmutableMap;
 
@@ -39,6 +44,11 @@ public class GraphsAPI extends API {
     private static final String GRAPH_READ_MODE = "graph_read_mode";
     private static final String CLEAR = "clear";
     private static final String CONFIRM_MESSAGE = "confirm_message";
+    private static final String CLEARED = "cleared";
+    private static final String RELOADED = "reloaded";
+    private static final String UPDATED = "updated";
+    private static final String GRAPHS = "graphs";
+    private static final String MANAGE = "manage";
     private static final String PATH = "graphspaces/%s/graphs";
 
     public GraphsAPI(RestClient client, String graphSpace) {
@@ -59,6 +69,8 @@ public class GraphsAPI extends API {
         return HugeType.GRAPHS.string();
     }
 
+    // TODO(@Thespcia): in inner version, clone is split into a single method, and doesn't have
+    // this parameter
     @SuppressWarnings("unchecked")
     public Map<String, String> create(String name, String cloneGraphName, String configText) {
         this.client.checkApiVersion("0.67", "dynamic graph add");
@@ -83,17 +95,108 @@ public class GraphsAPI extends API {
         return result.readList(this.type(), String.class);
     }
 
+    public List<Map<String, Object>> listProfile(String prefix) {
+        String profilePath = joinPath(this.path(), "profile");
+        Map<String, Object> params = new LinkedHashMap<>();
+        params.put("prefix", prefix);
+        RestResult result = this.client.get(profilePath, params);
+        List<Map> results = result.readList(Map.class);
+        List<Map<String, Object>> profiles = new ArrayList<>();
+        for (Object entry : results) {
+            profiles.add(JsonUtil.fromJson(JsonUtil.toJson(entry), Map.class));
+        }
+        return profiles;
+    }
+
+    public Map<String, String> setDefault(String name) {
+        String defaultPath = joinPath(this.path(), name, "default");
+        RestResult result = this.client.get(defaultPath);
+        return result.readObject(Map.class);
+    }
+
+    public Map<String, String> unSetDefault(String name) {
+        String unDefaultPath = joinPath(this.path(), name, "undefault");
+        RestResult result = this.client.get(unDefaultPath);
+        return result.readObject(Map.class);
+    }
+
+    public Map<String, String> getDefault() {
+        String defaultPath = joinPath(this.path(), "default");
+        RestResult result = this.client.get(defaultPath);
+        return result.readObject(Map.class);
+    }
+
+    public void clear(String graph) {
+        this.clear(graph, "I'm sure to delete all data");
+    }
+
+    // TODO: clearSchema is not supported yet, will always be true
+    public void clear(String graph, boolean clearSchema) {
+        this.clear(graph, "I'm sure to delete all data");
+    }
+
     public void clear(String graph, String message) {
         this.client.delete(joinPath(this.path(), graph, CLEAR),
                            ImmutableMap.of(CONFIRM_MESSAGE, message));
     }
 
+    public Map<String, String> update(String name, String nickname) {
+        Map<String, String> actionMap = new HashMap<>();
+        actionMap.put("name", name);
+        actionMap.put("nickname", nickname);
+        RestResult result = this.client.put(this.path(), name,
+                                            ImmutableMap.of("action", "update",
+                                                            "update", actionMap));
+        Map<String, String> response = result.readObject(Map.class);
+
+        E.checkState(response.size() == 1 && response.containsKey(name),
+                     "Response must be formatted to {\"%s\" : status}, " +
+                     "but got %s", name, response);
+        String status = response.get(name);
+        E.checkState(UPDATED.equals(status),
+                     "Server status must be '%s', but got '%s'", UPDATED, status);
+        return response;
+    }
+
+    // wrapper for inner server
+    public void delete(String graph) {
+        this.drop(graph, "I'm sure to drop the graph");
+    }
+
     public void drop(String graph, String message) {
         this.client.checkApiVersion("0.67", "dynamic graph delete");
         this.client.delete(joinPath(this.path(), graph),
                            ImmutableMap.of(CONFIRM_MESSAGE, message));
     }
 
+    public Map<String, String> reload(String name) {
+        RestResult result = this.client.put(this.path(), name,
+                                            ImmutableMap.of("action", "reload"));
+        Map<String, String> response = result.readObject(Map.class);
+
+        E.checkState(response.size() == 1 && response.containsKey(name),
+                     "Response must be formatted to {\"%s\" : status}, " +
+                     "but got %s", name, response);
+        String status = response.get(name);
+        E.checkState(RELOADED.equals(status),
+                     "Graph %s status must be %s, but got '%s'", name, RELOADED, status);
+        return response;
+    }
+
+    public Map<String, String> reload() {
+        RestResult result = this.client.put(this.path(), MANAGE,
+                                            ImmutableMap.of("action", "reload"));
+        Map<String, String> response = result.readObject(Map.class);
+
+        E.checkState(response.size() == 1 && response.containsKey(GRAPHS),
+                     "Response must be formatted to {\"%s\" : status}, " +
+                     "but got %s", GRAPHS, response);
+        String status = response.get(GRAPHS);
+        E.checkState(RELOADED.equals(status),
+                     "Server status must be '%s', but got '%s'", RELOADED, status);
+        return response;
+    }
+
     public void mode(String graph, GraphMode mode) {
         // NOTE: Must provide id for PUT. If you use "graph/mode", "/" will
         // be encoded to "%2F". So use "mode" here, although inaccurate.
@@ -139,4 +242,12 @@ public class GraphsAPI extends API {
             throw new InvalidResponseException("Invalid GraphReadMode value '%s'", value);
         }
     }
+
+    public String clone(String graph, Map<String, Object> body) {
+        RestResult result = this.client.post(joinPath(this.path(), graph,
+                                                      "clone"), body);
+        Map<String, Object> resultMap = result.readObject(Map.class);
+        String taskId = (String) resultMap.get("task_id");
+        return taskId;
+    }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/gremlin/GremlinRequest.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/gremlin/GremlinRequest.java
index d7f3f152..9a511bbf 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/gremlin/GremlinRequest.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/gremlin/GremlinRequest.java
@@ -42,8 +42,9 @@ public class GremlinRequest {
     }
 
     public static class Builder {
-        private GremlinRequest request;
-        private GremlinManager manager;
+
+        private final GremlinRequest request;
+        private final GremlinManager manager;
 
         public Builder(String gremlin, GremlinManager executor) {
             this.request = new GremlinRequest(gremlin);
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/schema/SchemaAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/ip/WhiteIpListAPI.java
similarity index 57%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/api/schema/SchemaAPI.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/api/ip/WhiteIpListAPI.java
index 078b7bce..00981b68 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/schema/SchemaAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/ip/WhiteIpListAPI.java
@@ -15,37 +15,44 @@
  * under the License.
  */
 
-package org.apache.hugegraph.api.schema;
+package org.apache.hugegraph.api.ip;
 
-import java.util.List;
-import java.util.Map;
+import com.google.common.collect.ImmutableMap;
 
-import org.apache.hugegraph.api.API;
 import org.apache.hugegraph.client.RestClient;
-import org.apache.hugegraph.exception.NotSupportException;
+import org.apache.hugegraph.api.API;
 import org.apache.hugegraph.rest.RestResult;
-import org.apache.hugegraph.structure.SchemaElement;
+import org.apache.hugegraph.structure.constant.HugeType;
 
-public class SchemaAPI extends API {
+import java.util.Map;
 
-    private static final String PATH = "graphspaces/%s/graphs/%s/%s";
+public class WhiteIpListAPI extends API {
+    private static final String PATH = "whiteiplist";
 
-    public SchemaAPI(RestClient client, String graphSpace, String graph) {
+    public WhiteIpListAPI(RestClient client) {
         super(client);
-        this.path(PATH, graphSpace, graph, this.type());
+        this.path(PATH);
+    }
+
+    @Override
+    protected String type() {
+        return HugeType.WHITE_IP_LIST.string();
     }
 
-    @SuppressWarnings("unchecked")
-    public Map<String, List<SchemaElement>> list() {
-        if (this.client.apiVersionLt("0.66")) {
-            throw new NotSupportException("schema get api");
-        }
+    public Map<String, Object> list() {
         RestResult result = this.client.get(this.path());
         return result.readObject(Map.class);
     }
 
-    @Override
-    protected String type() {
-        return "schema";
+    public Map<String, Object> batch(Map<String, Object> action) {
+        RestResult result = this.client.post(this.path(), action);
+        return result.readObject(Map.class);
+
+    }
+
+    public Map<String, Object> update(boolean status) {
+        Map<String, Object> params = ImmutableMap.of("status", status);
+        RestResult result = this.client.put(this.path(), null, params);
+        return result.readObject(Map.class);
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/EdgesAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/kvstore/KvStoreAPI.java
similarity index 70%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/EdgesAPI.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/api/kvstore/KvStoreAPI.java
index 162b9dec..084dd9db 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/EdgesAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/kvstore/KvStoreAPI.java
@@ -14,41 +14,35 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
-
-package org.apache.hugegraph.api.traverser;
+package org.apache.hugegraph.api.kvstore;
 
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.hugegraph.client.RestClient;
+import org.apache.hugegraph.api.API;
 import org.apache.hugegraph.rest.RestResult;
-import org.apache.hugegraph.structure.graph.Edge;
-import org.apache.hugegraph.structure.graph.Edges;
 import org.apache.hugegraph.structure.graph.Shard;
+import org.apache.hugegraph.structure.graph.Vertices;
 import org.apache.hugegraph.util.E;
 
 import com.google.common.collect.ImmutableMap;
 
-public class EdgesAPI extends TraversersAPI {
+public class KvStoreAPI extends API {
+
+    private static final String PATH = "kvstore";
+    private static String batchPath = "";
 
-    public EdgesAPI(RestClient client, String graph) {
-        super(client, graph);
+    public KvStoreAPI(RestClient client) {
+        super(client);
+        this.path(PATH);
+        batchPath = String.join("/", this.path(), "batch");
     }
 
     @Override
     protected String type() {
-        return "edges";
-    }
-
-    public List<Edge> list(List<String> ids) {
-        E.checkArgument(ids != null && !ids.isEmpty(),
-                        "Ids can't be null or empty");
-
-        Map<String, Object> params = new LinkedHashMap<>();
-        params.put("ids", ids);
-        RestResult result = this.client.get(this.path(), params);
-        return result.readList(this.type(), Edge.class);
+        return "kvstore";
     }
 
     public List<Shard> shards(long splitSize) {
@@ -58,7 +52,7 @@ public class EdgesAPI extends TraversersAPI {
         return result.readList("shards", Shard.class);
     }
 
-    public Edges scan(Shard shard, String page, long pageLimit) {
+    public Vertices scan(Shard shard, String page, long pageLimit) {
         E.checkArgument(shard != null, "Shard can't be null");
         String path = String.join(PATH_SPLITOR, this.path(), "scan");
         Map<String, Object> params = new LinkedHashMap<>();
@@ -67,7 +61,11 @@ public class EdgesAPI extends TraversersAPI {
         params.put("page", page);
         params.put("page_limit", pageLimit);
         RestResult result = this.client.get(path, params);
-        return result.readObject(Edges.class);
+        return result.readObject(Vertices.class);
     }
-}
 
+    public Map<String, Object> setBatch(Map<String, Object> data) {
+        RestResult result = this.client.post(batchPath, data);
+        return result.readObject(Map.class);
+    }
+}
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/schema/PropertyKeyAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/schema/PropertyKeyAPI.java
index 414e8979..a28bcb26 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/schema/PropertyKeyAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/schema/PropertyKeyAPI.java
@@ -68,6 +68,14 @@ public class PropertyKeyAPI extends SchemaElementAPI {
         return result.readObject(PropertyKey.PropertyKeyWithTask.class);
     }
 
+    public PropertyKey update(String oldPk, PropertyKey newPk) {
+        String id = oldPk;
+        Map<String, Object> params = ImmutableMap.of("action", "update");
+        Object pkey = this.checkCreateOrUpdate(newPk);
+        RestResult result = this.client.put(this.path(), id, pkey, params);
+        return result.readObject(PropertyKey.class);
+    }
+
     public PropertyKey.PropertyKeyWithTask clear(PropertyKey propertyKey) {
         if (this.client.apiVersionLt("0.65")) {
             throw new NotSupportException("action clear on property key");
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/schema/SchemaAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/schema/SchemaAPI.java
index 078b7bce..44973f7b 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/schema/SchemaAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/schema/SchemaAPI.java
@@ -20,6 +20,7 @@ package org.apache.hugegraph.api.schema;
 import java.util.List;
 import java.util.Map;
 
+import com.google.common.collect.ImmutableMap;
 import org.apache.hugegraph.api.API;
 import org.apache.hugegraph.client.RestClient;
 import org.apache.hugegraph.exception.NotSupportException;
@@ -35,12 +36,34 @@ public class SchemaAPI extends API {
         this.path(PATH, graphSpace, graph, this.type());
     }
 
-    @SuppressWarnings("unchecked")
     public Map<String, List<SchemaElement>> list() {
+        return this.listJson();
+    }
+
+    public Map<String, String> listGroovy() {
+        if (this.client.apiVersionLt("0.66")) {
+            throw new NotSupportException("schema get api");
+        }
+        RestResult result = this.client.get(this.path(), ImmutableMap.of(
+                "format", "groovy"));
+        return result.readObject(Map.class);
+    }
+
+    public Map<String, Object> listGroovy(String format, boolean attachIdFlag) {
+        if (this.client.apiVersionLt("0.66")) {
+            throw new NotSupportException("schema get api");
+        }
+        RestResult result = this.client.get(this.path(), ImmutableMap.of(
+                "format", format, "attachidflag", attachIdFlag));
+        return result.readObject(Map.class);
+    }
+
+    public Map<String, List<SchemaElement>> listJson() {
         if (this.client.apiVersionLt("0.66")) {
             throw new NotSupportException("schema get api");
         }
-        RestResult result = this.client.get(this.path());
+        RestResult result = this.client.get(this.path(), ImmutableMap.of(
+                "format", "json"));
         return result.readObject(Map.class);
     }
 
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/task/ComputerDisAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/task/ComputerDisAPI.java
new file mode 100644
index 00000000..b5838904
--- /dev/null
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/task/ComputerDisAPI.java
@@ -0,0 +1,104 @@
+/*
+ * 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.hugegraph.api.task;
+
+import com.google.common.collect.ImmutableMap;
+
+import org.apache.hugegraph.client.RestClient;
+import org.apache.hugegraph.api.API;
+import org.apache.hugegraph.rest.RestResult;
+import org.apache.hugegraph.structure.Task;
+import org.apache.hugegraph.util.E;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ComputerDisAPI extends API {
+
+    private static final String PATH = "graphspaces/%s/graphs/%s/jobs/computerdis";
+    private final String graphSpace;
+    private final String graph;
+    public static final String TASKS = "tasks";
+    public static final String TASK_ID = "task_id";
+
+    public ComputerDisAPI(RestClient client, String graphSpace, String graph) {
+        super(client);
+        this.graphSpace = graphSpace;
+        this.graph = graph;
+        this.path(String.format(PATH, this.graphSpace, this.graph));
+    }
+
+    @Override
+    protected String type() {
+        return "computerdis";
+    }
+
+    public long create(String algorithm, long worker,
+                       Map<String, Object> params) {
+        Map<String, Object> innerParams = new LinkedHashMap<>();
+        innerParams.put("algorithm", algorithm);
+        innerParams.put("worker", worker);
+        innerParams.put("params", params);
+        RestResult result = this.client.post(this.path(), innerParams);
+        @SuppressWarnings("unchecked")
+        Map<String, Object> task = result.readObject(Map.class);
+        return parseTaskId(task);
+    }
+
+    public void delete(long id) {
+        this.client.delete(this.path(), String.valueOf(id));
+    }
+
+    public Task cancel(long id) {
+        RestResult result = this.client.put(this.path(), String.valueOf(id),
+                                            ImmutableMap.of());
+        return result.readObject(Task.class);
+    }
+
+    public List<Task> list(long limit) {
+        Map<String, Object> params = new LinkedHashMap<>();
+        params.put("limit", limit);
+        RestResult result = this.client.get(this.path(), params);
+        return result.readList(TASKS, Task.class);
+    }
+
+    public TasksWithPage list(String page, long limit) {
+        E.checkArgument(page != null, "The page can not be null");
+        Map<String, Object> params = new LinkedHashMap<>();
+        params.put("limit", limit);
+        params.put("page", page);
+        RestResult result = this.client.get(this.path(), params);
+        return result.readObject(TasksWithPage.class);
+    }
+
+    public Task get(long id) {
+        RestResult result = this.client.get(this.path(), String.valueOf(id));
+        return result.readObject(Task.class);
+    }
+
+    public static long parseTaskId(Map<String, Object> task) {
+        E.checkState(task.size() == 1 && task.containsKey(TASK_ID),
+                     "Task must be formatted to {\"%s\" : id}, but got %s",
+                     TASK_ID, task);
+        Object taskId = task.get(TASK_ID);
+        E.checkState(taskId instanceof Number,
+                     "Task id must be number, but got '%s'", taskId);
+        return ((Number) taskId).longValue();
+    }
+}
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/task/TasksWithPage.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/task/TasksWithPage.java
index 44c06311..60619104 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/task/TasksWithPage.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/task/TasksWithPage.java
@@ -20,7 +20,6 @@ package org.apache.hugegraph.api.task;
 import java.util.List;
 
 import org.apache.hugegraph.structure.Task;
-
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 public class TasksWithPage {
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/JaccardSimilarityAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/AdamicAdarAPI.java
similarity index 65%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/JaccardSimilarityAPI.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/AdamicAdarAPI.java
index f87958bb..4123cb2f 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/JaccardSimilarityAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/AdamicAdarAPI.java
@@ -20,33 +20,30 @@ package org.apache.hugegraph.api.traverser;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
-import org.apache.hugegraph.api.graph.GraphAPI;
 import org.apache.hugegraph.client.RestClient;
-
+import org.apache.hugegraph.api.graph.GraphAPI;
 import org.apache.hugegraph.rest.RestResult;
-
 import org.apache.hugegraph.structure.constant.Direction;
-import org.apache.hugegraph.structure.traverser.JaccardSimilarity;
+import org.apache.hugegraph.structure.traverser.Prediction;
 import org.apache.hugegraph.structure.traverser.SingleSourceJaccardSimilarityRequest;
-
 import org.apache.hugegraph.util.E;
 
-public class JaccardSimilarityAPI extends TraversersAPI {
+public class AdamicAdarAPI extends TraversersAPI {
 
-    private static final String JACCARD_SIMILARITY = "jaccard_similarity";
+    private static final String AA = "adamic_adar";
 
-    public JaccardSimilarityAPI(RestClient client, String graph) {
-        super(client, graph);
+    public AdamicAdarAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
     protected String type() {
-        return "jaccardsimilarity";
+        return "adamicadar";
     }
 
-    public double get(Object vertexId, Object otherId, Direction direction,
-                      String label, long degree) {
-        this.client.checkApiVersion("0.51", "jaccard similarity");
+    public Prediction get(Object vertexId, Object otherId, Direction direction,
+                          String label, long degree) {
+        this.client.checkApiVersion("0.67", AA);
         String vertex = GraphAPI.formatVertexId(vertexId, false);
         String other = GraphAPI.formatVertexId(otherId, false);
         checkDegree(degree);
@@ -58,16 +55,20 @@ public class JaccardSimilarityAPI extends TraversersAPI {
         params.put("max_degree", degree);
         RestResult result = this.client.get(this.path(), params);
         @SuppressWarnings("unchecked")
-        Map<String, Double> jaccard = result.readObject(Map.class);
-        E.checkState(jaccard.containsKey(JACCARD_SIMILARITY),
-                     "The result doesn't have key '%s'", JACCARD_SIMILARITY);
-        return jaccard.get(JACCARD_SIMILARITY);
+        Prediction res = result.readObject(Prediction.class);
+        E.checkState(res.getAdamicAdar() != null,
+                     "The result doesn't have key '%s'", AA);
+        return res;
     }
 
+    /**
+     * No corresponding interface found in server
+     */
     @SuppressWarnings("unchecked")
-    public JaccardSimilarity post(SingleSourceJaccardSimilarityRequest request) {
-        this.client.checkApiVersion("0.58", "jaccard similar");
+    public Map<Object, Double> post(SingleSourceJaccardSimilarityRequest
+                                    request) {
+        this.client.checkApiVersion("0.67", AA);
         RestResult result = this.client.post(this.path(), request);
-        return result.readObject(JaccardSimilarity.class);
+        return result.readObject(Map.class);
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/AllShortestPathsAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/AllShortestPathsAPI.java
index d692935f..d8aee3d1 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/AllShortestPathsAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/AllShortestPathsAPI.java
@@ -18,19 +18,18 @@
 package org.apache.hugegraph.api.traverser;
 
 import java.util.LinkedHashMap;
-import java.util.List;
 import java.util.Map;
 
 import org.apache.hugegraph.api.graph.GraphAPI;
 import org.apache.hugegraph.client.RestClient;
 import org.apache.hugegraph.rest.RestResult;
 import org.apache.hugegraph.structure.constant.Direction;
-import org.apache.hugegraph.structure.graph.Path;
+import org.apache.hugegraph.structure.traverser.PathWithMeasure;
 
 public class AllShortestPathsAPI extends TraversersAPI {
 
-    public AllShortestPathsAPI(RestClient client, String graph) {
-        super(client, graph);
+    public AllShortestPathsAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
@@ -38,9 +37,9 @@ public class AllShortestPathsAPI extends TraversersAPI {
         return "allshortestpaths";
     }
 
-    public List<Path> get(Object sourceId, Object targetId,
-                          Direction direction, String label, int maxDepth,
-                          long degree, long skipDegree, long capacity) {
+    public PathWithMeasure get(Object sourceId, Object targetId,
+                               Direction direction, String label, int maxDepth,
+                               long degree, long skipDegree, long capacity) {
         this.client.checkApiVersion("0.51", "all shortest path");
         String source = GraphAPI.formatVertexId(sourceId, false);
         String target = GraphAPI.formatVertexId(targetId, false);
@@ -60,6 +59,6 @@ public class AllShortestPathsAPI extends TraversersAPI {
         params.put("skip_degree", skipDegree);
         params.put("capacity", capacity);
         RestResult result = this.client.get(this.path(), params);
-        return result.readList("paths", Path.class);
+        return result.readObject(PathWithMeasure.class);
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/CountAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/CountAPI.java
index 788e3879..02790947 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/CountAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/CountAPI.java
@@ -22,14 +22,15 @@ import java.util.Map;
 import org.apache.hugegraph.client.RestClient;
 import org.apache.hugegraph.rest.RestResult;
 import org.apache.hugegraph.structure.traverser.CountRequest;
+import org.apache.hugegraph.structure.traverser.CountResponse;
 import org.apache.hugegraph.util.E;
 
 public class CountAPI extends TraversersAPI {
 
     private static final String COUNT = "count";
 
-    public CountAPI(RestClient client, String graph) {
-        super(client, graph);
+    public CountAPI(RestClient client,  String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
@@ -37,13 +38,24 @@ public class CountAPI extends TraversersAPI {
         return "count";
     }
 
-    public long post(CountRequest request) {
+    public CountResponse post(CountRequest request) {
         this.client.checkApiVersion("0.55", "count");
         RestResult result = this.client.post(this.path(), request);
-        @SuppressWarnings("unchecked")
-        Map<String, Number> countMap = result.readObject(Map.class);
-        E.checkState(countMap.containsKey(COUNT),
-                     "The result doesn't have key '%s'", COUNT);
-        return countMap.get(COUNT).longValue();
+        // old version response doesn't have key 'countMap'
+        if (!result.content().contains("countMap")) {
+            @SuppressWarnings("unchecked")
+            Map<String, Number> countMap = result.readObject(Map.class);
+            E.checkState(countMap.containsKey(COUNT),
+                         "The result doesn't have key '%s'", COUNT);
+            CountResponse resp = new CountResponse();
+            resp.setCountMap(countMap);
+            return resp;
+        } else {
+            @SuppressWarnings("unchecked")
+            CountResponse resp = result.readObject(CountResponse.class);
+            E.checkState(resp.countMap().containsKey(COUNT),
+                         "The result doesn't have key '%s'", COUNT);
+            return resp;
+        }
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/CrosspointsAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/CrosspointsAPI.java
index 19669101..b5d5e817 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/CrosspointsAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/CrosspointsAPI.java
@@ -18,19 +18,18 @@
 package org.apache.hugegraph.api.traverser;
 
 import java.util.LinkedHashMap;
-import java.util.List;
 import java.util.Map;
 
 import org.apache.hugegraph.api.graph.GraphAPI;
 import org.apache.hugegraph.client.RestClient;
 import org.apache.hugegraph.rest.RestResult;
 import org.apache.hugegraph.structure.constant.Direction;
-import org.apache.hugegraph.structure.graph.Path;
+import org.apache.hugegraph.structure.traverser.PathWithMeasure;
 
 public class CrosspointsAPI extends TraversersAPI {
 
-    public CrosspointsAPI(RestClient client, String graph) {
-        super(client, graph);
+    public CrosspointsAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
@@ -38,10 +37,10 @@ public class CrosspointsAPI extends TraversersAPI {
         return "crosspoints";
     }
 
-    public List<Path> get(Object sourceId, Object targetId,
-                          Direction direction, String label,
-                          int maxDepth, long degree,
-                          long capacity, int limit) {
+    public PathWithMeasure get(Object sourceId, Object targetId,
+                               Direction direction, String label,
+                               int maxDepth, long degree,
+                               long capacity, long limit) {
         String source = GraphAPI.formatVertexId(sourceId, false);
         String target = GraphAPI.formatVertexId(targetId, false);
 
@@ -60,6 +59,6 @@ public class CrosspointsAPI extends TraversersAPI {
         params.put("capacity", capacity);
         params.put("limit", limit);
         RestResult result = this.client.get(this.path(), params);
-        return result.readList("crosspoints", Path.class);
+        return result.readObject(PathWithMeasure.class);
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/CustomizedCrosspointsAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/CustomizedCrosspointsAPI.java
index 70eb9481..eb69e789 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/CustomizedCrosspointsAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/CustomizedCrosspointsAPI.java
@@ -24,8 +24,8 @@ import org.apache.hugegraph.structure.traverser.CustomizedCrosspoints;
 
 public class CustomizedCrosspointsAPI extends TraversersAPI {
 
-    public CustomizedCrosspointsAPI(RestClient client, String graph) {
-        super(client, graph);
+    public CustomizedCrosspointsAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/CustomizedPathsAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/CustomizedPathsAPI.java
index 43a826f6..ac1c9f6d 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/CustomizedPathsAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/CustomizedPathsAPI.java
@@ -24,8 +24,8 @@ import org.apache.hugegraph.structure.traverser.CustomizedPathsRequest;
 
 public class CustomizedPathsAPI extends TraversersAPI {
 
-    public CustomizedPathsAPI(RestClient client, String graph) {
-        super(client, graph);
+    public CustomizedPathsAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/EdgeExistenceAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/EdgeExistenceAPI.java
index a62a7972..81b852a7 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/EdgeExistenceAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/EdgeExistenceAPI.java
@@ -30,8 +30,8 @@ import java.util.Map;
 
 public class EdgeExistenceAPI extends TraversersAPI {
 
-    public EdgeExistenceAPI(RestClient client, String graph) {
-        super(client, graph);
+    public EdgeExistenceAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/EdgesAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/EdgesAPI.java
index 162b9dec..2813e9f5 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/EdgesAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/EdgesAPI.java
@@ -32,8 +32,8 @@ import com.google.common.collect.ImmutableMap;
 
 public class EdgesAPI extends TraversersAPI {
 
-    public EdgesAPI(RestClient client, String graph) {
-        super(client, graph);
+    public EdgesAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/CustomizedPathsAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/EgonetAPI.java
similarity index 70%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/CustomizedPathsAPI.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/EgonetAPI.java
index 43a826f6..f1b1e598 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/CustomizedPathsAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/EgonetAPI.java
@@ -19,22 +19,23 @@ package org.apache.hugegraph.api.traverser;
 
 import org.apache.hugegraph.client.RestClient;
 import org.apache.hugegraph.rest.RestResult;
-import org.apache.hugegraph.structure.traverser.PathsWithVertices;
-import org.apache.hugegraph.structure.traverser.CustomizedPathsRequest;
+import org.apache.hugegraph.structure.traverser.Egonet;
+import org.apache.hugegraph.structure.traverser.EgonetRequest;
 
-public class CustomizedPathsAPI extends TraversersAPI {
+public class EgonetAPI extends TraversersAPI {
 
-    public CustomizedPathsAPI(RestClient client, String graph) {
-        super(client, graph);
+    public EgonetAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
     protected String type() {
-        return "customizedpaths";
+        return "egonet";
     }
 
-    public PathsWithVertices post(CustomizedPathsRequest request) {
+    public Egonet post(EgonetRequest request) {
+        this.client.checkApiVersion("0.66", "egonet");
         RestResult result = this.client.post(this.path(), request);
-        return result.readObject(PathsWithVertices.class);
+        return result.readObject(Egonet.class);
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/FusiformSimilarityAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/FusiformSimilarityAPI.java
index 5987f0c6..e8573d1e 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/FusiformSimilarityAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/FusiformSimilarityAPI.java
@@ -24,8 +24,8 @@ import org.apache.hugegraph.structure.traverser.FusiformSimilarityRequest;
 
 public class FusiformSimilarityAPI extends TraversersAPI {
 
-    public FusiformSimilarityAPI(RestClient client, String graph) {
-        super(client, graph);
+    public FusiformSimilarityAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/JaccardSimilarityAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/JaccardSimilarityAPI.java
index f87958bb..5f83355c 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/JaccardSimilarityAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/JaccardSimilarityAPI.java
@@ -35,8 +35,8 @@ public class JaccardSimilarityAPI extends TraversersAPI {
 
     private static final String JACCARD_SIMILARITY = "jaccard_similarity";
 
-    public JaccardSimilarityAPI(RestClient client, String graph) {
-        super(client, graph);
+    public JaccardSimilarityAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
@@ -44,8 +44,24 @@ public class JaccardSimilarityAPI extends TraversersAPI {
         return "jaccardsimilarity";
     }
 
-    public double get(Object vertexId, Object otherId, Direction direction,
-                      String label, long degree) {
+    private static JaccardSimilarity deserializeJaccardSimilarity(RestResult result) {
+        if (result.content().contains("similarsMap")) {
+            JaccardSimilarity jaccard = result.readObject(JaccardSimilarity.class);
+            E.checkState(jaccard.similarsMap() != null,
+                         "The result doesn't have key '%s'", JACCARD_SIMILARITY);
+            return jaccard;
+        } else {
+            JaccardSimilarity jaccard = new JaccardSimilarity();
+            @SuppressWarnings("unchecked")
+            Map<Object, Double> map = result.readObject(Map.class);
+            jaccard.setSimilarsMap(map);
+            return jaccard;
+        }
+    }
+
+    public JaccardSimilarity get(Object vertexId, Object otherId,
+                                 Direction direction, String label,
+                                 long degree) {
         this.client.checkApiVersion("0.51", "jaccard similarity");
         String vertex = GraphAPI.formatVertexId(vertexId, false);
         String other = GraphAPI.formatVertexId(otherId, false);
@@ -57,17 +73,16 @@ public class JaccardSimilarityAPI extends TraversersAPI {
         params.put("label", label);
         params.put("max_degree", degree);
         RestResult result = this.client.get(this.path(), params);
-        @SuppressWarnings("unchecked")
-        Map<String, Double> jaccard = result.readObject(Map.class);
-        E.checkState(jaccard.containsKey(JACCARD_SIMILARITY),
+        JaccardSimilarity jaccard = deserializeJaccardSimilarity(result);
+        E.checkState(jaccard.similarsMap() != null,
                      "The result doesn't have key '%s'", JACCARD_SIMILARITY);
-        return jaccard.get(JACCARD_SIMILARITY);
+        return jaccard;
     }
 
     @SuppressWarnings("unchecked")
     public JaccardSimilarity post(SingleSourceJaccardSimilarityRequest request) {
         this.client.checkApiVersion("0.58", "jaccard similar");
         RestResult result = this.client.post(this.path(), request);
-        return result.readObject(JaccardSimilarity.class);
+        return deserializeJaccardSimilarity(result);
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/KneighborAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/KneighborAPI.java
index 7470e28c..d0d7ae5a 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/KneighborAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/KneighborAPI.java
@@ -30,8 +30,8 @@ import org.apache.hugegraph.structure.traverser.KneighborRequest;
 
 public class KneighborAPI extends TraversersAPI {
 
-    public KneighborAPI(RestClient client, String graph) {
-        super(client, graph);
+    public KneighborAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
@@ -39,8 +39,9 @@ public class KneighborAPI extends TraversersAPI {
         return "kneighbor";
     }
 
-    public List<Object> get(Object sourceId, Direction direction,
-                            String label, int depth, long degree, int limit) {
+    public Map<String, Object> get(Object sourceId, Direction direction,
+                                   String label, int depth, long degree,
+                                   long limit) {
         String source = GraphAPI.formatVertexId(sourceId, false);
 
         checkPositive(depth, "Depth of k-neighbor");
@@ -55,7 +56,10 @@ public class KneighborAPI extends TraversersAPI {
         params.put("max_degree", degree);
         params.put("limit", limit);
         RestResult result = this.client.get(this.path(), params);
-        return result.readList("vertices", Object.class);
+        Map<String, Object> resMap = result.readObject(Map.class);
+        List<Object> ids = (List<Object>) resMap.get("vertices");
+        resMap.put("vertices", ids);
+        return resMap;
     }
 
     public Kneighbor post(KneighborRequest request) {
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/KoutAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/KoutAPI.java
index ec933271..1b7d1fed 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/KoutAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/KoutAPI.java
@@ -30,8 +30,8 @@ import org.apache.hugegraph.structure.traverser.KoutRequest;
 
 public class KoutAPI extends TraversersAPI {
 
-    public KoutAPI(RestClient client, String graph) {
-        super(client, graph);
+    public KoutAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
@@ -39,9 +39,9 @@ public class KoutAPI extends TraversersAPI {
         return "kout";
     }
 
-    public List<Object> get(Object sourceId, Direction direction,
-                            String label, int depth, boolean nearest,
-                            long degree, long capacity, int limit) {
+    public Map<String, Object> get(Object sourceId, Direction direction,
+                                   String label, int depth, boolean nearest,
+                                   long degree, long capacity, long limit) {
         String source = GraphAPI.formatVertexId(sourceId, false);
 
         checkPositive(depth, "Depth of k-out");
@@ -59,7 +59,10 @@ public class KoutAPI extends TraversersAPI {
         params.put("capacity", capacity);
         params.put("limit", limit);
         RestResult result = this.client.get(this.path(), params);
-        return result.readList("vertices", Object.class);
+        Map<String, Object> resMap = result.readObject(Map.class);
+        List<Object> ids = (List<Object>) resMap.get("vertices");
+        resMap.put("vertices", ids);
+        return resMap;
     }
 
     public Kout post(KoutRequest request) {
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/MultiNodeShortestPathAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/MultiNodeShortestPathAPI.java
index 8036d41c..495a6268 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/MultiNodeShortestPathAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/MultiNodeShortestPathAPI.java
@@ -24,8 +24,8 @@ import org.apache.hugegraph.structure.traverser.PathsWithVertices;
 
 public class MultiNodeShortestPathAPI extends TraversersAPI {
 
-    public MultiNodeShortestPathAPI(RestClient client, String graph) {
-        super(client, graph);
+    public MultiNodeShortestPathAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/NeighborRankAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/NeighborRankAPI.java
index d7057337..953be7a8 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/NeighborRankAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/NeighborRankAPI.java
@@ -25,15 +25,15 @@ import org.apache.hugegraph.client.RestClient;
 import org.apache.hugegraph.rest.RestResult;
 import org.apache.hugegraph.structure.constant.Direction;
 import org.apache.hugegraph.structure.constant.Traverser;
-import org.apache.hugegraph.structure.traverser.Ranks;
+import org.apache.hugegraph.structure.traverser.RanksWithMeasure;
 import org.apache.hugegraph.util.E;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 public class NeighborRankAPI extends TraversersAPI {
 
-    public NeighborRankAPI(RestClient client, String graph) {
-        super(client, graph);
+    public NeighborRankAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
@@ -41,9 +41,9 @@ public class NeighborRankAPI extends TraversersAPI {
         return "neighborrank";
     }
 
-    public List<Ranks> post(Request request) {
+    public RanksWithMeasure post(Request request) {
         RestResult result = this.client.post(this.path(), request);
-        return result.readList("ranks", Ranks.class);
+        return result.readObject(RanksWithMeasure.class);
     }
 
     public static class Request {
@@ -77,8 +77,8 @@ public class NeighborRankAPI extends TraversersAPI {
 
         public static class Builder {
 
-            private Request request;
-            private List<Step.Builder> stepBuilders;
+            private final Request request;
+            private final List<Step.Builder> stepBuilders;
 
             private Builder() {
                 this.request = new Request();
@@ -86,8 +86,8 @@ public class NeighborRankAPI extends TraversersAPI {
             }
 
             public Builder source(Object source) {
-                E.checkArgument(source != null,
-                                "The label of request for neighbor rank can't be null");
+                E.checkArgument(source != null, "The label of request " +
+                                                "for neighbor rank can't be null");
                 this.request.source = source;
                 return this;
             }
@@ -140,7 +140,7 @@ public class NeighborRankAPI extends TraversersAPI {
                 this.direction = null;
                 this.labels = new ArrayList<>();
                 this.degree = Traverser.DEFAULT_MAX_DEGREE;
-                this.top = (int) Traverser.DEFAULT_PATHS_LIMIT;
+                this.top = Traverser.DEFAULT_PATHS_LIMIT;
             }
 
             @Override
@@ -152,7 +152,7 @@ public class NeighborRankAPI extends TraversersAPI {
 
             public static class Builder {
 
-                private Step step;
+                private final Step step;
 
                 private Builder() {
                     this.step = new Step();
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/PathsAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/PathsAPI.java
index 2d14cae7..d37e267d 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/PathsAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/PathsAPI.java
@@ -18,21 +18,20 @@
 package org.apache.hugegraph.api.traverser;
 
 import java.util.LinkedHashMap;
-import java.util.List;
 import java.util.Map;
 
 import org.apache.hugegraph.api.graph.GraphAPI;
 import org.apache.hugegraph.client.RestClient;
 import org.apache.hugegraph.rest.RestResult;
 import org.apache.hugegraph.structure.constant.Direction;
-import org.apache.hugegraph.structure.graph.Path;
+import org.apache.hugegraph.structure.traverser.PathWithMeasure;
 import org.apache.hugegraph.structure.traverser.PathsRequest;
 import org.apache.hugegraph.structure.traverser.PathsWithVertices;
 
 public class PathsAPI extends TraversersAPI {
 
-    public PathsAPI(RestClient client, String graph) {
-        super(client, graph);
+    public PathsAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
@@ -40,10 +39,10 @@ public class PathsAPI extends TraversersAPI {
         return "paths";
     }
 
-    public List<Path> get(Object sourceId, Object targetId,
-                          Direction direction, String label,
-                          int maxDepth, long degree, long capacity,
-                          int limit) {
+    public PathWithMeasure get(Object sourceId, Object targetId,
+                               Direction direction, String label,
+                               int maxDepth, long degree, long capacity,
+                               long limit) {
         String source = GraphAPI.formatVertexId(sourceId, false);
         String target = GraphAPI.formatVertexId(targetId, false);
 
@@ -62,7 +61,7 @@ public class PathsAPI extends TraversersAPI {
         params.put("capacity", capacity);
         params.put("limit", limit);
         RestResult result = this.client.get(this.path(), params);
-        return result.readList("paths", Path.class);
+        return result.readObject(PathWithMeasure.class);
     }
 
     public PathsWithVertices post(PathsRequest request) {
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/PersonalRankAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/PersonalRankAPI.java
index 5d7fbb2b..536a6390 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/PersonalRankAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/PersonalRankAPI.java
@@ -17,18 +17,20 @@
 
 package org.apache.hugegraph.api.traverser;
 
-import org.apache.hugegraph.client.RestClient;
 import org.apache.hugegraph.rest.RestResult;
-import org.apache.hugegraph.structure.constant.Traverser;
 import org.apache.hugegraph.structure.traverser.Ranks;
 import org.apache.hugegraph.util.E;
 
+import org.apache.hugegraph.client.RestClient;
+import org.apache.hugegraph.structure.constant.Traverser;
+import org.apache.hugegraph.structure.traverser.RanksWithMeasure;
+
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 public class PersonalRankAPI extends TraversersAPI {
 
-    public PersonalRankAPI(RestClient client, String graph) {
-        super(client, graph);
+    public PersonalRankAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
@@ -36,9 +38,18 @@ public class PersonalRankAPI extends TraversersAPI {
         return "personalrank";
     }
 
-    public Ranks post(Request request) {
+    public RanksWithMeasure post(Request request) {
         RestResult result = this.client.post(this.path(), request);
-        return result.readObject(Ranks.class);
+        // to compatible with the old version, the result may be Ranks or RanksWithMeasure
+        // so we need to check the content of result to decide which class to use
+        if (result.content().contains("measure")) {
+            return result.readObject(RanksWithMeasure.class);
+        } else {
+            Ranks personalRanks = result.readObject(Ranks.class);
+            RanksWithMeasure ranksWithMeasure = new RanksWithMeasure();
+            ranksWithMeasure.setPersonalRank(personalRanks);
+            return ranksWithMeasure;
+        }
     }
 
     public static class Request {
@@ -52,7 +63,7 @@ public class PersonalRankAPI extends TraversersAPI {
         @JsonProperty("max_degree")
         public long degree = Traverser.DEFAULT_MAX_DEGREE;
         @JsonProperty("limit")
-        private int limit = Traverser.DEFAULT_LIMIT;
+        private long limit = Traverser.DEFAULT_LIMIT;
         @JsonProperty("max_depth")
         private int maxDepth = 5;
         @JsonProperty("with_label")
@@ -82,7 +93,7 @@ public class PersonalRankAPI extends TraversersAPI {
 
         public static class Builder {
 
-            private Request request;
+            private final Request request;
 
             private Builder() {
                 this.request = new Request();
@@ -114,7 +125,7 @@ public class PersonalRankAPI extends TraversersAPI {
                 return this;
             }
 
-            public Builder limit(int limit) {
+            public Builder limit(long limit) {
                 TraversersAPI.checkLimit(limit);
                 this.request.limit = limit;
                 return this;
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/RaysAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/RaysAPI.java
index 9908b311..7d922181 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/RaysAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/RaysAPI.java
@@ -18,19 +18,18 @@
 package org.apache.hugegraph.api.traverser;
 
 import java.util.LinkedHashMap;
-import java.util.List;
 import java.util.Map;
 
 import org.apache.hugegraph.api.graph.GraphAPI;
 import org.apache.hugegraph.client.RestClient;
 import org.apache.hugegraph.rest.RestResult;
 import org.apache.hugegraph.structure.constant.Direction;
-import org.apache.hugegraph.structure.graph.Path;
+import org.apache.hugegraph.structure.traverser.PathWithMeasure;
 
 public class RaysAPI extends TraversersAPI {
 
-    public RaysAPI(RestClient client, String graph) {
-        super(client, graph);
+    public RaysAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
@@ -38,8 +37,8 @@ public class RaysAPI extends TraversersAPI {
         return "rays";
     }
 
-    public List<Path> get(Object sourceId, Direction direction, String label,
-                          int depth, long degree, long capacity, int limit) {
+    public PathWithMeasure get(Object sourceId, Direction direction, String label,
+                               int depth, long degree, long capacity, long limit) {
         String source = GraphAPI.formatVertexId(sourceId, false);
 
         checkPositive(depth, "Max depth of path");
@@ -56,6 +55,6 @@ public class RaysAPI extends TraversersAPI {
         params.put("capacity", capacity);
         params.put("limit", limit);
         RestResult result = this.client.get(this.path(), params);
-        return result.readList(this.type(), Path.class);
+        return result.readObject(PathWithMeasure.class);
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/SameNeighborsAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/ResourceAllocationAPI.java
similarity index 62%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/SameNeighborsAPI.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/ResourceAllocationAPI.java
index 1ef4b9ce..b2b8da16 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/SameNeighborsAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/ResourceAllocationAPI.java
@@ -17,32 +17,34 @@
 
 package org.apache.hugegraph.api.traverser;
 
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.hugegraph.api.graph.GraphAPI;
 import org.apache.hugegraph.client.RestClient;
+import org.apache.hugegraph.api.graph.GraphAPI;
 import org.apache.hugegraph.rest.RestResult;
 import org.apache.hugegraph.structure.constant.Direction;
+import org.apache.hugegraph.structure.traverser.Prediction;
+import org.apache.hugegraph.util.E;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
 
-public class SameNeighborsAPI extends TraversersAPI {
+public class ResourceAllocationAPI extends TraversersAPI {
 
-    private static final String SAME_NEIGHBORS = "same_neighbors";
+    private static final String RESOURCE_ALLOCATION = "resource_allocation";
 
-    public SameNeighborsAPI(RestClient client, String graph) {
-        super(client, graph);
+    public ResourceAllocationAPI(RestClient client,
+                                 String graphSpace,
+                                 String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
     protected String type() {
-        return "sameneighbors";
+        return "resourceallocation";
     }
 
-    public List<Object> get(Object vertexId, Object otherId,
-                            Direction direction, String label,
-                            long degree, int limit) {
-        this.client.checkApiVersion("0.51", "same neighbors");
+    public Prediction get(Object vertexId, Object otherId, Direction direction,
+                          String label, long degree) {
+        this.client.checkApiVersion("0.67", RESOURCE_ALLOCATION);
         String vertex = GraphAPI.formatVertexId(vertexId, false);
         String other = GraphAPI.formatVertexId(otherId, false);
         checkDegree(degree);
@@ -52,8 +54,12 @@ public class SameNeighborsAPI extends TraversersAPI {
         params.put("direction", direction);
         params.put("label", label);
         params.put("max_degree", degree);
-        params.put("limit", limit);
         RestResult result = this.client.get(this.path(), params);
-        return result.readList(SAME_NEIGHBORS, Object.class);
+        @SuppressWarnings("unchecked")
+        Prediction res = result.readObject(Prediction.class);
+        Map<String, Double> resourceAllocation = result.readObject(Map.class);
+        E.checkState(res.getResourceAllocation() != null,
+                     "The result doesn't have key '%s'", RESOURCE_ALLOCATION);
+        return res;
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/RingsAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/RingsAPI.java
index 26aaff44..cd0416d1 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/RingsAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/RingsAPI.java
@@ -18,19 +18,18 @@
 package org.apache.hugegraph.api.traverser;
 
 import java.util.LinkedHashMap;
-import java.util.List;
 import java.util.Map;
 
 import org.apache.hugegraph.api.graph.GraphAPI;
 import org.apache.hugegraph.client.RestClient;
 import org.apache.hugegraph.rest.RestResult;
 import org.apache.hugegraph.structure.constant.Direction;
-import org.apache.hugegraph.structure.graph.Path;
+import org.apache.hugegraph.structure.traverser.PathWithMeasure;
 
 public class RingsAPI extends TraversersAPI {
 
-    public RingsAPI(RestClient client, String graph) {
-        super(client, graph);
+    public RingsAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
@@ -38,9 +37,9 @@ public class RingsAPI extends TraversersAPI {
         return "rings";
     }
 
-    public List<Path> get(Object sourceId, Direction direction, String label,
-                          int depth, boolean sourceInRing, long degree,
-                          long capacity, int limit) {
+    public PathWithMeasure get(Object sourceId, Direction direction, String label,
+                               int depth, boolean sourceInRing, long degree,
+                               long capacity, long limit) {
         String source = GraphAPI.formatVertexId(sourceId, false);
 
         checkPositive(depth, "Max depth of path");
@@ -63,6 +62,6 @@ public class RingsAPI extends TraversersAPI {
         params.put("capacity", capacity);
         params.put("limit", limit);
         RestResult result = this.client.get(this.path(), params);
-        return result.readList(this.type(), Path.class);
+        return result.readObject(PathWithMeasure.class);
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/SameNeighborsAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/SameNeighborsAPI.java
index 1ef4b9ce..57ce3e87 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/SameNeighborsAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/SameNeighborsAPI.java
@@ -18,20 +18,20 @@
 package org.apache.hugegraph.api.traverser;
 
 import java.util.LinkedHashMap;
-import java.util.List;
 import java.util.Map;
 
 import org.apache.hugegraph.api.graph.GraphAPI;
 import org.apache.hugegraph.client.RestClient;
 import org.apache.hugegraph.rest.RestResult;
 import org.apache.hugegraph.structure.constant.Direction;
+import org.apache.hugegraph.structure.traverser.SameNeighbors;
 
 public class SameNeighborsAPI extends TraversersAPI {
 
     private static final String SAME_NEIGHBORS = "same_neighbors";
 
-    public SameNeighborsAPI(RestClient client, String graph) {
-        super(client, graph);
+    public SameNeighborsAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
@@ -39,9 +39,9 @@ public class SameNeighborsAPI extends TraversersAPI {
         return "sameneighbors";
     }
 
-    public List<Object> get(Object vertexId, Object otherId,
-                            Direction direction, String label,
-                            long degree, int limit) {
+    public SameNeighbors get(Object vertexId, Object otherId,
+                             Direction direction, String label,
+                             long degree, long limit) {
         this.client.checkApiVersion("0.51", "same neighbors");
         String vertex = GraphAPI.formatVertexId(vertexId, false);
         String other = GraphAPI.formatVertexId(otherId, false);
@@ -54,6 +54,6 @@ public class SameNeighborsAPI extends TraversersAPI {
         params.put("max_degree", degree);
         params.put("limit", limit);
         RestResult result = this.client.get(this.path(), params);
-        return result.readList(SAME_NEIGHBORS, Object.class);
+        return result.readObject(SameNeighbors.class);
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/FusiformSimilarityAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/SameNeighborsBatchAPI.java
similarity index 65%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/FusiformSimilarityAPI.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/SameNeighborsBatchAPI.java
index 5987f0c6..d57d859f 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/FusiformSimilarityAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/SameNeighborsBatchAPI.java
@@ -19,23 +19,23 @@ package org.apache.hugegraph.api.traverser;
 
 import org.apache.hugegraph.client.RestClient;
 import org.apache.hugegraph.rest.RestResult;
-import org.apache.hugegraph.structure.traverser.FusiformSimilarity;
-import org.apache.hugegraph.structure.traverser.FusiformSimilarityRequest;
+import org.apache.hugegraph.structure.traverser.SameNeighborsBatch;
+import org.apache.hugegraph.structure.traverser.SameNeighborsBatchRequest;
 
-public class FusiformSimilarityAPI extends TraversersAPI {
+public class SameNeighborsBatchAPI extends TraversersAPI {
 
-    public FusiformSimilarityAPI(RestClient client, String graph) {
-        super(client, graph);
+    public SameNeighborsBatchAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
     protected String type() {
-        return "fusiformsimilarity";
+        return "sameneighborsbatch";
     }
 
-    public FusiformSimilarity post(FusiformSimilarityRequest request) {
-        this.client.checkApiVersion("0.49", "fusiform similarity");
+    public SameNeighborsBatch post(SameNeighborsBatchRequest request) {
+        this.client.checkApiVersion("0.66", "same neighbors batch");
         RestResult result = this.client.post(this.path(), request);
-        return result.readObject(FusiformSimilarity.class);
+        return result.readObject(SameNeighborsBatch.class);
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/ShortestPathAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/ShortestPathAPI.java
index 4b5cfa99..ca2d3f3c 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/ShortestPathAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/ShortestPathAPI.java
@@ -18,19 +18,18 @@
 package org.apache.hugegraph.api.traverser;
 
 import java.util.LinkedHashMap;
-import java.util.List;
 import java.util.Map;
 
 import org.apache.hugegraph.api.graph.GraphAPI;
 import org.apache.hugegraph.client.RestClient;
 import org.apache.hugegraph.rest.RestResult;
 import org.apache.hugegraph.structure.constant.Direction;
-import org.apache.hugegraph.structure.graph.Path;
+import org.apache.hugegraph.structure.traverser.PathOfVertices;
 
 public class ShortestPathAPI extends TraversersAPI {
 
-    public ShortestPathAPI(RestClient client, String graph) {
-        super(client, graph);
+    public ShortestPathAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
@@ -38,9 +37,9 @@ public class ShortestPathAPI extends TraversersAPI {
         return "shortestpath";
     }
 
-    public Path get(Object sourceId, Object targetId,
-                    Direction direction, String label, int maxDepth,
-                    long degree, long skipDegree, long capacity) {
+    public PathOfVertices get(Object sourceId, Object targetId,
+                              Direction direction, String label, int maxDepth,
+                              long degree, long skipDegree, long capacity) {
         String source = GraphAPI.formatVertexId(sourceId, false);
         String target = GraphAPI.formatVertexId(targetId, false);
 
@@ -59,7 +58,6 @@ public class ShortestPathAPI extends TraversersAPI {
         params.put("skip_degree", skipDegree);
         params.put("capacity", capacity);
         RestResult result = this.client.get(this.path(), params);
-        List<Object> vertices = result.readList("path", Object.class);
-        return new Path(vertices);
+        return result.readObject(PathOfVertices.class);
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/SingleSourceShortestPathAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/SingleSourceShortestPathAPI.java
index 31ee2dbd..dab3cce2 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/SingleSourceShortestPathAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/SingleSourceShortestPathAPI.java
@@ -29,8 +29,8 @@ import org.apache.hugegraph.util.E;
 
 public class SingleSourceShortestPathAPI extends TraversersAPI {
 
-    public SingleSourceShortestPathAPI(RestClient client, String graph) {
-        super(client, graph);
+    public SingleSourceShortestPathAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
@@ -40,7 +40,7 @@ public class SingleSourceShortestPathAPI extends TraversersAPI {
 
     public WeightedPaths get(Object sourceId, Direction direction, String label,
                              String weight, long degree, long skipDegree,
-                             long capacity, int limit, boolean withVertex, boolean withEdge) {
+                             long capacity, long limit, boolean withVertex, boolean withEdge) {
         this.client.checkApiVersion("0.51", "single source shortest path");
         String source = GraphAPI.formatVertexId(sourceId, false);
 
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/TemplatePathsAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/TemplatePathsAPI.java
index 2f198738..eef1f222 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/TemplatePathsAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/TemplatePathsAPI.java
@@ -24,8 +24,8 @@ import org.apache.hugegraph.structure.traverser.TemplatePathsRequest;
 
 public class TemplatePathsAPI extends TraversersAPI {
 
-    public TemplatePathsAPI(RestClient client, String graph) {
-        super(client, graph);
+    public TemplatePathsAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/TraversersAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/TraversersAPI.java
index 20b765a7..2a764a12 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/TraversersAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/TraversersAPI.java
@@ -23,11 +23,11 @@ import org.apache.hugegraph.util.E;
 
 public class TraversersAPI extends API {
 
-    private static final String PATH = "graphs/%s/traversers/%s";
+    private static final String PATH = "graphspaces/%s/graphs/%s/traversers/%s";
 
-    public TraversersAPI(RestClient client, String graph) {
+    public TraversersAPI(RestClient client, String graphSpace, String graph) {
         super(client);
-        this.path(PATH, graph, this.type());
+        this.path(PATH, graphSpace, graph, this.type());
     }
 
     @Override
@@ -48,7 +48,7 @@ public class TraversersAPI extends API {
         checkLimit(capacity, "Capacity");
     }
 
-    public static void checkLimit(int limit) {
+    public static void checkLimit(long limit) {
         checkLimit(limit, "Limit");
     }
 
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/EdgesAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/VariablesAPI.java
similarity index 72%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/EdgesAPI.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/VariablesAPI.java
index 162b9dec..240e1416 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/EdgesAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/VariablesAPI.java
@@ -14,41 +14,28 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
-
 package org.apache.hugegraph.api.traverser;
 
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
 import org.apache.hugegraph.client.RestClient;
-import org.apache.hugegraph.rest.RestResult;
-import org.apache.hugegraph.structure.graph.Edge;
-import org.apache.hugegraph.structure.graph.Edges;
 import org.apache.hugegraph.structure.graph.Shard;
+import org.apache.hugegraph.structure.graph.Vertices;
+import com.google.common.collect.ImmutableMap;
+import org.apache.hugegraph.rest.RestResult;
 import org.apache.hugegraph.util.E;
 
-import com.google.common.collect.ImmutableMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
 
-public class EdgesAPI extends TraversersAPI {
+public class VariablesAPI extends TraversersAPI {
 
-    public EdgesAPI(RestClient client, String graph) {
-        super(client, graph);
+    public VariablesAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
     protected String type() {
-        return "edges";
-    }
-
-    public List<Edge> list(List<String> ids) {
-        E.checkArgument(ids != null && !ids.isEmpty(),
-                        "Ids can't be null or empty");
-
-        Map<String, Object> params = new LinkedHashMap<>();
-        params.put("ids", ids);
-        RestResult result = this.client.get(this.path(), params);
-        return result.readList(this.type(), Edge.class);
+        return "variables";
     }
 
     public List<Shard> shards(long splitSize) {
@@ -58,7 +45,7 @@ public class EdgesAPI extends TraversersAPI {
         return result.readList("shards", Shard.class);
     }
 
-    public Edges scan(Shard shard, String page, long pageLimit) {
+    public Vertices scan(Shard shard, String page, long pageLimit) {
         E.checkArgument(shard != null, "Shard can't be null");
         String path = String.join(PATH_SPLITOR, this.path(), "scan");
         Map<String, Object> params = new LinkedHashMap<>();
@@ -67,7 +54,6 @@ public class EdgesAPI extends TraversersAPI {
         params.put("page", page);
         params.put("page_limit", pageLimit);
         RestResult result = this.client.get(path, params);
-        return result.readObject(Edges.class);
+        return result.readObject(Vertices.class);
     }
 }
-
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/VerticesAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/VerticesAPI.java
index c80a4fa7..7718a0ae 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/VerticesAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/VerticesAPI.java
@@ -34,8 +34,8 @@ import com.google.common.collect.ImmutableMap;
 
 public class VerticesAPI extends TraversersAPI {
 
-    public VerticesAPI(RestClient client, String graph) {
-        super(client, graph);
+    public VerticesAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/WeightedShortestPathAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/WeightedShortestPathAPI.java
index aaf043f9..97b0c53c 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/WeightedShortestPathAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/WeightedShortestPathAPI.java
@@ -29,8 +29,8 @@ import org.apache.hugegraph.util.E;
 
 public class WeightedShortestPathAPI extends TraversersAPI {
 
-    public WeightedShortestPathAPI(RestClient client, String graph) {
-        super(client, graph);
+    public WeightedShortestPathAPI(RestClient client, String graphSpace, String graph) {
+        super(client, graphSpace, graph);
     }
 
     @Override
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/vermeer/VermeerAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/vermeer/VermeerAPI.java
new file mode 100644
index 00000000..93b78aff
--- /dev/null
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/vermeer/VermeerAPI.java
@@ -0,0 +1,86 @@
+/*
+ * 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.hugegraph.api.vermeer;
+
+import com.google.common.collect.ImmutableMap;
+
+import org.apache.hugegraph.client.RestClient;
+import org.apache.hugegraph.api.API;
+import org.apache.hugegraph.rest.RestResult;
+import org.apache.hugegraph.structure.constant.HugeType;
+
+import java.util.Map;
+
+public class VermeerAPI extends API {
+
+    private static final String PATH = "vermeer";
+    private static final String GET_SYS_CFG =
+            "api/v1.0/memt_clu/config/getsyscfg";
+
+    public VermeerAPI(RestClient client) {
+        super(client);
+    }
+
+    @Override
+    protected String type() {
+        return HugeType.VERMEER.string();
+    }
+
+    public Map<String, Object> getStatus() {
+        Map<String, Object> sertMap = ImmutableMap.of("sertype", "vermeer");
+        RestResult results = this.client.post(GET_SYS_CFG, sertMap);
+        return results.readObject(Map.class);
+    }
+
+    public Map<String, Object> post(Map<String, Object> params) {
+        this.path(PATH);
+        RestResult results = this.client.post(this.path(), params);
+        return results.readObject(Map.class);
+    }
+
+    public Map<String, Object> getGraphsInfo() {
+        this.path(String.join("/", PATH, "vermeergraphs"));
+        RestResult results = this.client.get(this.path());
+        return results.readObject(Map.class);
+    }
+
+    public Map<String, Object> getGraphInfoByName(String graphName) {
+        this.path(String.join("/", PATH, "vermeergraphs", graphName));
+        RestResult results = this.client.get(this.path());
+        return results.readObject(Map.class);
+    }
+
+    public Map<String, Object> deleteGraphByName(String graphName) {
+        this.path(String.join("/", PATH, "vermeergraphs", graphName));
+        RestResult results = this.client.delete(this.path(), ImmutableMap.of());
+        return results.readObject(Map.class);
+    }
+
+    public Map<String, Object> getTasksInfo() {
+        this.path(String.join("/", PATH, "vermeertasks"));
+        RestResult results = this.client.get(this.path());
+        return results.readObject(Map.class);
+    }
+
+    public Map<String, Object> getTasksInfoById(String taskId) {
+        this.path(
+                String.join("/", PATH, "vermeertasks", taskId));
+        RestResult results = this.client.get(this.path());
+        return results.readObject(Map.class);
+    }
+}
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/client/RestClient.java b/hugegraph-client/src/main/java/org/apache/hugegraph/client/RestClient.java
index 5d29c845..f7550bfd 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/client/RestClient.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/client/RestClient.java
@@ -63,10 +63,21 @@ public class RestClient extends AbstractRestClient {
               maxConnsPerRoute, trustStoreFile, trustStorePassword);
     }
 
+    public RestClient(String url, String token, int timeout) {
+        this(url, RestClientConfig.builder().token(token).timeout(timeout * SECOND).build());
+    }
+
     public RestClient(String url, RestClientConfig config) {
         super(url, config);
     }
 
+    public RestClient(String url, String token, int timeout, int maxConns,
+                      int maxConnsPerRoute, String trustStoreFile,
+                      String trustStorePassword) {
+        super(url, token, timeout * SECOND, maxConns,
+              maxConnsPerRoute, trustStoreFile, trustStorePassword);
+    }
+
     private static String removeDefaultGsPrefix(String path) {
         final String DEFAULT_GS_PATH_PREFIX = "graphspaces/DEFAULT/";
         final String EMPTY = "";
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/AuthManager.java b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/AuthManager.java
index a15e7353..bd8e77b0 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/AuthManager.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/AuthManager.java
@@ -18,6 +18,7 @@
 package org.apache.hugegraph.driver;
 
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.collections.CollectionUtils;
@@ -27,6 +28,7 @@ import org.apache.hugegraph.api.auth.BelongAPI;
 import org.apache.hugegraph.api.auth.GroupAPI;
 import org.apache.hugegraph.api.auth.LoginAPI;
 import org.apache.hugegraph.api.auth.LogoutAPI;
+import org.apache.hugegraph.api.auth.ManagerAPI;
 import org.apache.hugegraph.api.auth.ProjectAPI;
 import org.apache.hugegraph.api.auth.TargetAPI;
 import org.apache.hugegraph.api.auth.TokenAPI;
@@ -35,12 +37,14 @@ import org.apache.hugegraph.client.RestClient;
 import org.apache.hugegraph.structure.auth.Access;
 import org.apache.hugegraph.structure.auth.Belong;
 import org.apache.hugegraph.structure.auth.Group;
+import org.apache.hugegraph.structure.auth.HugePermission;
 import org.apache.hugegraph.structure.auth.Login;
 import org.apache.hugegraph.structure.auth.LoginResult;
 import org.apache.hugegraph.structure.auth.Project;
 import org.apache.hugegraph.structure.auth.Target;
 import org.apache.hugegraph.structure.auth.TokenPayload;
 import org.apache.hugegraph.structure.auth.User;
+import org.apache.hugegraph.structure.auth.UserManager;
 
 public class AuthManager {
 
@@ -53,6 +57,7 @@ public class AuthManager {
     private final LoginAPI loginAPI;
     private final LogoutAPI logoutAPI;
     private final TokenAPI tokenAPI;
+    private final ManagerAPI managerAPI;
 
     public AuthManager(RestClient client, String graph) {
         this.targetAPI = new TargetAPI(client, graph);
@@ -64,6 +69,7 @@ public class AuthManager {
         this.loginAPI = new LoginAPI(client, graph);
         this.logoutAPI = new LogoutAPI(client, graph);
         this.tokenAPI = new TokenAPI(client, graph);
+        this.managerAPI = new ManagerAPI(client, graph);
     }
 
     public List<Target> listTargets() {
@@ -134,6 +140,10 @@ public class AuthManager {
         return this.userAPI.create(user);
     }
 
+    public Map<String, List<Map<String, String>>> createBatch(List<Map<String, String>> data) {
+        return this.userAPI.createBatch(data);
+    }
+
     public User updateUser(User user) {
         return this.userAPI.update(user);
     }
@@ -278,4 +288,51 @@ public class AuthManager {
     public TokenPayload verifyToken() {
         return this.tokenAPI.verifyToken();
     }
+
+    public UserManager addSuperAdmin(String user) {
+        UserManager userManager = new UserManager();
+        userManager.type(HugePermission.ADMIN);
+        userManager.user(user);
+        return this.managerAPI.create(userManager);
+    }
+
+    public UserManager addSpaceAdmin(String user, String graphSpace) {
+        UserManager userManager = new UserManager();
+        userManager.type(HugePermission.SPACE);
+        userManager.graphSpace(graphSpace);
+        userManager.user(user);
+        return this.managerAPI.create(userManager);
+    }
+
+    public void delSuperAdmin(String user) {
+        this.managerAPI.delete(user, HugePermission.ADMIN, null);
+    }
+
+    public void delSpaceAdmin(String user, String graphSpace) {
+        this.managerAPI.delete(user, HugePermission.SPACE, graphSpace);
+    }
+
+    public List<String> listSpaceAdmin(String graphSpace) {
+        return this.managerAPI.list(HugePermission.SPACE, graphSpace);
+    }
+
+    public List<String> listSuperAdmin() {
+        return this.managerAPI.list(HugePermission.ADMIN, null);
+    }
+
+    public boolean isSuperAdmin() {
+        return this.managerAPI.checkPermission(HugePermission.ADMIN, null);
+    }
+
+    public boolean isSpaceAdmin(String graphSpace) {
+        return this.managerAPI.checkPermission(HugePermission.SPACE, graphSpace);
+    }
+
+    public boolean checkDefaultRole(String graphSpace, String role) {
+        return this.managerAPI.checkDefaultRole(graphSpace, role, "");
+    }
+
+    public boolean checkDefaultRole(String graphSpace, String role, String graph) {
+        return this.managerAPI.checkDefaultRole(graphSpace, role, graph);
+    }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/TaskManager.java b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/ComputerManager.java
similarity index 52%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/driver/TaskManager.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/driver/ComputerManager.java
index e04a6311..9935ea9e 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/TaskManager.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/ComputerManager.java
@@ -17,58 +17,44 @@
 
 package org.apache.hugegraph.driver;
 
-import java.util.List;
-
-import org.apache.hugegraph.api.task.TaskAPI;
+import org.apache.hugegraph.api.task.ComputerDisAPI;
 import org.apache.hugegraph.api.task.TasksWithPage;
 import org.apache.hugegraph.client.RestClient;
 import org.apache.hugegraph.structure.Task;
 
-public class TaskManager {
+import java.util.List;
+import java.util.Map;
 
-    private TaskAPI taskAPI;
+public class ComputerManager {
 
-    public TaskManager(RestClient client, String graphSpace, String graph) {
-        this.taskAPI = new TaskAPI(client, graphSpace, graph);
-    }
+    private final ComputerDisAPI computerDisAPI;
 
-    public List<Task> list() {
-        return this.list(-1);
+    public ComputerManager(RestClient client, String graphSpace, String graph) {
+        this.computerDisAPI = new ComputerDisAPI(client, graphSpace, graph);
     }
 
-    public List<Task> list(long limit) {
-        return this.taskAPI.list(null, limit);
+    public long create(String algorithm, long worker,
+                       Map<String, Object> params) {
+        return this.computerDisAPI.create(algorithm, worker, params);
     }
 
-    public List<Task> list(List<Long> ids) {
-        return this.taskAPI.list(ids);
+    public void delete(long id) {
+        this.computerDisAPI.delete(id);
     }
 
-    public List<Task> list(String status) {
-        return this.list(status, -1L);
+    public void cancel(long id) {
+        this.computerDisAPI.cancel(id);
     }
 
-    public List<Task> list(String status, long limit) {
-        return this.taskAPI.list(status, limit);
+    public List<Task> list(long limit) {
+        return this.computerDisAPI.list(limit);
     }
 
-    public TasksWithPage list(String status, String page, long limit) {
-        return this.taskAPI.list(status, page, limit);
+    public TasksWithPage list(String page, long limit) {
+        return this.computerDisAPI.list(page, limit);
     }
 
     public Task get(long id) {
-        return this.taskAPI.get(id);
-    }
-
-    public void delete(long id) {
-        this.taskAPI.delete(id);
-    }
-
-    public Task cancel(long id) {
-        return this.taskAPI.cancel(id);
-    }
-
-    public Task waitUntilTaskCompleted(long taskId, long seconds) {
-        return this.taskAPI.waitUntilTaskSuccess(taskId, seconds);
+        return this.computerDisAPI.get(id);
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/GraphManager.java b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/GraphManager.java
index 98b82cd4..25efa802 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/GraphManager.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/GraphManager.java
@@ -23,6 +23,7 @@ import java.util.Map;
 
 import org.apache.hugegraph.annotation.UnimplementedFeature;
 import org.apache.hugegraph.api.graph.EdgeAPI;
+import org.apache.hugegraph.api.graph.GraphMetricsAPI;
 import org.apache.hugegraph.api.graph.VertexAPI;
 import org.apache.hugegraph.exception.InvalidOperationException;
 import org.apache.hugegraph.structure.GraphElement;
@@ -43,12 +44,14 @@ public class GraphManager {
     private final String graph;
     private final VertexAPI vertexAPI;
     private final EdgeAPI edgeAPI;
+    private final GraphMetricsAPI graphMetricsAPI;
 
     public GraphManager(RestClient client, String graphSpace, String graph) {
         this.graphSpace = graphSpace;
         this.graph = graph;
         this.vertexAPI = new VertexAPI(client, graphSpace, graph);
         this.edgeAPI = new EdgeAPI(client, graphSpace, graph);
+        this.graphMetricsAPI = new GraphMetricsAPI(client, graphSpace, graph);
     }
 
     public String graphSpace() {
@@ -96,6 +99,10 @@ public class GraphManager {
         return vertex;
     }
 
+    public void deleteVertex(Object vertexId) {
+        this.vertexAPI.delete(vertexId);
+    }
+
     public List<Vertex> addVertices(List<Vertex> vertices) {
         List<Object> ids = this.vertexAPI.create(vertices);
         for (int i = 0; i < vertices.size(); i++) {
@@ -207,6 +214,12 @@ public class GraphManager {
         return vertex;
     }
 
+    public Vertex updateVertexProperty(String vertexid, Vertex vertex) {
+        vertex = this.vertexAPI.update(vertexid, vertex);
+        this.attachManager(vertex);
+        return vertex;
+    }
+
     public Vertex eliminateVertexProperty(Vertex vertex) {
         vertex = this.vertexAPI.eliminate(vertex);
         this.attachManager(vertex);
@@ -256,6 +269,10 @@ public class GraphManager {
         return edge;
     }
 
+    public void deleteEdge(String edgeId) {
+        this.edgeAPI.delete(edgeId);
+    }
+
     public List<Edge> addEdges(List<Edge> edges) {
         return this.addEdges(edges, true);
     }
@@ -447,12 +464,46 @@ public class GraphManager {
         return edge;
     }
 
+    public Edge updateEdgeProperty(String edgeid, Edge edge) {
+        edge = this.edgeAPI.update(edgeid, edge);
+        this.attachManager(edge);
+        return edge;
+    }
+
     public Edge eliminateEdgeProperty(Edge edge) {
         edge = this.edgeAPI.eliminate(edge);
         this.attachManager(edge);
         return edge;
     }
 
+    public long createEVCountJob() {
+        return this.graphMetricsAPI.createEVCountJob();
+    }
+
+    public GraphMetricsAPI.ElementCount getEVCount(String strDate) {
+        return this.graphMetricsAPI.getEVCount(strDate);
+    }
+
+    public Map<String, GraphMetricsAPI.ElementCount> getEVCountByMonth(String strMonth) {
+        return this.graphMetricsAPI.getEVCountByMonth(strMonth);
+    }
+
+    public long createTypeCountJob() {
+        return this.graphMetricsAPI.createTypeCountJob();
+    }
+
+    public GraphMetricsAPI.TypeCount getTypeCount(String strDate) {
+        return this.graphMetricsAPI.getTypeCount(strDate);
+    }
+
+    public GraphMetricsAPI.TypeCounts getTypeCounts(String from, String to) {
+        return this.graphMetricsAPI.getTypeCounts(from, to);
+    }
+
+    public Map<String, GraphMetricsAPI.TypeCount> getTypeCountByMonth(String strMonth) {
+        return this.graphMetricsAPI.getTypeCountByMonth(strMonth);
+    }
+
     private Object getValue(String key, Object... keyValues) {
         E.checkArgument((keyValues.length & 0x01) == 0,
                         "The number of parameters must be even");
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/GraphsManager.java b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/GraphsManager.java
index e4ebf40c..aacf261f 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/GraphsManager.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/GraphsManager.java
@@ -17,24 +17,39 @@
 
 package org.apache.hugegraph.driver;
 
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.io.FileUtils;
 import org.apache.hugegraph.api.graphs.GraphsAPI;
+import org.apache.hugegraph.rest.ClientException;
 import org.apache.hugegraph.structure.constant.GraphMode;
 import org.apache.hugegraph.structure.constant.GraphReadMode;
 import org.apache.hugegraph.client.RestClient;
 
 public class GraphsManager {
 
-    private GraphsAPI graphsAPI;
+    private final GraphsAPI graphsAPI;
 
     public GraphsManager(RestClient client, String graphSpace) {
         this.graphsAPI = new GraphsAPI(client, graphSpace);
     }
 
-    public Map<String, String> createGraph(String name, String configText) {
-        return this.graphsAPI.create(name, null, configText);
+    public Map<String, String> createGraph(String name, String config) {
+        return this.graphsAPI.create(name, null, config);
+    }
+
+    public Map<String, String> createGraph(String name, File file) {
+        String config;
+        try {
+            config = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
+        } catch (IOException e) {
+            throw new ClientException("Failed to read config file: %s", file);
+        }
+        return this.graphsAPI.create(name, null, config);
     }
 
     public Map<String, String> cloneGraph(String name, String cloneGraphName) {
@@ -54,14 +69,48 @@ public class GraphsManager {
         return this.graphsAPI.list();
     }
 
+    public List<Map<String, Object>> listProfile() {
+        return this.graphsAPI.listProfile(null);
+    }
+
+    public List<Map<String, Object>> listProfile(String prefix) {
+        return this.graphsAPI.listProfile(prefix);
+    }
+
+    public Map<String, String> setDefault(String name) {
+        return this.graphsAPI.setDefault(name);
+    }
+
+    public Map<String, String> unSetDefault(String name) {
+        return this.graphsAPI.unSetDefault(name);
+    }
+
+    public Map<String, String> getDefault() {
+        return this.graphsAPI.getDefault();
+    }
+
+    // TODO(@Thespica): see org.apache.hugegraph.api.graphs.GraphsAPI.clear
     public void clearGraph(String graph, String message) {
         this.graphsAPI.clear(graph, message);
     }
 
+    public void update(String graph, String nickname) {
+        this.graphsAPI.update(graph, nickname);
+    }
+
+    // TODO(@Thespica): see org.apache.hugegraph.api.graphs.GraphsAPI.drop
     public void dropGraph(String graph, String message) {
         this.graphsAPI.drop(graph, message);
     }
 
+    public void reload(String graph) {
+        this.graphsAPI.reload(graph);
+    }
+
+    public void reload() {
+        this.graphsAPI.reload();
+    }
+
     public void mode(String graph, GraphMode mode) {
         this.graphsAPI.mode(graph, mode);
     }
@@ -77,4 +126,8 @@ public class GraphsManager {
     public GraphReadMode readMode(String graph) {
         return this.graphsAPI.readMode(graph);
     }
+
+    public String clone(String graph, Map<String, Object> body) {
+        return this.graphsAPI.clone(graph, body);
+    }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/VersionManager.java b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/HStoreManager.java
similarity index 55%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/driver/VersionManager.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/driver/HStoreManager.java
index f5283ca6..3a27af5b 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/VersionManager.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/HStoreManager.java
@@ -17,30 +17,41 @@
 
 package org.apache.hugegraph.driver;
 
-import org.apache.hugegraph.api.version.VersionAPI;
-import org.apache.hugegraph.structure.version.Versions;
+import java.util.List;
+
+import org.apache.hugegraph.api.space.HStoreAPI;
 import org.apache.hugegraph.client.RestClient;
+import org.apache.hugegraph.structure.space.HStoreNodeInfo;
+
+public class HStoreManager {
 
-public class VersionManager {
+    private final HStoreAPI hStoreAPI;
+
+    public HStoreManager(RestClient client) {
+        this.hStoreAPI = new HStoreAPI(client);
+    }
 
-    private VersionAPI versionAPI;
+    public List<String> list() {
+        return hStoreAPI.list();
+    }
+
+    public HStoreNodeInfo get(String id) {
+        return hStoreAPI.get(id);
+    }
 
-    public VersionManager(RestClient client) {
-        this.versionAPI = new VersionAPI(client);
+    public String status() {
+        return hStoreAPI.status();
     }
 
-    public String getCoreVersion() {
-        Versions versions = this.versionAPI.get();
-        return versions.get("core");
+    public void startSplit() {
+        hStoreAPI.startSplit();
     }
 
-    public String getGremlinVersion() {
-        Versions versions = this.versionAPI.get();
-        return versions.get("gremlin");
+    public void nodeStartup(String id) {
+        hStoreAPI.nodeStartup(id);
     }
 
-    public String getApiVersion() {
-        Versions versions = this.versionAPI.get();
-        return versions.get("api");
+    public void nodeShutdown(String id) {
+        hStoreAPI.nodeShutdown(id);
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/HugeClient.java b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/HugeClient.java
index 8a9ef20c..dcb84768 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/HugeClient.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/HugeClient.java
@@ -42,11 +42,10 @@ public class HugeClient implements Closeable {
         ClientVersion.check();
     }
 
-    private final RestClient client;
-    private final boolean borrowedClient;
     protected String graphSpaceName;
     protected String graphName;
-    protected GraphSpaceManager graphSpace;
+    private final boolean borrowedClient;
+    private final RestClient client;
     private VersionManager version;
     private GraphsManager graphs;
     private SchemaManager schema;
@@ -57,8 +56,16 @@ public class HugeClient implements Closeable {
     private VariablesManager variable;
     private JobManager job;
     private TaskManager task;
+    private ComputerManager computer;
     private AuthManager auth;
     private MetricsManager metrics;
+    private GraphSpaceManager graphSpace;
+    private ServiceManager serviceManager;
+    private SchemaTemplateManager schemaTemplageManager;
+    private PDManager pdManager;
+    private HStoreManager hStoreManager;
+    private WhiteIpListManager whiteIpListManager;
+    private VermeerManager vermeerManager;
 
     /**
      * Constructs a new HugeClient using the provided builder.
@@ -139,6 +146,13 @@ public class HugeClient implements Closeable {
         this.auth = new AuthManager(client, graph);
         this.metrics = new MetricsManager(client);
         this.graphSpace = new GraphSpaceManager(client);
+        this.schemaTemplageManager = new SchemaTemplateManager(client, graphSpace);
+        this.serviceManager = new ServiceManager(client, graphSpace);
+        this.pdManager = new PDManager(client);
+        this.hStoreManager = new HStoreManager(client);
+        this.whiteIpListManager = new WhiteIpListManager(client);
+        this.vermeerManager = new VermeerManager(client);
+
         if (!Strings.isNullOrEmpty(graph)) {
             this.schema = new SchemaManager(client, graphSpace, graph);
             this.graph = new GraphManager(client, graphSpace, graph);
@@ -203,6 +217,10 @@ public class HugeClient implements Closeable {
         return this.job;
     }
 
+    public ComputerManager computer() {
+        return this.computer;
+    }
+
     public TaskManager task() {
         return this.task;
     }
@@ -219,6 +237,30 @@ public class HugeClient implements Closeable {
         return this.graphSpace;
     }
 
+    public WhiteIpListManager whiteIpListManager() {
+        return this.whiteIpListManager;
+    }
+
+    public VermeerManager vermeer() {
+        return this.vermeerManager;
+    }
+
+    public SchemaTemplateManager schemaTemplateManager() {
+        return this.schemaTemplageManager;
+    }
+
+    public ServiceManager serviceManager() {
+        return this.serviceManager;
+    }
+
+    public PDManager pdManager() {
+        return pdManager;
+    }
+
+    public HStoreManager hStoreManager() {
+        return hStoreManager;
+    }
+
     public VersionManager versionManager() {
         return version;
     }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/JobManager.java b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/JobManager.java
index ed4c92bd..08073183 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/JobManager.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/JobManager.java
@@ -26,8 +26,8 @@ import org.apache.hugegraph.client.RestClient;
 
 public class JobManager {
 
-    private RebuildAPI rebuildAPI;
-    private TaskAPI taskAPI;
+    private final RebuildAPI rebuildAPI;
+    private final TaskAPI taskAPI;
 
     public JobManager(RestClient client, String graphSpace, String graph) {
         this.rebuildAPI = new RebuildAPI(client, graphSpace, graph);
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/MetricsManager.java b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/MetricsManager.java
index b3ff5c08..defed2ec 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/MetricsManager.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/MetricsManager.java
@@ -24,7 +24,7 @@ import org.apache.hugegraph.client.RestClient;
 
 public class MetricsManager {
 
-    private MetricsAPI metricsAPI;
+    private final MetricsAPI metricsAPI;
 
     public MetricsManager(RestClient client) {
         this.metricsAPI = new MetricsAPI(client);
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/task/TasksWithPage.java b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/PDManager.java
similarity index 68%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/api/task/TasksWithPage.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/driver/PDManager.java
index 44c06311..bfc17279 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/task/TasksWithPage.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/PDManager.java
@@ -15,26 +15,23 @@
  * under the License.
  */
 
-package org.apache.hugegraph.api.task;
+package org.apache.hugegraph.driver;
 
 import java.util.List;
 
-import org.apache.hugegraph.structure.Task;
+import org.apache.hugegraph.api.space.PDAPI;
+import org.apache.hugegraph.client.RestClient;
+import org.apache.hugegraph.structure.space.PDNodeInfo;
 
-import com.fasterxml.jackson.annotation.JsonProperty;
+public class PDManager {
 
-public class TasksWithPage {
+    private final PDAPI pdAPI;
 
-    @JsonProperty
-    private String page;
-    @JsonProperty
-    private List<Task> tasks;
-
-    public String page() {
-        return this.page;
+    public PDManager(RestClient client) {
+        this.pdAPI = new PDAPI(client);
     }
 
-    public List<Task> tasks() {
-        return this.tasks;
+    public List<PDNodeInfo> status() {
+        return this.pdAPI.list();
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/SchemaManager.java b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/SchemaManager.java
index 9a13205f..7c8963c9 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/SchemaManager.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/SchemaManager.java
@@ -36,12 +36,12 @@ import org.apache.hugegraph.structure.schema.VertexLabel;
 
 public class SchemaManager {
 
-    private PropertyKeyAPI propertyKeyAPI;
-    private VertexLabelAPI vertexLabelAPI;
-    private EdgeLabelAPI edgeLabelAPI;
-    private IndexLabelAPI indexLabelAPI;
-    private SchemaAPI schemaAPI;
-    private TaskAPI taskAPI;
+    private final PropertyKeyAPI propertyKeyAPI;
+    private final VertexLabelAPI vertexLabelAPI;
+    private final EdgeLabelAPI edgeLabelAPI;
+    private final IndexLabelAPI indexLabelAPI;
+    private final SchemaAPI schemaAPI;
+    private final TaskAPI taskAPI;
 
     public SchemaManager(RestClient client, String graphSpace, String graph) {
         this.propertyKeyAPI = new PropertyKeyAPI(client, graphSpace, graph);
@@ -58,31 +58,59 @@ public class SchemaManager {
         return proxy.proxy();
     }
 
+    public PropertyKey.Builder propertyKey(Long id, String name) {
+        PropertyKey.Builder builder =
+                new PropertyKey.BuilderImpl(name, this).id(id);
+        BuilderProxy<PropertyKey.Builder> proxy = new BuilderProxy<>(builder);
+        return proxy.proxy();
+    }
+
     public VertexLabel.Builder vertexLabel(String name) {
         VertexLabel.Builder builder = new VertexLabel.BuilderImpl(name, this);
         BuilderProxy<VertexLabel.Builder> proxy = new BuilderProxy<>(builder);
         return proxy.proxy();
     }
 
+    public VertexLabel.Builder vertexLabel(Long id, String name) {
+        VertexLabel.Builder builder =
+                new VertexLabel.BuilderImpl(name, this).id(id);
+        BuilderProxy<VertexLabel.Builder> proxy = new BuilderProxy<>(builder);
+        return proxy.proxy();
+    }
+
     public EdgeLabel.Builder edgeLabel(String name) {
         EdgeLabel.Builder builder = new EdgeLabel.BuilderImpl(name, this);
         BuilderProxy<EdgeLabel.Builder> proxy = new BuilderProxy<>(builder);
         return proxy.proxy();
     }
 
+    public EdgeLabel.Builder edgeLabel(Long id, String name) {
+        EdgeLabel.Builder builder =
+                new EdgeLabel.BuilderImpl(name, this).id(id);
+        BuilderProxy<EdgeLabel.Builder> proxy = new BuilderProxy<>(builder);
+        return proxy.proxy();
+    }
+
     public IndexLabel.Builder indexLabel(String name) {
         IndexLabel.Builder builder = new IndexLabel.BuilderImpl(name, this);
         BuilderProxy<IndexLabel.Builder> proxy = new BuilderProxy<>(builder);
         return proxy.proxy();
     }
 
+    public IndexLabel.Builder indexLabel(Long id, String name) {
+        IndexLabel.Builder builder =
+                new IndexLabel.BuilderImpl(name, this).id(id);
+        BuilderProxy<IndexLabel.Builder> proxy = new BuilderProxy<>(builder);
+        return proxy.proxy();
+    }
+
     public PropertyKey addPropertyKey(PropertyKey propertyKey) {
         return this.addPropertyKey(propertyKey, TaskAPI.TASK_TIMEOUT);
     }
 
     public PropertyKey addPropertyKey(PropertyKey propertyKey, long seconds) {
         PropertyKey.PropertyKeyWithTask task = this.propertyKeyAPI
-                                                   .create(propertyKey);
+                .create(propertyKey);
         if (task.taskId() != 0L) {
             this.taskAPI.waitUntilTaskSuccess(task.taskId(), seconds);
         }
@@ -91,7 +119,7 @@ public class SchemaManager {
 
     public long addPropertyKeyAsync(PropertyKey propertyKey) {
         PropertyKey.PropertyKeyWithTask task = this.propertyKeyAPI
-                                                   .create(propertyKey);
+                .create(propertyKey);
         return task.taskId();
     }
 
@@ -103,13 +131,18 @@ public class SchemaManager {
         return this.propertyKeyAPI.eliminate(propertyKey).propertyKey();
     }
 
+    public PropertyKey updatePropertyKey(String oldPk,
+                                         PropertyKey newPk) {
+        return this.propertyKeyAPI.update(oldPk, newPk);
+    }
+
     public PropertyKey clearPropertyKey(PropertyKey propertyKey) {
         return this.clearPropertyKey(propertyKey, TaskAPI.TASK_TIMEOUT);
     }
 
     public PropertyKey clearPropertyKey(PropertyKey propertyKey, long seconds) {
         PropertyKey.PropertyKeyWithTask task = this.propertyKeyAPI
-                                                   .clear(propertyKey);
+                .clear(propertyKey);
         if (task.taskId() != 0L) {
             this.taskAPI.waitUntilTaskSuccess(task.taskId(), seconds);
         }
@@ -118,7 +151,7 @@ public class SchemaManager {
 
     public long clearPropertyKeyAsync(PropertyKey propertyKey) {
         PropertyKey.PropertyKeyWithTask task = this.propertyKeyAPI
-                                                   .clear(propertyKey);
+                .clear(propertyKey);
         return task.taskId();
     }
 
@@ -228,7 +261,7 @@ public class SchemaManager {
 
     public IndexLabel addIndexLabel(IndexLabel indexLabel, long seconds) {
         IndexLabel.IndexLabelWithTask cil = this.indexLabelAPI
-                                                .create(indexLabel);
+                .create(indexLabel);
         if (cil.taskId() != 0L) {
             this.taskAPI.waitUntilTaskSuccess(cil.taskId(), seconds);
         }
@@ -237,7 +270,7 @@ public class SchemaManager {
 
     public long addIndexLabelAsync(IndexLabel indexLabel) {
         IndexLabel.IndexLabelWithTask cil = this.indexLabelAPI
-                                                .create(indexLabel);
+                .create(indexLabel);
         return cil.taskId();
     }
 
@@ -277,4 +310,12 @@ public class SchemaManager {
     public Map<String, List<SchemaElement>> getSchema() {
         return this.schemaAPI.list();
     }
+
+    public String getGroovySchema() {
+        return this.schemaAPI.listGroovy().getOrDefault("schema", "");
+    }
+
+    public Map<String, Object> getGroovySchema(String format, boolean attachIdFlag) {
+        return this.schemaAPI.listGroovy(format, attachIdFlag);
+    }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/SchemaTemplateManager.java b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/SchemaTemplateManager.java
new file mode 100644
index 00000000..568328f7
--- /dev/null
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/SchemaTemplateManager.java
@@ -0,0 +1,59 @@
+/*
+ * 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.hugegraph.driver;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.hugegraph.api.space.SchemaTemplateAPI;
+import org.apache.hugegraph.client.RestClient;
+import org.apache.hugegraph.structure.space.SchemaTemplate;
+
+public class SchemaTemplateManager {
+
+    private final SchemaTemplateAPI schemaTemplateAPI;
+
+    public SchemaTemplateManager(RestClient client, String graphSpace) {
+        this.schemaTemplateAPI = new SchemaTemplateAPI(client, graphSpace);
+    }
+
+    public List<String> listSchemTemplate() {
+        return this.schemaTemplateAPI.list();
+    }
+
+    public Map getSchemaTemplate(String name) {
+        return this.schemaTemplateAPI.get(name);
+    }
+
+    public Map createSchemaTemplate(SchemaTemplate template) {
+        SchemaTemplate.SchemaTemplateReq req
+                = SchemaTemplate.SchemaTemplateReq.fromBase(template);
+        return this.schemaTemplateAPI.create(req);
+    }
+
+    public Map updateSchemaTemplate(SchemaTemplate template) {
+        SchemaTemplate.SchemaTemplateReq req
+                = SchemaTemplate.SchemaTemplateReq.fromBase(template);
+
+        return this.schemaTemplateAPI.update(req);
+    }
+
+    public void deleteSchemaTemplate(String name) {
+        this.schemaTemplateAPI.delete(name);
+    }
+}
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/ServiceManager.java b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/ServiceManager.java
new file mode 100644
index 00000000..1a998479
--- /dev/null
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/ServiceManager.java
@@ -0,0 +1,108 @@
+/*
+ * 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.hugegraph.driver;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.hugegraph.api.space.ConfigAPI;
+import org.apache.hugegraph.api.space.ServiceAPI;
+import org.apache.hugegraph.client.RestClient;
+import org.apache.hugegraph.structure.space.OLTPService;
+
+public class ServiceManager {
+
+    private final ServiceAPI serviceAPI;
+    private final ConfigAPI configAPI;
+
+    public ServiceManager(RestClient client, String graphSpace) {
+        this.serviceAPI = new ServiceAPI(client, graphSpace);
+        this.configAPI = new ConfigAPI(client, graphSpace);
+    }
+
+    public List<String> listService() {
+        return serviceAPI.list();
+    }
+
+    public OLTPService getService(String name) {
+        OLTPService service = this.serviceAPI.get(name);
+
+        Map<String, Object> config = this.configAPI.get(name);
+        service.setConfigs(config);
+
+        return service;
+    }
+
+    public OLTPService addService(OLTPService service) {
+        // Add service config info
+        this.configAPI.add(service.getName(), service.getConfigs());
+
+        // Start service
+        OLTPService.OLTPServiceReq req
+                = OLTPService.OLTPServiceReq.fromBase(service);
+        this.serviceAPI.add(req);
+
+        return getService(service.getName());
+    }
+
+    public void delService(String name, String message) {
+        this.configAPI.delete(name);
+        this.serviceAPI.delete(name, message);
+    }
+
+    public OLTPService updateService(OLTPService service) {
+        if (service.checkIsK8s()) {
+            // Only update config
+            this.configAPI.update(service.getName(), service.getConfigs());
+            // Delete and recreate service
+            this.delService(service.getName(),
+                            "I'm sure to delete the service");
+            return addService(service);
+        } else {
+            // Manually created service
+            this.delService(service.getName(),
+                            "I'm sure to delete the service");
+            return addService(service);
+        }
+    }
+
+    public void startService(String name) {
+        this.serviceAPI.startService(name);
+    }
+
+    public void stopService(String name) {
+        this.serviceAPI.stopService(name);
+    }
+
+    /**
+     * Check if service modification requires k8s pod restart by comparing
+     *
+     * @param service
+     * @return
+     */
+    public boolean checkIfReloadK8sService(OLTPService service) {
+        OLTPService curService = getService(service.getName());
+        return service.getCount() != curService.getCount() ||
+               service.getCpuLimit() != curService.getCpuLimit() ||
+               service.getMemoryLimit() != curService.getMemoryLimit();
+    }
+
+    public List<String> configOptinList() {
+        return this.configAPI.listConfigOptions();
+    }
+}
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/TaskManager.java b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/TaskManager.java
index e04a6311..b2b4fe96 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/TaskManager.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/TaskManager.java
@@ -26,7 +26,7 @@ import org.apache.hugegraph.structure.Task;
 
 public class TaskManager {
 
-    private TaskAPI taskAPI;
+    private final TaskAPI taskAPI;
 
     public TaskManager(RestClient client, String graphSpace, String graph) {
         this.taskAPI = new TaskAPI(client, graphSpace, graph);
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/TraverserManager.java b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/TraverserManager.java
index 58081342..d6ab963f 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/TraverserManager.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/TraverserManager.java
@@ -19,13 +19,18 @@ package org.apache.hugegraph.driver;
 
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
+import org.apache.hugegraph.api.kvstore.KvStoreAPI;
+import org.apache.hugegraph.api.traverser.AdamicAdarAPI;
 import org.apache.hugegraph.api.traverser.AllShortestPathsAPI;
 import org.apache.hugegraph.api.traverser.CountAPI;
 import org.apache.hugegraph.api.traverser.CrosspointsAPI;
 import org.apache.hugegraph.api.traverser.CustomizedCrosspointsAPI;
 import org.apache.hugegraph.api.traverser.CustomizedPathsAPI;
+import org.apache.hugegraph.api.traverser.EdgeExistenceAPI;
 import org.apache.hugegraph.api.traverser.EdgesAPI;
+import org.apache.hugegraph.api.traverser.EgonetAPI;
 import org.apache.hugegraph.api.traverser.FusiformSimilarityAPI;
 import org.apache.hugegraph.api.traverser.JaccardSimilarityAPI;
 import org.apache.hugegraph.api.traverser.KneighborAPI;
@@ -35,28 +40,32 @@ import org.apache.hugegraph.api.traverser.NeighborRankAPI;
 import org.apache.hugegraph.api.traverser.PathsAPI;
 import org.apache.hugegraph.api.traverser.PersonalRankAPI;
 import org.apache.hugegraph.api.traverser.RaysAPI;
+import org.apache.hugegraph.api.traverser.ResourceAllocationAPI;
 import org.apache.hugegraph.api.traverser.RingsAPI;
 import org.apache.hugegraph.api.traverser.SameNeighborsAPI;
+import org.apache.hugegraph.api.traverser.SameNeighborsBatchAPI;
 import org.apache.hugegraph.api.traverser.ShortestPathAPI;
 import org.apache.hugegraph.api.traverser.SingleSourceShortestPathAPI;
 import org.apache.hugegraph.api.traverser.TemplatePathsAPI;
+import org.apache.hugegraph.api.traverser.VariablesAPI;
 import org.apache.hugegraph.api.traverser.VerticesAPI;
 import org.apache.hugegraph.api.traverser.WeightedShortestPathAPI;
-import org.apache.hugegraph.api.traverser.EdgeExistenceAPI;
 import org.apache.hugegraph.client.RestClient;
 import org.apache.hugegraph.structure.constant.Direction;
 import org.apache.hugegraph.structure.constant.Traverser;
 import org.apache.hugegraph.structure.graph.Edge;
 import org.apache.hugegraph.structure.graph.Edges;
 import org.apache.hugegraph.structure.graph.GraphIterator;
-import org.apache.hugegraph.structure.graph.Path;
 import org.apache.hugegraph.structure.graph.Shard;
 import org.apache.hugegraph.structure.graph.Vertex;
 import org.apache.hugegraph.structure.graph.Vertices;
 import org.apache.hugegraph.structure.traverser.CountRequest;
+import org.apache.hugegraph.structure.traverser.CountResponse;
 import org.apache.hugegraph.structure.traverser.CrosspointsRequest;
 import org.apache.hugegraph.structure.traverser.CustomizedCrosspoints;
 import org.apache.hugegraph.structure.traverser.CustomizedPathsRequest;
+import org.apache.hugegraph.structure.traverser.Egonet;
+import org.apache.hugegraph.structure.traverser.EgonetRequest;
 import org.apache.hugegraph.structure.traverser.FusiformSimilarity;
 import org.apache.hugegraph.structure.traverser.FusiformSimilarityRequest;
 import org.apache.hugegraph.structure.traverser.JaccardSimilarity;
@@ -65,9 +74,15 @@ import org.apache.hugegraph.structure.traverser.KneighborRequest;
 import org.apache.hugegraph.structure.traverser.Kout;
 import org.apache.hugegraph.structure.traverser.KoutRequest;
 import org.apache.hugegraph.structure.traverser.MultiNodeShortestPathRequest;
+import org.apache.hugegraph.structure.traverser.PathOfVertices;
+import org.apache.hugegraph.structure.traverser.PathWithMeasure;
 import org.apache.hugegraph.structure.traverser.PathsRequest;
 import org.apache.hugegraph.structure.traverser.PathsWithVertices;
-import org.apache.hugegraph.structure.traverser.Ranks;
+import org.apache.hugegraph.structure.traverser.Prediction;
+import org.apache.hugegraph.structure.traverser.RanksWithMeasure;
+import org.apache.hugegraph.structure.traverser.SameNeighbors;
+import org.apache.hugegraph.structure.traverser.SameNeighborsBatch;
+import org.apache.hugegraph.structure.traverser.SameNeighborsBatchRequest;
 import org.apache.hugegraph.structure.traverser.SingleSourceJaccardSimilarityRequest;
 import org.apache.hugegraph.structure.traverser.TemplatePathsRequest;
 import org.apache.hugegraph.structure.traverser.WeightedPath;
@@ -95,148 +110,173 @@ public class TraverserManager {
     private final CustomizedCrosspointsAPI customizedCrosspointsAPI;
     private final TemplatePathsAPI templatePathsAPI;
     private final FusiformSimilarityAPI fusiformSimilarityAPI;
+    private final AdamicAdarAPI adamicAdarAPI;
+    private final ResourceAllocationAPI resourceAllocationAPI;
+    private final SameNeighborsBatchAPI sameNeighborsBatchAPI;
+    private final EgonetAPI egonetAPI;
     private final NeighborRankAPI neighborRankAPI;
     private final PersonalRankAPI personalRankAPI;
     private final VerticesAPI verticesAPI;
     private final EdgesAPI edgesAPI;
     private final EdgeExistenceAPI edgeExistenceAPI;
+    private final VariablesAPI variablesAPI;
+    private final KvStoreAPI kvStoreAPI;
 
     public TraverserManager(RestClient client, GraphManager graphManager) {
         this.graphManager = graphManager;
+        String graphSpace = graphManager.graphSpace();
         String graph = graphManager.graph();
-        this.jaccardSimilarityAPI = new JaccardSimilarityAPI(client, graph);
-        this.sameNeighborsAPI = new SameNeighborsAPI(client, graph);
-        this.shortestPathAPI = new ShortestPathAPI(client, graph);
-        this.allShortestPathsAPI = new AllShortestPathsAPI(client, graph);
-        this.singleSourceShortestPathAPI = new SingleSourceShortestPathAPI(client, graph);
-        this.weightedShortestPathAPI = new WeightedShortestPathAPI(client, graph);
-        this.multiNodeShortestPathAPI = new MultiNodeShortestPathAPI(client, graph);
-        this.pathsAPI = new PathsAPI(client, graph);
-        this.crosspointsAPI = new CrosspointsAPI(client, graph);
-        this.koutAPI = new KoutAPI(client, graph);
-        this.kneighborAPI = new KneighborAPI(client, graph);
-        this.countAPI = new CountAPI(client, graph);
-        this.ringsAPI = new RingsAPI(client, graph);
-        this.raysAPI = new RaysAPI(client, graph);
-        this.customizedPathsAPI = new CustomizedPathsAPI(client, graph);
-        this.customizedCrosspointsAPI = new CustomizedCrosspointsAPI(client, graph);
-        this.templatePathsAPI = new TemplatePathsAPI(client, graph);
-        this.fusiformSimilarityAPI = new FusiformSimilarityAPI(client, graph);
-        this.neighborRankAPI = new NeighborRankAPI(client, graph);
-        this.personalRankAPI = new PersonalRankAPI(client, graph);
-        this.verticesAPI = new VerticesAPI(client, graph);
-        this.edgesAPI = new EdgesAPI(client, graph);
-        this.edgeExistenceAPI = new EdgeExistenceAPI(client, graph);
-    }
-
-    public double jaccardSimilarity(Object vertexId, Object otherId) {
+        this.jaccardSimilarityAPI = new JaccardSimilarityAPI(client, graphSpace, graph);
+        this.sameNeighborsAPI = new SameNeighborsAPI(client, graphSpace, graph);
+        this.shortestPathAPI = new ShortestPathAPI(client, graphSpace, graph);
+        this.allShortestPathsAPI = new AllShortestPathsAPI(client, graphSpace, graph);
+        this.singleSourceShortestPathAPI = new SingleSourceShortestPathAPI(
+                client, graphSpace, graph);
+        this.weightedShortestPathAPI = new WeightedShortestPathAPI(
+                client, graphSpace, graph);
+        this.multiNodeShortestPathAPI = new MultiNodeShortestPathAPI(
+                client, graphSpace, graph);
+        this.pathsAPI = new PathsAPI(client, graphSpace, graph);
+        this.crosspointsAPI = new CrosspointsAPI(client, graphSpace, graph);
+        this.koutAPI = new KoutAPI(client, graphSpace, graph);
+        this.kneighborAPI = new KneighborAPI(client, graphSpace, graph);
+        this.countAPI = new CountAPI(client, graphSpace, graph);
+        this.ringsAPI = new RingsAPI(client, graphSpace, graph);
+        this.raysAPI = new RaysAPI(client, graphSpace, graph);
+        this.customizedPathsAPI = new CustomizedPathsAPI(client, graphSpace, graph);
+        this.customizedCrosspointsAPI = new CustomizedCrosspointsAPI(
+                client, graphSpace, graph);
+        this.templatePathsAPI = new TemplatePathsAPI(client, graphSpace, graph);
+        this.fusiformSimilarityAPI = new FusiformSimilarityAPI(client, graphSpace, graph);
+        this.adamicAdarAPI = new AdamicAdarAPI(client, graphSpace, graph);
+        this.resourceAllocationAPI = new ResourceAllocationAPI(client, graphSpace, graph);
+        this.sameNeighborsBatchAPI = new SameNeighborsBatchAPI(client, graphSpace, graph);
+        this.egonetAPI = new EgonetAPI(client, graphSpace, graph);
+        this.neighborRankAPI = new NeighborRankAPI(client, graphSpace, graph);
+        this.personalRankAPI = new PersonalRankAPI(client, graphSpace, graph);
+        this.verticesAPI = new VerticesAPI(client, graphSpace, graph);
+        this.edgesAPI = new EdgesAPI(client, graphSpace, graph);
+        this.edgeExistenceAPI = new EdgeExistenceAPI(client, graphSpace, graph);
+        this.variablesAPI = new VariablesAPI(client, graphSpace, graph);
+        this.kvStoreAPI = new KvStoreAPI(client);
+    }
+
+    public JaccardSimilarity jaccardSimilarity(Object vertexId, Object otherId) {
         return this.jaccardSimilarity(vertexId, otherId, Traverser.DEFAULT_MAX_DEGREE);
     }
 
-    public double jaccardSimilarity(Object vertexId, Object otherId,
-                                    long degree) {
+    public JaccardSimilarity jaccardSimilarity(Object vertexId, Object otherId,
+                                               long degree) {
         return this.jaccardSimilarity(vertexId, otherId, Direction.BOTH,
                                       null, degree);
     }
 
-    public double jaccardSimilarity(Object vertexId, Object otherId,
-                                    Direction direction, String label,
-                                    long degree) {
+    public JaccardSimilarity jaccardSimilarity(Object vertexId, Object otherId,
+                                               Direction direction, String label,
+                                               long degree) {
         return this.jaccardSimilarityAPI.get(vertexId, otherId, direction,
                                              label, degree);
     }
 
-    public JaccardSimilarity jaccardSimilarity(SingleSourceJaccardSimilarityRequest request) {
+    public JaccardSimilarity jaccardSimilarity(
+            SingleSourceJaccardSimilarityRequest request) {
         return this.jaccardSimilarityAPI.post(request);
     }
 
-    public List<Object> sameNeighbors(Object vertexId, Object otherId) {
+    public SameNeighbors sameNeighbors(Object vertexId, Object otherId) {
         return this.sameNeighbors(vertexId, otherId, Traverser.DEFAULT_MAX_DEGREE);
     }
 
-    public List<Object> sameNeighbors(Object vertexId, Object otherId,
-                                      long degree) {
+    public SameNeighbors sameNeighbors(Object vertexId, Object otherId,
+                                       long degree) {
         return this.sameNeighbors(vertexId, otherId, Direction.BOTH,
                                   null, degree);
     }
 
-    public List<Object> sameNeighbors(Object vertexId, Object otherId,
-                                      Direction direction, String label,
-                                      long degree) {
+    public SameNeighbors sameNeighbors(Object vertexId, Object otherId,
+                                       Direction direction, String label,
+                                       long degree) {
         return this.sameNeighbors(vertexId, otherId, direction, label,
                                   degree, Traverser.DEFAULT_PATHS_LIMIT);
     }
 
-    public List<Object> sameNeighbors(Object vertexId, Object otherId,
-                                      Direction direction, String label,
-                                      long degree, int limit) {
+    public SameNeighbors sameNeighbors(Object vertexId, Object otherId,
+                                       Direction direction, String label,
+                                       long degree, long limit) {
         return this.sameNeighborsAPI.get(vertexId, otherId, direction,
                                          label, degree, limit);
     }
 
-    public Path shortestPath(Object sourceId, Object targetId, int maxDepth) {
+    public SameNeighborsBatch sameNeighbors(SameNeighborsBatchRequest request) {
+        return this.sameNeighborsBatchAPI.post(request);
+    }
+
+    public PathOfVertices shortestPath(Object sourceId, Object targetId,
+                                       int maxDepth) {
         return this.shortestPath(sourceId, targetId, Direction.BOTH, null,
                                  maxDepth);
     }
 
-    public Path shortestPath(Object sourceId, Object targetId,
-                             Direction direction, int maxDepth) {
+    public PathOfVertices shortestPath(Object sourceId, Object targetId,
+                                       Direction direction, int maxDepth) {
         return this.shortestPath(sourceId, targetId, direction, null,
                                  maxDepth);
     }
 
-    public Path shortestPath(Object sourceId, Object targetId,
-                             Direction direction, String label, int maxDepth) {
+    public PathOfVertices shortestPath(Object sourceId, Object targetId,
+                                       Direction direction, String label,
+                                       int maxDepth) {
         return this.shortestPath(sourceId, targetId, direction, label, maxDepth,
                                  Traverser.DEFAULT_MAX_DEGREE, Traverser.DEFAULT_CAPACITY);
     }
 
-    public Path shortestPath(Object sourceId, Object targetId,
-                             Direction direction, String label, int maxDepth,
-                             long degree, long capacity) {
+    public PathOfVertices shortestPath(Object sourceId, Object targetId,
+                                       Direction direction, String label,
+                                       int maxDepth, long degree, long capacity) {
         return this.shortestPath(sourceId, targetId, direction, label,
                                  maxDepth, degree, 0L, capacity);
     }
 
-    public Path shortestPath(Object sourceId, Object targetId,
-                             Direction direction, String label, int maxDepth,
-                             long degree, long skipDegree, long capacity) {
+    public PathOfVertices shortestPath(Object sourceId, Object targetId,
+                                       Direction direction, String label,
+                                       int maxDepth, long degree, long skipDegree,
+                                       long capacity) {
         return this.shortestPathAPI.get(sourceId, targetId, direction, label,
                                         maxDepth, degree, skipDegree, capacity);
     }
 
-    public List<Path> allShortestPaths(Object sourceId, Object targetId,
-                                       int maxDepth) {
+    public PathWithMeasure allShortestPaths(Object sourceId, Object targetId,
+                                            int maxDepth) {
         return this.allShortestPaths(sourceId, targetId, Direction.BOTH,
                                      null, maxDepth);
     }
 
-    public List<Path> allShortestPaths(Object sourceId, Object targetId,
-                                       Direction direction, int maxDepth) {
+    public PathWithMeasure allShortestPaths(Object sourceId, Object targetId,
+                                            Direction direction, int maxDepth) {
         return this.allShortestPaths(sourceId, targetId, direction,
                                      null, maxDepth);
     }
 
-    public List<Path> allShortestPaths(Object sourceId, Object targetId,
-                                       Direction direction, String label,
-                                       int maxDepth) {
+    public PathWithMeasure allShortestPaths(Object sourceId, Object targetId,
+                                            Direction direction, String label,
+                                            int maxDepth) {
         return this.allShortestPaths(sourceId, targetId, direction,
                                      label, maxDepth, Traverser.DEFAULT_MAX_DEGREE,
                                      Traverser.DEFAULT_CAPACITY);
     }
 
-    public List<Path> allShortestPaths(Object sourceId, Object targetId,
-                                       Direction direction, String label,
-                                       int maxDepth, long degree,
-                                       long capacity) {
+    public PathWithMeasure allShortestPaths(Object sourceId, Object targetId,
+                                            Direction direction, String label,
+                                            int maxDepth, long degree,
+                                            long capacity) {
         return this.allShortestPaths(sourceId, targetId, direction, label,
                                      maxDepth, degree, 0L, capacity);
     }
 
-    public List<Path> allShortestPaths(Object sourceId, Object targetId,
-                                       Direction direction, String label,
-                                       int maxDepth, long degree,
-                                       long skipDegree, long capacity) {
+    public PathWithMeasure allShortestPaths(Object sourceId, Object targetId,
+                                            Direction direction, String label,
+                                            int maxDepth, long degree,
+                                            long skipDegree, long capacity) {
         return this.allShortestPathsAPI.get(sourceId, targetId, direction,
                                             label, maxDepth, degree,
                                             skipDegree, capacity);
@@ -244,8 +284,7 @@ public class TraverserManager {
 
     public WeightedPaths singleSourceShortestPath(Object sourceId,
                                                   String weight,
-                                                  boolean withVertex,
-                                                  boolean withEdge) {
+                                                  boolean withVertex, boolean withEdge) {
         return this.singleSourceShortestPath(sourceId, Direction.BOTH, null,
                                              weight, withVertex, withEdge);
     }
@@ -264,7 +303,7 @@ public class TraverserManager {
                                                   Direction direction,
                                                   String label, String weight,
                                                   long degree, long skipDegree,
-                                                  long capacity, int limit,
+                                                  long capacity, long limit,
                                                   boolean withVertex, boolean withEdge) {
         return this.singleSourceShortestPathAPI.get(sourceId, direction, label,
                                                     weight, degree, skipDegree,
@@ -281,8 +320,7 @@ public class TraverserManager {
     public WeightedPath weightedShortestPath(Object sourceId, Object targetId,
                                              Direction direction, String label,
                                              String weight,
-                                             boolean withVertex,
-                                             boolean withEdge) {
+                                             boolean withVertex, boolean withEdge) {
         return this.weightedShortestPath(sourceId, targetId, direction, label,
                                          weight, Traverser.DEFAULT_MAX_DEGREE, 0L,
                                          Traverser.DEFAULT_CAPACITY, withVertex, withEdge);
@@ -293,35 +331,41 @@ public class TraverserManager {
                                              String label, String weight,
                                              long degree, long skipDegree,
                                              long capacity, boolean withVertex, boolean withEdge) {
-        return this.weightedShortestPathAPI.get(sourceId, targetId, direction, label, weight,
-                                                degree, skipDegree, capacity, withVertex, withEdge);
+        return this.weightedShortestPathAPI.get(sourceId, targetId, direction,
+                                                label, weight, degree,
+                                                skipDegree, capacity,
+                                                withVertex, withEdge);
     }
 
-    public PathsWithVertices multiNodeShortestPath(MultiNodeShortestPathRequest request) {
+    public PathsWithVertices multiNodeShortestPath(
+            MultiNodeShortestPathRequest request) {
         return this.multiNodeShortestPathAPI.post(request);
     }
 
-    public List<Path> paths(Object sourceId, Object targetId, int maxDepth) {
+    public PathWithMeasure paths(Object sourceId, Object targetId,
+                                 int maxDepth) {
         return this.paths(sourceId, targetId, Direction.BOTH, null,
                           maxDepth, Traverser.DEFAULT_PATHS_LIMIT);
     }
 
-    public List<Path> paths(Object sourceId, Object targetId,
-                            Direction direction, int maxDepth, int limit) {
+    public PathWithMeasure paths(Object sourceId, Object targetId,
+                                 Direction direction, int maxDepth,
+                                 long limit) {
         return this.paths(sourceId, targetId, direction, null,
                           maxDepth, limit);
     }
 
-    public List<Path> paths(Object sourceId, Object targetId,
-                            Direction direction, String label,
-                            int maxDepth, int limit) {
+    public PathWithMeasure paths(Object sourceId, Object targetId,
+                                 Direction direction, String label,
+                                 int maxDepth, long limit) {
         return this.paths(sourceId, targetId, direction, label, maxDepth,
                           Traverser.DEFAULT_MAX_DEGREE, Traverser.DEFAULT_CAPACITY, limit);
     }
 
-    public List<Path> paths(Object sourceId, Object targetId,
-                            Direction direction, String label, int maxDepth,
-                            long degree, long capacity, int limit) {
+    public PathWithMeasure paths(Object sourceId, Object targetId,
+                                 Direction direction, String label,
+                                 int maxDepth, long degree, long capacity,
+                                 long limit) {
         return this.pathsAPI.get(sourceId, targetId, direction, label,
                                  maxDepth, degree, capacity, limit);
     }
@@ -330,52 +374,53 @@ public class TraverserManager {
         return this.pathsAPI.post(request);
     }
 
-    public List<Path> crosspoint(Object sourceId, Object targetId,
-                                 int maxDepth) {
+    public PathWithMeasure crosspoint(Object sourceId, Object targetId,
+                                      int maxDepth) {
         return this.crosspoint(sourceId, targetId, Direction.BOTH, null,
                                maxDepth, Traverser.DEFAULT_PATHS_LIMIT);
     }
 
-    public List<Path> crosspoint(Object sourceId, Object targetId,
-                                 Direction direction, int maxDepth,
-                                 int limit) {
+    public PathWithMeasure crosspoint(Object sourceId, Object targetId,
+                                      Direction direction, int maxDepth,
+                                      long limit) {
         return this.crosspoint(sourceId, targetId, direction, null,
                                maxDepth, limit);
     }
 
-    public List<Path> crosspoint(Object sourceId, Object targetId,
-                                 Direction direction, String label,
-                                 int maxDepth, int limit) {
+    public PathWithMeasure crosspoint(Object sourceId, Object targetId,
+                                      Direction direction, String label,
+                                      int maxDepth, long limit) {
         return this.crosspoint(sourceId, targetId, direction, label, maxDepth,
                                Traverser.DEFAULT_MAX_DEGREE, Traverser.DEFAULT_CAPACITY, limit);
     }
 
-    public List<Path> crosspoint(Object sourceId, Object targetId,
-                                 Direction direction, String label,
-                                 int maxDepth, long degree, long capacity,
-                                 int limit) {
+    public PathWithMeasure crosspoint(Object sourceId, Object targetId,
+                                      Direction direction, String label,
+                                      int maxDepth, long degree, long capacity,
+                                      long limit) {
         return this.crosspointsAPI.get(sourceId, targetId, direction, label,
                                        maxDepth, degree, capacity, limit);
     }
 
-    public List<Object> kout(Object sourceId, int depth) {
+    public Map<String, Object> kout(Object sourceId, int depth) {
         return this.kout(sourceId, Direction.BOTH, depth);
     }
 
-    public List<Object> kout(Object sourceId, Direction direction, int depth) {
+    public Map<String, Object> kout(Object sourceId, Direction direction,
+                                    int depth) {
         return this.kout(sourceId, direction, null, depth, true);
     }
 
-    public List<Object> kout(Object sourceId, Direction direction,
-                             String label, int depth, boolean nearest) {
+    public Map<String, Object> kout(Object sourceId, Direction direction,
+                                    String label, int depth, boolean nearest) {
         return this.kout(sourceId, direction, label, depth, nearest,
                          Traverser.DEFAULT_MAX_DEGREE, Traverser.DEFAULT_CAPACITY,
                          Traverser.DEFAULT_ELEMENTS_LIMIT);
     }
 
-    public List<Object> kout(Object sourceId, Direction direction,
-                             String label, int depth, boolean nearest,
-                             long degree, long capacity, int limit) {
+    public Map<String, Object> kout(Object sourceId, Direction direction,
+                                    String label, int depth, boolean nearest,
+                                    long degree, long capacity, long limit) {
         return this.koutAPI.get(sourceId, direction, label, depth, nearest,
                                 degree, capacity, limit);
     }
@@ -384,24 +429,24 @@ public class TraverserManager {
         return this.koutAPI.post(request);
     }
 
-    public List<Object> kneighbor(Object sourceId, int depth) {
+    public Map<String, Object> kneighbor(Object sourceId, int depth) {
         return this.kneighbor(sourceId, Direction.BOTH, null, depth);
     }
 
-    public List<Object> kneighbor(Object sourceId, Direction direction,
-                                  int depth) {
+    public Map<String, Object> kneighbor(Object sourceId, Direction direction,
+                                         int depth) {
         return this.kneighbor(sourceId, direction, null, depth);
     }
 
-    public List<Object> kneighbor(Object sourceId, Direction direction,
-                                  String label, int depth) {
+    public Map<String, Object> kneighbor(Object sourceId, Direction direction,
+                                         String label, int depth) {
         return this.kneighbor(sourceId, direction, label, depth,
                               Traverser.DEFAULT_MAX_DEGREE, Traverser.DEFAULT_ELEMENTS_LIMIT);
     }
 
-    public List<Object> kneighbor(Object sourceId, Direction direction,
-                                  String label, int depth,
-                                  long degree, int limit) {
+    public Map<String, Object> kneighbor(Object sourceId, Direction direction,
+                                         String label, int depth,
+                                         long degree, long limit) {
         return this.kneighborAPI.get(sourceId, direction, label, depth,
                                      degree, limit);
     }
@@ -410,31 +455,31 @@ public class TraverserManager {
         return this.kneighborAPI.post(request);
     }
 
-    public long count(CountRequest request) {
+    public CountResponse count(CountRequest request) {
         return this.countAPI.post(request);
     }
 
-    public List<Path> rings(Object sourceId, int depth) {
+    public PathWithMeasure rings(Object sourceId, int depth) {
         return this.rings(sourceId, Direction.BOTH, null, depth, true,
                           Traverser.DEFAULT_MAX_DEGREE, Traverser.DEFAULT_CAPACITY,
                           Traverser.DEFAULT_ELEMENTS_LIMIT);
     }
 
-    public List<Path> rings(Object sourceId, Direction direction, String label,
-                            int depth, boolean sourceInRing, long degree,
-                            long capacity, int limit) {
+    public PathWithMeasure rings(Object sourceId, Direction direction, String label,
+                                 int depth, boolean sourceInRing, long degree,
+                                 long capacity, long limit) {
         return this.ringsAPI.get(sourceId, direction, label, depth,
                                  sourceInRing, degree, capacity, limit);
     }
 
-    public List<Path> rays(Object sourceId, int depth) {
+    public PathWithMeasure rays(Object sourceId, int depth) {
         return this.rays(sourceId, Direction.BOTH, null, depth,
                          Traverser.DEFAULT_MAX_DEGREE, Traverser.DEFAULT_CAPACITY,
                          Traverser.DEFAULT_ELEMENTS_LIMIT);
     }
 
-    public List<Path> rays(Object sourceId, Direction direction, String label,
-                           int depth, long degree, long capacity, int limit) {
+    public PathWithMeasure rays(Object sourceId, Direction direction, String label,
+                                int depth, long degree, long capacity, long limit) {
         return this.raysAPI.get(sourceId, direction, label, depth, degree,
                                 capacity, limit);
     }
@@ -455,11 +500,28 @@ public class TraverserManager {
         return this.fusiformSimilarityAPI.post(request);
     }
 
-    public List<Ranks> neighborRank(NeighborRankAPI.Request request) {
+    public Prediction adamicadar(Object vertexId, Object otherId,
+                                 Direction direction, String label, long degree) {
+        return this.adamicAdarAPI.get(vertexId, otherId, direction,
+                                      label, degree);
+    }
+
+    public Prediction resourceAllocation(Object vertexId, Object otherId,
+                                         Direction direction, String label,
+                                         long degree) {
+        return this.resourceAllocationAPI.get(vertexId, otherId, direction,
+                                              label, degree);
+    }
+
+    public Egonet egonet(EgonetRequest request) {
+        return this.egonetAPI.post(request);
+    }
+
+    public RanksWithMeasure neighborRank(NeighborRankAPI.Request request) {
         return this.neighborRankAPI.post(request);
     }
 
-    public Ranks personalRank(PersonalRankAPI.Request request) {
+    public RanksWithMeasure personalRank(PersonalRankAPI.Request request) {
         return this.personalRankAPI.post(request);
     }
 
@@ -471,6 +533,14 @@ public class TraverserManager {
         return this.edgesAPI.shards(splitSize);
     }
 
+    public List<Shard> variablesShards(long splitSize) {
+        return this.variablesAPI.shards(splitSize);
+    }
+
+    public List<Shard> kvStoreShards(long splitSize) {
+        return this.kvStoreAPI.shards(splitSize);
+    }
+
     public List<Vertex> vertices(List<Object> ids) {
         List<Vertex> vertices = this.verticesAPI.list(ids);
         for (Vertex vertex : vertices) {
@@ -502,6 +572,40 @@ public class TraverserManager {
         return vertices;
     }
 
+    public Vertices variables(Shard shard) {
+        Vertices vertices = this.variables(shard, null, 0L);
+        E.checkState(vertices.page() == null,
+                     "Can't contains page when not in paging");
+        return vertices;
+    }
+
+    public Vertices variables(Shard shard, String page) {
+        E.checkArgument(page != null, "Page can't be null");
+        return this.variables(shard, page, Traverser.DEFAULT_PAGE_LIMIT);
+    }
+
+    public Vertices variables(Shard shard, String page, long pageLimit) {
+        E.checkArgument(page == null || pageLimit >= 0,
+                        "Page limit must be >= 0 when page is not null");
+        Vertices vertices = this.variablesAPI.scan(shard, page, pageLimit);
+
+        for (Vertex vertex : vertices.results()) {
+            vertex.attachManager(this.graphManager);
+        }
+        return vertices;
+    }
+
+    public Vertices kvStores(Shard shard, String page, long pageLimit) {
+        E.checkArgument(page == null || pageLimit >= 0,
+                        "Page limit must be >= 0 when page is not null");
+        Vertices vertices = this.kvStoreAPI.scan(shard, page, pageLimit);
+
+        for (Vertex vertex : vertices.results()) {
+            vertex.attachManager(this.graphManager);
+        }
+        return vertices;
+    }
+
     public Iterator<Vertex> iteratorVertices(Shard shard, int sizePerPage) {
         return new GraphIterator<>(this.graphManager, sizePerPage, (page) -> {
             return this.vertices(shard, page, sizePerPage);
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/VermeerManager.java b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/VermeerManager.java
new file mode 100644
index 00000000..753c398e
--- /dev/null
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/VermeerManager.java
@@ -0,0 +1,61 @@
+/*
+ * 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.hugegraph.driver;
+
+import java.util.Map;
+
+import org.apache.hugegraph.client.RestClient;
+import org.apache.hugegraph.api.vermeer.VermeerAPI;
+
+public class VermeerManager {
+
+    private final VermeerAPI vermeerAPI;
+
+    public VermeerManager(RestClient client) {
+        this.vermeerAPI = new VermeerAPI(client);
+    }
+
+    public Map<String, Object> getStatus() {
+        return this.vermeerAPI.getStatus();
+    }
+
+    public Map<String, Object> post(Map<String, Object> params) {
+        return this.vermeerAPI.post(params);
+    }
+
+    public Map<String, Object> getGraphsInfo() {
+        return this.vermeerAPI.getGraphsInfo();
+    }
+
+    public Map<String, Object> getGraphInfoByName(String graphName) {
+        return this.vermeerAPI.getGraphInfoByName(graphName);
+    }
+
+    public Map<String, Object> deleteGraphByName(String graphName) {
+        return this.vermeerAPI.deleteGraphByName(graphName);
+    }
+
+    public Map<String, Object> getTasksInfo() {
+        return this.vermeerAPI.getTasksInfo();
+    }
+
+    public Map<String, Object> getTasksInfoById(String taskId) {
+        return this.vermeerAPI.getTasksInfoById(taskId);
+    }
+
+}
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/VersionManager.java b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/VersionManager.java
index f5283ca6..7ba76718 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/VersionManager.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/VersionManager.java
@@ -23,7 +23,7 @@ import org.apache.hugegraph.client.RestClient;
 
 public class VersionManager {
 
-    private VersionAPI versionAPI;
+    private final VersionAPI versionAPI;
 
     public VersionManager(RestClient client) {
         this.versionAPI = new VersionAPI(client);
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/VersionManager.java b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/WhiteIpListManager.java
similarity index 58%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/driver/VersionManager.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/driver/WhiteIpListManager.java
index f5283ca6..9b1408eb 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/VersionManager.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/WhiteIpListManager.java
@@ -17,30 +17,29 @@
 
 package org.apache.hugegraph.driver;
 
-import org.apache.hugegraph.api.version.VersionAPI;
-import org.apache.hugegraph.structure.version.Versions;
 import org.apache.hugegraph.client.RestClient;
+import org.apache.hugegraph.api.ip.WhiteIpListAPI;
 
-public class VersionManager {
+import java.util.Map;
 
-    private VersionAPI versionAPI;
+public class WhiteIpListManager {
 
-    public VersionManager(RestClient client) {
-        this.versionAPI = new VersionAPI(client);
+    private final WhiteIpListAPI whiteIpListAPI;
+
+    public WhiteIpListManager(RestClient client) {
+        this.whiteIpListAPI = new WhiteIpListAPI(client);
     }
 
-    public String getCoreVersion() {
-        Versions versions = this.versionAPI.get();
-        return versions.get("core");
+    public Map<String, Object> list() {
+        return this.whiteIpListAPI.list();
     }
 
-    public String getGremlinVersion() {
-        Versions versions = this.versionAPI.get();
-        return versions.get("gremlin");
+    public Map<String, Object> batch(Map<String, Object> action) {
+        return this.whiteIpListAPI.batch(action);
     }
 
-    public String getApiVersion() {
-        Versions versions = this.versionAPI.get();
-        return versions.get("api");
+    public Map<String, Object> update(boolean status) {
+        return this.whiteIpListAPI.update(status);
     }
+
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/factory/PDHugeClientFactory.java b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/factory/PDHugeClientFactory.java
new file mode 100644
index 00000000..9f9c21f7
--- /dev/null
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/factory/PDHugeClientFactory.java
@@ -0,0 +1,227 @@
+/*
+ * 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.hugegraph.driver.factory;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.hugegraph.util.E;
+import org.apache.hugegraph.util.Log;
+import org.slf4j.Logger;
+
+import org.apache.hugegraph.driver.HugeClient;
+import org.apache.hugegraph.pd.client.DiscoveryClient;
+import org.apache.hugegraph.pd.client.DiscoveryClientImpl;
+import org.apache.hugegraph.pd.client.PDConfig;
+import org.apache.hugegraph.pd.grpc.discovery.NodeInfos;
+import org.apache.hugegraph.pd.grpc.discovery.Query;
+import com.google.common.collect.ImmutableMap;
+
+import lombok.SneakyThrows;
+
+public class PDHugeClientFactory {
+
+    private static final Logger LOG = Log.logger(PDHugeClientFactory.class);
+
+    public static final String DEFAULT_GRAPHSPACE = "DEFAULT";
+    public static final String DEFAULT_SERVICE = "DEFAULT";
+    public static final String NAME = "hg";
+    public static final String TOKEN =
+            "$2a$04$i10KooNg6wLvIPVDh909n.RBYlZ/4pJo978nFK86nrqQiGIKV4UGS";
+
+    protected static final String SERVICE_VERSION = "1.0.0";
+    protected final String pdAddrs;
+    protected final RouteType type;
+    protected final DiscoveryClient client;
+
+    public PDHugeClientFactory(String pdAddrs) {
+        this(pdAddrs, null);
+    }
+
+    @SneakyThrows
+    public PDHugeClientFactory(String pdAddrs, String type) {
+        this.pdAddrs = pdAddrs;
+        this.type = type != null ? RouteType.valueOf(type) : RouteType.BOTH;
+
+        PDConfig pdConfig = PDConfig.of(pdAddrs);
+        // TODO: Not suport now: pdConfig.setAuthority(NAME, TOKEN);
+        this.client = DiscoveryClientImpl.newBuilder()
+                                                    // TODO: Not suport now: .setPdConfig(pdConfig)
+                                                    .setCenterAddress(pdAddrs)
+                                                    .build();
+    }
+
+    public HugeClient createUnauthClient(String cluster, String graphSpace,
+                                         String graph) {
+        E.checkArgument(cluster != null,
+                        "create unauth client: cluster must not null");
+
+        return createUnauthClient(cluster, graphSpace, graph, 60);
+    }
+
+    public HugeClient createUnauthClient(String cluster, String graphSpace,
+                                         String graph, int timeout) {
+        E.checkArgument(cluster != null,
+                        "create unauth client: cluster must not null");
+
+        return createClient(cluster, graphSpace, graph, null, null, null,
+                            timeout);
+    }
+
+    public HugeClient createAuthClient(String cluster, String graphSpace,
+                                       String graph, String token,
+                                       String username, String password) {
+
+        return createAuthClient(cluster, graphSpace, graph, token, username,
+                                password, 60);
+    }
+
+    public HugeClient createAuthClient(String cluster, String graphSpace,
+                                       String graph, String token,
+                                       String username, String password,
+                                       int timeout) {
+        E.checkArgument(cluster != null,
+                        "create auth client: cluster must not null");
+
+        E.checkArgument(token != null || (username != null && password != null),
+                        "create auth client: token must not null or " +
+                                "username/password must not null");
+
+        return createClient(cluster, graphSpace, graph, token, username,
+                            password, timeout);
+    }
+
+    protected HugeClient createClient(String cluster, String graphSpace,
+                                      String graph, String token,
+                                      String username, String password,
+                                      int timeout) {
+
+        List<String> urls = getAutoURLs(cluster, graphSpace, graph);
+
+        DefaultHugeClientFactory defaultFactory =
+                new DefaultHugeClientFactory(urls.toArray(new String[0]));
+
+        int r = (int) Math.floor(Math.random() * urls.size());
+        String address = urls.get(r);
+        if (!address.startsWith("http")) {
+            address = "http://" + address;
+        }
+
+        HugeClient client = HugeClient.builder(address, graphSpace, graph)
+                                      .configToken(token)
+                                      .configUser(username, password)
+                                      .configTimeout(timeout)
+                                      .build();
+        return client;
+    }
+
+    public List<String> getAutoURLs(String cluster, String graphSpace,
+                                    String service) {
+        // if no urls under graphspace/service
+        // use DEFAULT/DEFAULT
+
+        List<String> urls = null;
+        if (StringUtils.isNotEmpty(graphSpace)) {
+            if (StringUtils.isNotEmpty(service)) {
+                // Get urls From service
+                urls = getURLs(cluster, graphSpace, service);
+            }
+
+            if (CollectionUtils.isNotEmpty(urls)) {
+                return urls;
+            }
+
+            // Get Url from graphspace
+            urls = getURLs(cluster, graphSpace, null);
+            if (CollectionUtils.isNotEmpty(urls)) {
+                return urls;
+            }
+        }
+
+        urls = getURLs(cluster, DEFAULT_GRAPHSPACE, DEFAULT_SERVICE);
+
+        return urls;
+    }
+
+
+    public List<String> getURLs(String cluster, String graphSpace,
+                                String service) {
+
+        E.checkArgument(StringUtils.isNotEmpty(graphSpace), "list urls" +
+                " error, cluster must not null");
+
+        Map<String, String>  configs = new HashMap<>();
+        if (StringUtils.isNotEmpty(graphSpace)) {
+            configs.put("GRAPHSPACE", graphSpace);
+        }
+        if (StringUtils.isNotEmpty(service)) {
+            configs.put("SERVICE_NAME", service);
+        }
+
+        if (!RouteType.BOTH.equals(this.type)) {
+            configs.put("REGISTER_TYPE", this.type.name());
+        }
+
+        Query query = Query.newBuilder().setAppName(cluster)
+                           .putAllLabels(configs)
+                           .build();
+
+        NodeInfos nodeInfos = client.getNodeInfos(query);
+
+
+        List<String> urls = nodeInfos.getInfoList().stream()
+                                     .map(nodeInfo -> nodeInfo.getAddress())
+                                     .collect(Collectors.toList());
+
+        return urls;
+    }
+
+    protected List<String> getURLsWithConfig(String cluster,
+                                             Map<String, String> configs) {
+
+        if (null == configs) {
+            configs = ImmutableMap.of();
+        }
+        Query query = Query.newBuilder().setAppName(cluster)
+                           .setVersion(SERVICE_VERSION)
+                           .putAllLabels(configs)
+                           .build();
+
+        NodeInfos nodeInfos = client.getNodeInfos(query);
+
+        List<String> urls = nodeInfos.getInfoList().stream()
+                                     .map(nodeInfo -> nodeInfo.getAddress())
+                                     .collect(Collectors.toList());
+
+        return urls;
+    }
+
+    public void close() {
+        this.client.close();
+    }
+
+    public enum RouteType {
+        BOTH,
+        NODE_PORT,
+        DDS
+    }
+}
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/exception/NotAllCreatedException.java b/hugegraph-client/src/main/java/org/apache/hugegraph/exception/NotAllCreatedException.java
index bbacb5af..e37892f8 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/exception/NotAllCreatedException.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/exception/NotAllCreatedException.java
@@ -23,7 +23,7 @@ public class NotAllCreatedException extends ServerException {
 
     private static final long serialVersionUID = -8795820552805040556L;
 
-    private Collection<?> ids;
+    private final Collection<?> ids;
 
     public NotAllCreatedException(String message, Collection<?> ids,
                                   Object... args) {
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/serializer/direct/HBaseSerializer.java b/hugegraph-client/src/main/java/org/apache/hugegraph/serializer/direct/HBaseSerializer.java
index 18cb87af..c963dfce 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/serializer/direct/HBaseSerializer.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/serializer/direct/HBaseSerializer.java
@@ -35,10 +35,10 @@ import org.apache.hugegraph.structure.schema.PropertyKey;
  */
 public class HBaseSerializer {
 
-    private int edgeLogicPartitions;
-    private int vertexLogicPartitions;
-    private HugeClient client;
-    private GraphSchema graphSchema;
+    private final int edgeLogicPartitions;
+    private final int vertexLogicPartitions;
+    private final HugeClient client;
+    private final GraphSchema graphSchema;
 
     public HBaseSerializer(HugeClient client, int vertexPartitions, int edgePartitions) {
         this.client = client;
@@ -51,16 +51,17 @@ public class HBaseSerializer {
         byte[] array = null;
         if (e.type() == "vertex" && e.id() != null) {
             BytesBuffer buffer = BytesBuffer.allocate(2 + 1 + e.id().toString().length());
-            buffer.writeShort(getPartition(HugeType.VERTEX,  IdGenerator.of(e.id())));
+            buffer.writeShort(getPartition(HugeType.VERTEX, IdGenerator.of(e.id())));
             buffer.writeId(IdGenerator.of(e.id()));
             array = buffer.bytes();
         } else if (e.type() == "edge") {
             BytesBuffer buffer = BytesBuffer.allocate(BytesBuffer.BUF_EDGE_ID);
-            Edge edge = (Edge)e;
+            Edge edge = (Edge) e;
             buffer.writeShort(getPartition(HugeType.EDGE, IdGenerator.of(edge.sourceId())));
             buffer.writeId(IdGenerator.of(edge.sourceId()));
             buffer.write(HugeType.EDGE_OUT.code());
-            buffer.writeId(IdGenerator.of(graphSchema.getEdgeLabel(e.label()).id())); //出现错误
+            buffer.writeId(
+                    IdGenerator.of(graphSchema.getEdgeLabel(e.label()).id())); // Error occurred
             buffer.writeStringWithEnding("");
             buffer.writeId(IdGenerator.of(edge.targetId()));
             array = buffer.bytes();
@@ -78,17 +79,17 @@ public class HBaseSerializer {
             for (Map.Entry<String, Object> entry : e.properties().entrySet()) {
                 PropertyKey propertyKey = graphSchema.getPropertyKey(entry.getKey());
                 buffer.writeVInt(propertyKey.id().intValue());
-                buffer.writeProperty(propertyKey.dataType(),entry.getValue());
+                buffer.writeProperty(propertyKey.dataType(), entry.getValue());
             }
             array = buffer.bytes();
         } else if (e.type() == "edge") {
-            int propsCount =  e.properties().size();
+            int propsCount = e.properties().size();
             BytesBuffer buffer = BytesBuffer.allocate(4 + 16 * propsCount);
             buffer.writeVInt(propsCount);
             for (Map.Entry<String, Object> entry : e.properties().entrySet()) {
                 PropertyKey propertyKey = graphSchema.getPropertyKey(entry.getKey());
                 buffer.writeVInt(propertyKey.id().intValue());
-                buffer.writeProperty(propertyKey.dataType(),entry.getValue());
+                buffer.writeProperty(propertyKey.dataType(), entry.getValue());
             }
             array = buffer.bytes();
         }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/serializer/direct/struct/HugeType.java b/hugegraph-client/src/main/java/org/apache/hugegraph/serializer/direct/struct/HugeType.java
index 61485bda..343ab0f5 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/serializer/direct/struct/HugeType.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/serializer/direct/struct/HugeType.java
@@ -71,7 +71,7 @@ public enum HugeType {
     MAX_TYPE(255, "~");
 
     private byte type = 0;
-    private String name;
+    private final String name;
 
     private static final Map<String, HugeType> ALL_NAME;
 
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/serializer/direct/util/BytesBuffer.java b/hugegraph-client/src/main/java/org/apache/hugegraph/serializer/direct/util/BytesBuffer.java
index 7da303c2..054f24bb 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/serializer/direct/util/BytesBuffer.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/serializer/direct/util/BytesBuffer.java
@@ -54,7 +54,7 @@ public final class BytesBuffer extends OutputStream {
     public static final byte STRING_ENDING_BYTE = (byte) 0x00;
     public static final byte STRING_ENDING_BYTE_FF = (byte) 0xff;
     public static final int STRING_LEN_MAX = UINT16_MAX;
-    public static final long BLOB_LEN_MAX = 1 * Bytes.GB;
+    public static final long BLOB_LEN_MAX = Bytes.GB;
 
     // The value must be in range [8, ID_LEN_MAX]
     public static final int INDEX_HASH_ID_THRESHOLD = 32;
@@ -667,7 +667,7 @@ public final class BytesBuffer extends OutputStream {
                 value |= this.readUInt16();
                 break;
             case 2:
-                value |= this.readUInt8() << 16 | this.readUInt16();
+                value |= (long) this.readUInt8() << 16 | this.readUInt16();
                 break;
             case 3:
                 value |= this.readUInt32();
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/Task.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/Task.java
index f10b2b5e..13bfecde 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/Task.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/Task.java
@@ -72,6 +72,9 @@ public class Task {
     @JsonProperty(P.SERVER)
     private String server;
 
+    @JsonProperty(P.PRIORITY)
+    private String priority;
+
     public long id() {
         return this.id;
     }
@@ -80,6 +83,10 @@ public class Task {
         return this.type;
     }
 
+    public void type(String type) {
+        this.type = type;
+    }
+
     public String name() {
         return this.name;
     }
@@ -128,6 +135,10 @@ public class Task {
         return this.server;
     }
 
+    public String priority() {
+        return this.priority;
+    }
+
     public boolean completed() {
         return ImmutableSet.of("success", "failed", "cancelled")
                            .contains(this.status);
@@ -176,6 +187,9 @@ public class Task {
         if (this.server != null) {
             map.put(P.SERVER, this.server);
         }
+        if (this.priority != null) {
+            map.put(P.PRIORITY, this.priority);
+        }
 
         return map;
     }
@@ -201,5 +215,6 @@ public class Task {
         public static final String RESULT = "task_result";
         public static final String DEPENDENCIES = "task_dependencies";
         public static final String SERVER = "task_server";
+        public static final String PRIORITY = "task_priority";
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Access.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Access.java
index 5ebcbb68..595b75d6 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Access.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Access.java
@@ -26,14 +26,16 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 
 public class Access extends AuthElement {
 
+    @JsonProperty("graphspace")
+    protected String graphSpace;
     @JsonProperty("group")
     private Object group;
     @JsonProperty("target")
-    private Object target;
+    protected Object target;
     @JsonProperty("access_permission")
-    private HugePermission permission;
+    protected HugePermission permission;
     @JsonProperty("access_description")
-    private String description;
+    protected String description;
 
     @JsonProperty("access_create")
     @JsonFormat(pattern = DATE_FORMAT)
@@ -64,6 +66,14 @@ public class Access extends AuthElement {
         return this.creator;
     }
 
+    public String graphSpace() {
+        return this.graphSpace;
+    }
+
+    public void graphSpace(String graphSpace) {
+        this.graphSpace = graphSpace;
+    }
+
     public Object group() {
         return this.group;
     }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/AuthElement.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/AuthElement.java
index cca35921..a359052a 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/AuthElement.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/AuthElement.java
@@ -17,12 +17,12 @@
 
 package org.apache.hugegraph.structure.auth;
 
-import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
 
 import org.apache.hugegraph.structure.Element;
 
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.Date;
 
 @JsonInclude(JsonInclude.Include.NON_NULL)
 public abstract class AuthElement extends Element {
@@ -37,6 +37,10 @@ public abstract class AuthElement extends Element {
         return this.id;
     }
 
+    public void setId(Object id) {
+        this.id = id;
+    }
+
     public abstract Date createTime();
 
     public abstract Date updateTime();
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Belong.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Belong.java
index e0aebe5f..41fc95b6 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Belong.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Belong.java
@@ -26,12 +26,18 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 
 public class Belong extends AuthElement {
 
+    @JsonProperty("graphspace")
+    protected String graphSpace;
     @JsonProperty("user")
-    private Object user;
+    protected Object user;
     @JsonProperty("group")
-    private Object group;
+    protected Object group;
+    @JsonProperty("role")
+    protected Object role;
     @JsonProperty("belong_description")
-    private String description;
+    protected String description;
+    @JsonProperty("link")
+    protected String link;
 
     @JsonProperty("belong_create")
     @JsonFormat(pattern = DATE_FORMAT)
@@ -62,6 +68,18 @@ public class Belong extends AuthElement {
         return this.creator;
     }
 
+    public String graphSpace() {
+        return this.graphSpace;
+    }
+
+    public String link() {
+        return this.link;
+    }
+
+    public void graphSpace(String graphSpace) {
+        this.graphSpace = graphSpace;
+    }
+
     public Object user() {
         return this.user;
     }
@@ -84,6 +102,17 @@ public class Belong extends AuthElement {
         this.group = group;
     }
 
+    public Object role() {
+        return this.role;
+    }
+
+    public void role(Object role) {
+        if (role instanceof Role) {
+            role = ((Role) role).id();
+        }
+        this.role = role;
+    }
+
     public String description() {
         return this.description;
     }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/HugePermission.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/HugePermission.java
index 1f5fe184..0267f267 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/HugePermission.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/HugePermission.java
@@ -26,7 +26,8 @@ public enum HugePermission {
     DELETE(0x04),
     EXECUTE(0x08),
 
-    ANY(0x7f);
+    SPACE(0x1f),
+    ADMIN(0x7f);
 
     private final byte code;
 
@@ -44,8 +45,8 @@ public enum HugePermission {
     }
 
     public boolean match(HugePermission other) {
-        if (other == ANY) {
-            return this == ANY;
+        if (other == ADMIN) {
+            return this == ADMIN;
         }
         return (this.code & other.code) != 0;
     }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Login.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Login.java
index bb362c43..45a581ad 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Login.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Login.java
@@ -27,6 +27,9 @@ public class Login {
     @JsonProperty("user_password")
     private String password;
 
+    @JsonProperty("token_expire")
+    private long expire;
+
     public void name(String name) {
         this.name = name;
     }
@@ -42,4 +45,12 @@ public class Login {
     public String password() {
         return this.password;
     }
+
+    public void expire(long expire) {
+        this.expire = expire;
+    }
+
+    public long expire() {
+        return this.expire;
+    }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Access.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Role.java
similarity index 51%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Access.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Role.java
index 5ebcbb68..c6e66090 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Access.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Role.java
@@ -17,36 +17,35 @@
 
 package org.apache.hugegraph.structure.auth;
 
-import java.util.Date;
-
-import org.apache.hugegraph.structure.constant.HugeType;
-
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.hugegraph.structure.constant.HugeType;
 
-public class Access extends AuthElement {
-
-    @JsonProperty("group")
-    private Object group;
-    @JsonProperty("target")
-    private Object target;
-    @JsonProperty("access_permission")
-    private HugePermission permission;
-    @JsonProperty("access_description")
-    private String description;
+import java.util.Date;
 
-    @JsonProperty("access_create")
-    @JsonFormat(pattern = DATE_FORMAT)
+public class Role extends AuthElement {
+    @JsonProperty("graphspace")
+    protected String graphSpace;
+    @JsonProperty("role_name")
+    protected String name;
+    @JsonProperty("role_nickname")
+    protected String nickname;
+    @JsonProperty("role_description")
+    protected String description;
+
+    @JsonProperty("role_create")
+    @JsonFormat(pattern = DATE_FORMAT, timezone = "GMT+8")
     protected Date create;
-    @JsonProperty("access_update")
-    @JsonFormat(pattern = DATE_FORMAT)
+    @JsonProperty("role_update")
+    @JsonFormat(pattern = DATE_FORMAT, timezone = "GMT+8")
     protected Date update;
-    @JsonProperty("access_creator")
+    @JsonProperty("role_creator")
     protected String creator;
 
     @Override
     public String type() {
-        return HugeType.ACCESS.string();
+        return HugeType.GROUP.string();
     }
 
     @Override
@@ -64,34 +63,28 @@ public class Access extends AuthElement {
         return this.creator;
     }
 
-    public Object group() {
-        return this.group;
+    public String name() {
+        return this.name;
     }
 
-    public void group(Object group) {
-        if (group instanceof Group) {
-            group = ((Group) group).id();
-        }
-        this.group = group;
+    public void name(String name) {
+        this.name = name;
     }
 
-    public Object target() {
-        return this.target;
+    public void graphSpace(String graphSpace) {
+        this.graphSpace = graphSpace;
     }
 
-    public void target(Object target) {
-        if (target instanceof Target) {
-            target = ((Target) target).id();
-        }
-        this.target = target;
+    public String graphSpace() {
+        return this.graphSpace;
     }
 
-    public HugePermission permission() {
-        return this.permission;
+    public String nickname() {
+        return this.nickname;
     }
 
-    public void permission(HugePermission permission) {
-        this.permission = permission;
+    public void nickname(String nickname) {
+        this.nickname = nickname;
     }
 
     public String description() {
@@ -101,4 +94,22 @@ public class Access extends AuthElement {
     public void description(String description) {
         this.description = description;
     }
+
+    public RoleReq switchReq() {
+        return new RoleReq(this);
+    }
+
+    @JsonIgnoreProperties({"graphspace"})
+    public static class RoleReq extends Role {
+
+        public RoleReq(Role role) {
+            this.id = role.id();
+            this.name = role.name();
+            this.nickname = role.nickname;
+            this.description = role.description();
+            this.update = role.updateTime();
+            this.create = role.createTime();
+            this.creator = role.creator();
+        }
+    }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Target.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Target.java
index 5d4b2031..e398752a 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Target.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/Target.java
@@ -30,13 +30,17 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 public class Target extends AuthElement {
 
     @JsonProperty("target_name")
-    private String name;
+    protected String name;
+    @JsonProperty("graphspace")
+    protected String graphSpace;
     @JsonProperty("target_graph")
-    private String graph;
+    protected String graph;
     @JsonProperty("target_url")
-    private String url;
+    protected String url;
+    @JsonProperty("target_description")
+    protected String description;
     @JsonProperty("target_resources")
-    private List<HugeResource> resources;
+    protected List<HugeResource> resources;
 
     @JsonProperty("target_create")
     @JsonFormat(pattern = DATE_FORMAT)
@@ -75,6 +79,14 @@ public class Target extends AuthElement {
         this.name = name;
     }
 
+    public String graphSpace() {
+        return this.graphSpace;
+    }
+
+    public void graphSpace(String graphSpace) {
+        this.graphSpace = graphSpace;
+    }
+
     public String graph() {
         return this.graph;
     }
@@ -91,6 +103,14 @@ public class Target extends AuthElement {
         this.url = url;
     }
 
+    public String description() {
+        return this.description;
+    }
+
+    public void description(String description) {
+        this.description = description;
+    }
+
     public HugeResource resource() {
         if (this.resources == null || this.resources.size() != 1) {
             return null;
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/User.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/User.java
index a0749333..7303b191 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/User.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/User.java
@@ -32,6 +32,8 @@ public class User extends AuthElement {
 
     @JsonProperty("user_name")
     private String name;
+    @JsonProperty("user_nickname")
+    private String nickname;
     @JsonProperty("user_password")
     private String password;
     @JsonProperty("user_phone")
@@ -42,6 +44,11 @@ public class User extends AuthElement {
     private String avatar;
     @JsonProperty("user_description")
     private String description;
+    @JsonProperty("department") // User's department
+    private String department;
+    @JsonProperty("image_url") // User's avatar URL
+    private String imageUrl;
+
 
     @JsonProperty("user_create")
     @JsonFormat(pattern = DATE_FORMAT)
@@ -80,6 +87,23 @@ public class User extends AuthElement {
         this.name = name;
     }
 
+    public String nickname() {
+        return this.nickname;
+    }
+
+
+    public void nickname(String nickname) {
+        this.nickname = nickname;
+    }
+
+    public String imageUrl() {
+        return imageUrl;
+    }
+
+    public void imageUrl(String imageUrl) {
+        this.imageUrl = imageUrl;
+    }
+
     public String password() {
         return this.password;
     }
@@ -116,6 +140,13 @@ public class User extends AuthElement {
         return this.description;
     }
 
+    public String department() {
+        return this.department;
+    }
+
+    public String department(String department) {
+        return this.department = department;
+    }
     public void description(String description) {
         this.description = description;
     }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/AuthElement.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/UserManager.java
similarity index 62%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/AuthElement.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/UserManager.java
index cca35921..feadf829 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/AuthElement.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/UserManager.java
@@ -17,29 +17,40 @@
 
 package org.apache.hugegraph.structure.auth;
 
-import java.util.Date;
-
-import org.apache.hugegraph.structure.Element;
-
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 @JsonInclude(JsonInclude.Include.NON_NULL)
-public abstract class AuthElement extends Element {
+public class UserManager {
 
-    public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
+    @JsonProperty("user")
+    private String user;
+    @JsonProperty("type")
+    private HugePermission type;
+    @JsonProperty("graphspace")
+    private String graphSpace;
+
+    public String user() {
+        return user;
+    }
 
-    @JsonProperty("id")
-    protected Object id;
+    public void user(String user) {
+        this.user = user;
+    }
 
-    @Override
-    public Object id() {
-        return this.id;
+    public HugePermission type() {
+        return type;
     }
 
-    public abstract Date createTime();
+    public void type(HugePermission type) {
+        this.type = type;
+    }
 
-    public abstract Date updateTime();
+    public String graphSpace() {
+        return graphSpace;
+    }
 
-    public abstract String creator();
+    public void graphSpace(String graphSpace) {
+        this.graphSpace = graphSpace;
+    }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/graph/BatchEdgeRequest.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/graph/BatchEdgeRequest.java
index 66e979cd..526f500c 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/graph/BatchEdgeRequest.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/graph/BatchEdgeRequest.java
@@ -58,7 +58,7 @@ public class BatchEdgeRequest {
 
     public static class Builder {
 
-        private BatchEdgeRequest req;
+        private final BatchEdgeRequest req;
 
         public Builder() {
             this.req = new BatchEdgeRequest();
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/graph/BatchOlapPropertyRequest.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/graph/BatchOlapPropertyRequest.java
index e8a40199..49c14fbd 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/graph/BatchOlapPropertyRequest.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/graph/BatchOlapPropertyRequest.java
@@ -48,7 +48,7 @@ public class BatchOlapPropertyRequest {
 
     public static class Builder {
 
-        private BatchOlapPropertyRequest req;
+        private final BatchOlapPropertyRequest req;
 
         private Builder() {
             this.req = new BatchOlapPropertyRequest();
@@ -96,7 +96,7 @@ public class BatchOlapPropertyRequest {
 
         public static class Builder {
 
-            private OlapVertex vertex;
+            private final OlapVertex vertex;
 
             public Builder() {
                 this.vertex = new OlapVertex();
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/graph/BatchVertexRequest.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/graph/BatchVertexRequest.java
index 50cc5462..6e6cc2a8 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/graph/BatchVertexRequest.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/graph/BatchVertexRequest.java
@@ -54,7 +54,7 @@ public class BatchVertexRequest {
 
     public static class Builder {
 
-        private BatchVertexRequest req;
+        private final BatchVertexRequest req;
 
         public Builder() {
             this.req = new BatchVertexRequest();
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/graph/Graph.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/graph/Graph.java
index cc6d577b..b72c0746 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/graph/Graph.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/graph/Graph.java
@@ -94,7 +94,7 @@ public class Graph {
     public static class HugeVertex {
 
         private Vertex vertex;
-        private List<HugeEdge> edges;
+        private final List<HugeEdge> edges;
 
         public HugeVertex(Vertex v) {
             this.vertex = v;
@@ -126,7 +126,7 @@ public class Graph {
 
     public static class HugeEdge {
 
-        private Edge edge;
+        private final Edge edge;
         private HugeVertex source;
         private HugeVertex target;
 
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/gremlin/Result.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/gremlin/Result.java
index 03353dfa..80ac32a5 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/gremlin/Result.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/gremlin/Result.java
@@ -23,7 +23,7 @@ import org.apache.hugegraph.structure.graph.Vertex;
 
 public class Result {
 
-    private Object object;
+    private final Object object;
 
     public Result(Object object) {
         this.object = object;
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/schema/BuilderProxy.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/schema/BuilderProxy.java
index 064010c6..b65451f4 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/schema/BuilderProxy.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/schema/BuilderProxy.java
@@ -26,8 +26,8 @@ import org.apache.hugegraph.exception.InvalidOperationException;
 public class BuilderProxy<T> implements InvocationHandler {
 
     private boolean finished;
-    private T builder;
-    private T proxy;
+    private final T builder;
+    private final T proxy;
 
     @SuppressWarnings("unchecked")
     public BuilderProxy(T builder) {
@@ -43,10 +43,10 @@ public class BuilderProxy<T> implements InvocationHandler {
 
     @Override
     public Object invoke(Object proxy, Method method, Object[] args)
-                         throws Throwable {
+            throws Throwable {
         if (this.finished) {
             throw new InvalidOperationException(
-                      "Can't access builder which is completed");
+                    "Can't access builder which is completed");
         }
         // The result may be equal this.builder, like method `asText`
         Object result = method.invoke(this.builder, args);
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/schema/EdgeLabel.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/schema/EdgeLabel.java
index 820a60e0..adeb8dd9 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/schema/EdgeLabel.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/schema/EdgeLabel.java
@@ -205,6 +205,8 @@ public class EdgeLabel extends SchemaLabel {
         Builder userdata(String key, Object val);
 
         Builder ifNotExist();
+
+        Builder id(long id);
     }
 
     public static class BuilderImpl implements Builder {
@@ -381,6 +383,12 @@ public class EdgeLabel extends SchemaLabel {
             return this;
         }
 
+        @Override
+        public Builder id(long id) {
+            this.edgeLabel.id = id;
+            return this;
+        }
+
         private void checkFrequency() {
             E.checkArgument(this.edgeLabel.frequency == Frequency.DEFAULT,
                             "Not allowed to change frequency for edge label '%s'",
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/schema/IndexLabel.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/schema/IndexLabel.java
index f390af2a..de64f4fc 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/schema/IndexLabel.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/schema/IndexLabel.java
@@ -123,12 +123,14 @@ public class IndexLabel extends SchemaElement {
         Builder ifNotExist();
 
         Builder rebuild(boolean rebuild);
+
+        Builder id(long id);
     }
 
     public static class BuilderImpl implements Builder {
 
-        private IndexLabel indexLabel;
-        private SchemaManager manager;
+        private final IndexLabel indexLabel;
+        private final SchemaManager manager;
 
         public BuilderImpl(String name, SchemaManager manager) {
             this.indexLabel = new IndexLabel(name);
@@ -246,6 +248,12 @@ public class IndexLabel extends SchemaElement {
             this.indexLabel.rebuild = rebuild;
             return this;
         }
+
+        @Override
+        public Builder id(long id) {
+            this.indexLabel.id = id;
+            return this;
+        }
     }
 
     public static class IndexLabelWithTask {
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/schema/PropertyKey.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/schema/PropertyKey.java
index ce699ff3..b690c1e8 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/schema/PropertyKey.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/schema/PropertyKey.java
@@ -124,6 +124,8 @@ public class PropertyKey extends SchemaElement {
 
         Builder writeType(WriteType writeType);
 
+        Builder writeType(String name);
+
         Builder calcSum();
 
         Builder calcMax();
@@ -135,12 +137,19 @@ public class PropertyKey extends SchemaElement {
         Builder userdata(String key, Object val);
 
         Builder ifNotExist();
+
+        Builder newName(String newName);
+
+        PropertyKey update();
+
+        Builder id(long id);
     }
 
     public static class BuilderImpl implements Builder {
 
-        private PropertyKey propertyKey;
-        private SchemaManager manager;
+        private final PropertyKey propertyKey;
+        private final SchemaManager manager;
+        private String oldName;
 
         public BuilderImpl(String name, SchemaManager manager) {
             this.propertyKey = new PropertyKey(name);
@@ -167,6 +176,18 @@ public class PropertyKey extends SchemaElement {
             return this.manager.eliminatePropertyKey(this.propertyKey);
         }
 
+        @Override
+        public PropertyKey update() {
+            return this.manager.updatePropertyKey(this.oldName,
+                                                  this.propertyKey);
+        }
+
+        @Override
+        public Builder id(long id) {
+            this.propertyKey.id = id;
+            return this;
+        }
+
         @Override
         public void remove() {
             this.manager.removePropertyKey(this.propertyKey.name);
@@ -178,6 +199,13 @@ public class PropertyKey extends SchemaElement {
             return this;
         }
 
+        @Override
+        public Builder newName(String name) {
+            this.oldName = this.propertyKey.name;
+            this.propertyKey.name = name;
+            return this;
+        }
+
         @Override
         public Builder asText() {
             this.propertyKey.dataType = DataType.TEXT;
@@ -274,6 +302,12 @@ public class PropertyKey extends SchemaElement {
             return this;
         }
 
+        @Override
+        public Builder writeType(String name) {
+            this.propertyKey.writeType = WriteType.valueOf(name);
+            return this;
+        }
+
         @Override
         public Builder calcSum() {
             this.propertyKey.aggregateType = AggregateType.SUM;
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/schema/VertexLabel.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/schema/VertexLabel.java
index 6581062e..fd81f807 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/schema/VertexLabel.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/schema/VertexLabel.java
@@ -123,12 +123,14 @@ public class VertexLabel extends SchemaLabel {
         Builder userdata(String key, Object val);
 
         Builder ifNotExist();
+
+        Builder id(long id);
     }
 
     public static class BuilderImpl implements Builder {
 
-        private VertexLabel vertexLabel;
-        private SchemaManager manager;
+        private final VertexLabel vertexLabel;
+        private final SchemaManager manager;
 
         public BuilderImpl(String name, SchemaManager manager) {
             this.vertexLabel = new VertexLabel(name);
@@ -259,6 +261,12 @@ public class VertexLabel extends SchemaLabel {
             return this;
         }
 
+        @Override
+        public Builder id(long id) {
+            this.vertexLabel.id = id;
+            return this;
+        }
+
         private void checkIdStrategy() {
             E.checkArgument(this.vertexLabel.idStrategy == IdStrategy.DEFAULT,
                             "Not allowed to change id strategy for " +
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/space/HStoreNodeInfo.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/space/HStoreNodeInfo.java
index 94568d74..f5ecde45 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/space/HStoreNodeInfo.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/space/HStoreNodeInfo.java
@@ -29,13 +29,13 @@ public class HStoreNodeInfo {
     // Node id
     @JsonProperty("id")
     private String id;
-    // 总空间大小
+    // Total space size
     @JsonProperty("capacity")
     private long capacity;
-    // 已使用空间
+    // Used space
     @JsonProperty("used")
     private long used;
-    // 节点状态
+    // Node status
     @JsonProperty("state")
     private String state;
     // grpc ip:port
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/CountRequest.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/CountRequest.java
index 2fbd5cbf..80d6536e 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/CountRequest.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/CountRequest.java
@@ -58,8 +58,8 @@ public class CountRequest {
 
     public static class Builder {
 
-        private CountRequest request;
-        private List<EdgeStep.Builder> stepBuilders;
+        private final CountRequest request;
+        private final List<EdgeStep.Builder> stepBuilders;
 
         private Builder() {
             this.request = new CountRequest();
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/task/TasksWithPage.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/CountResponse.java
similarity index 71%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/api/task/TasksWithPage.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/CountResponse.java
index 44c06311..127130b5 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/task/TasksWithPage.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/CountResponse.java
@@ -15,26 +15,27 @@
  * under the License.
  */
 
-package org.apache.hugegraph.api.task;
+package org.apache.hugegraph.structure.traverser;
 
-import java.util.List;
-
-import org.apache.hugegraph.structure.Task;
+import java.util.Map;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-public class TasksWithPage {
+import lombok.Setter;
+
+public class CountResponse {
 
     @JsonProperty
-    private String page;
+    @Setter
+    private Map<String, Number> countMap;
     @JsonProperty
-    private List<Task> tasks;
+    private Map<String, Object> measure;
 
-    public String page() {
-        return this.page;
+    public Map<String, Number> countMap() {
+        return this.countMap;
     }
 
-    public List<Task> tasks() {
-        return this.tasks;
+    public Map<String, Object> measure() {
+        return this.measure;
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/CrosspointsRequest.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/CrosspointsRequest.java
index 7371e95b..c9d12cd3 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/CrosspointsRequest.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/CrosspointsRequest.java
@@ -38,13 +38,13 @@ public class CrosspointsRequest {
     @JsonProperty("capacity")
     private long capacity;
     @JsonProperty("limit")
-    private int limit;
+    private long limit;
     @JsonProperty("with_path")
-    private boolean withPath;
+    public boolean withPath;
     @JsonProperty("with_vertex")
-    private boolean withVertex;
+    public boolean withVertex;
     @JsonProperty("with_edge")
-    private boolean withEdge;
+    public boolean withEdge;
 
     private CrosspointsRequest() {
         this.sources = null;
@@ -72,9 +72,9 @@ public class CrosspointsRequest {
 
     public static class Builder {
 
-        private CrosspointsRequest request;
-        private VerticesArgs.Builder sourcesBuilder;
-        private List<PathPattern.Builder> pathPatternBuilders;
+        private final CrosspointsRequest request;
+        private final VerticesArgs.Builder sourcesBuilder;
+        private final List<PathPattern.Builder> pathPatternBuilders;
 
         private Builder() {
             this.request = new CrosspointsRequest();
@@ -98,7 +98,7 @@ public class CrosspointsRequest {
             return this;
         }
 
-        public Builder limit(int limit) {
+        public Builder limit(long limit) {
             TraversersAPI.checkLimit(limit);
             this.request.limit = limit;
             return this;
@@ -146,8 +146,8 @@ public class CrosspointsRequest {
 
         public static class Builder {
 
-            private PathPattern pathPattern;
-            private List<Step.Builder> stepBuilders;
+            private final PathPattern pathPattern;
+            private final List<Step.Builder> stepBuilders;
 
             private Builder() {
                 this.pathPattern = new PathPattern();
@@ -199,7 +199,7 @@ public class CrosspointsRequest {
 
         public static class Builder {
 
-            private Step step;
+            private final Step step;
 
             private Builder() {
                 this.step = new Step();
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/CustomizedPathsRequest.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/CustomizedPathsRequest.java
index b238286e..378403dd 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/CustomizedPathsRequest.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/CustomizedPathsRequest.java
@@ -42,9 +42,9 @@ public class CustomizedPathsRequest {
     @JsonProperty("capacity")
     private long capacity;
     @JsonProperty("limit")
-    private int limit;
+    private long limit;
     @JsonProperty("with_vertex")
-    private boolean withVertex;
+    public boolean withVertex;
     @JsonProperty("with_edge")
     private boolean withEdge;
 
@@ -73,9 +73,9 @@ public class CustomizedPathsRequest {
 
     public static class Builder {
 
-        private CustomizedPathsRequest request;
-        private VerticesArgs.Builder sourcesBuilder;
-        private List<Step.Builder> stepBuilders;
+        private final CustomizedPathsRequest request;
+        private final VerticesArgs.Builder sourcesBuilder;
+        private final List<Step.Builder> stepBuilders;
 
         private Builder() {
             this.request = new CustomizedPathsRequest();
@@ -104,7 +104,7 @@ public class CustomizedPathsRequest {
             return this;
         }
 
-        public Builder limit(int limit) {
+        public Builder limit(long limit) {
             TraversersAPI.checkLimit(limit);
             this.request.limit = limit;
             return this;
@@ -174,7 +174,7 @@ public class CustomizedPathsRequest {
 
         public static class Builder {
 
-            private Step step;
+            private final Step step;
 
             private Builder() {
                 this.step = new Step();
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/JaccardSimilarity.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/Egonet.java
similarity index 57%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/JaccardSimilarity.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/Egonet.java
index 428598cc..24cb9fde 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/JaccardSimilarity.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/Egonet.java
@@ -17,35 +17,52 @@
 
 package org.apache.hugegraph.structure.traverser;
 
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.hugegraph.structure.graph.Edge;
+import org.apache.hugegraph.structure.graph.Path;
+import org.apache.hugegraph.structure.graph.Vertex;
+
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-public class JaccardSimilarity {
+public class Egonet {
 
-    @JsonProperty("jaccard_similarity")
-    private Map<Object, Double> similarsMap;
+    @JsonProperty("egonet")
+    private Set<Object> ids;
+    @JsonProperty
+    private int size;
+    @JsonProperty
+    private List<Path> paths;
     @JsonProperty
-    private ApiMeasure measure;
+    private Set<Vertex> vertices;
+    @JsonProperty
+    private Set<Edge> edges;
+    @JsonProperty
+    private Map<String, Object> measure;
 
-    public Map<Object, Double> similarsMap() {
-        return this.similarsMap;
+    public Set<Object> ids() {
+        return this.ids;
     }
 
-    public ApiMeasure measure() {
-        return this.measure;
+    public int size() {
+        return this.size;
     }
 
-    public int size() {
-        return this.similarsMap.size();
+    public List<Path> paths() {
+        return this.paths;
     }
 
-    public Set<Object> keySet() {
-        return this.similarsMap.keySet();
+    public Set<Vertex> vertices() {
+        return this.vertices;
     }
 
-    public Double get(Object key) {
-        return this.similarsMap.get(key);
+    public Set<Edge> edges() {
+        return this.edges;
+    }
+
+    public Map<String, Object> measure() {
+        return this.measure;
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/KneighborRequest.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/EgonetRequest.java
similarity index 63%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/KneighborRequest.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/EgonetRequest.java
index 4c9bd580..68b6e2e5 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/KneighborRequest.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/EgonetRequest.java
@@ -17,74 +17,78 @@
 
 package org.apache.hugegraph.structure.traverser;
 
+import java.util.Set;
+
+import org.apache.hugegraph.util.E;
+
 import org.apache.hugegraph.api.traverser.TraversersAPI;
 import org.apache.hugegraph.structure.constant.Traverser;
-import org.apache.hugegraph.util.E;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-public class KneighborRequest {
+public class EgonetRequest {
 
-    @JsonProperty("source")
-    private Object source;
+    @JsonProperty("sources")
+    public Set<Object> sources;
     @JsonProperty("steps")
-    public VESteps steps;
+    public Steps steps;
     @JsonProperty("max_depth")
     public int maxDepth;
-    @JsonProperty("count_only")
-    public boolean countOnly;
     @JsonProperty("limit")
-    public int limit;
+    public long limit = Traverser.DEFAULT_LIMIT;
+    @JsonProperty("count_only")
+    public boolean countOnly = false;
     @JsonProperty("with_vertex")
-    public boolean withVertex;
+    public boolean withVertex = false;
     @JsonProperty("with_path")
-    public boolean withPath;
+    public boolean withPath = false;
     @JsonProperty("with_edge")
-    public boolean withEdge;
+    public boolean withEdge = false;
 
-    private KneighborRequest() {
-        this.source = null;
+    private EgonetRequest() {
+        this.sources = null;
         this.steps = null;
         this.maxDepth = Traverser.DEFAULT_MAX_DEPTH;
-        this.countOnly = false;
         this.limit = Traverser.DEFAULT_PATHS_LIMIT;
+        this.countOnly = false;
         this.withVertex = false;
         this.withPath = false;
         this.withEdge = false;
     }
 
-    public static Builder builder() {
-        return new Builder();
+    public static EgonetRequest.Builder builder() {
+        return new EgonetRequest.Builder();
     }
 
     @Override
     public String toString() {
-        return String.format("KneighborRequest{source=%s,steps=%s,maxDepth=%s" +
-                             "countOnly=%s,limit=%s,withVertex=%s,withPath=%s,withEdge=%s}",
-                             this.source, this.steps, this.maxDepth,
-                             this.countOnly, this.limit, this.withVertex,
+        return String.format("EgonetRequest{sources=%s,steps=%s," +
+                             "maxDepth=%s,limit=%s,countOnly=%s," +
+                             "withVertex=%s,withPath=%s,withEdge=%s}",
+                             this.sources, this.steps, this.maxDepth,
+                             this.limit, this.countOnly, this.withVertex,
                              this.withPath, this.withEdge);
     }
 
     public static class Builder {
 
-        private KneighborRequest request;
-        private VESteps.Builder stepBuilder;
+        private final EgonetRequest request;
+        private Steps.Builder stepsBuilder;
 
         private Builder() {
-            this.request = new KneighborRequest();
-            this.stepBuilder = VESteps.builder();
+            this.request = new EgonetRequest();
+            this.stepsBuilder = Steps.builder();
         }
 
-        public Builder source(Object source) {
-            E.checkNotNull(source, "source");
-            this.request.source = source;
+        public Builder source(Set<Object> sources) {
+            E.checkNotNull(sources, "sources");
+            this.request.sources = sources;
             return this;
         }
 
-        public VESteps.Builder steps() {
-            VESteps.Builder builder = VESteps.builder();
-            this.stepBuilder = builder;
+        public Steps.Builder steps() {
+            Steps.Builder builder = Steps.builder();
+            this.stepsBuilder = builder;
             return builder;
         }
 
@@ -99,7 +103,7 @@ public class KneighborRequest {
             return this;
         }
 
-        public Builder limit(int limit) {
+        public Builder limit(long limit) {
             TraversersAPI.checkLimit(limit);
             this.request.limit = limit;
             return this;
@@ -110,26 +114,28 @@ public class KneighborRequest {
             return this;
         }
 
-        public Builder withEdge(boolean withEdge) {
-            this.request.withEdge = withEdge;
+        public Builder withPath(boolean withPath) {
+            this.request.withPath = withPath;
             return this;
         }
 
-        public Builder withPath(boolean withPath) {
-            this.request.withPath = withPath;
+        public Builder withEdge(boolean withEdge) {
+            this.request.withEdge = withEdge;
             return this;
         }
 
-        public KneighborRequest build() {
-            E.checkNotNull(this.request.source, "The source can't be null");
-            this.request.steps = this.stepBuilder.build();
+        public EgonetRequest build() {
+            E.checkArgument(this.request.sources != null &&
+                            !this.request.sources.isEmpty(),
+                            "The sources can't be null or empty");
+            this.request.steps = this.stepsBuilder.build();
             E.checkNotNull(this.request.steps, "steps");
             TraversersAPI.checkPositive(this.request.maxDepth, "max depth");
             TraversersAPI.checkLimit(this.request.limit);
             if (this.request.countOnly) {
                 E.checkArgument(!this.request.withVertex &&
-                                !this.request.withPath,
-                                "Can't return vertex or path " +
+                                !this.request.withPath && !this.request.withEdge,
+                                "Can't return vertex, edge or path " +
                                 "when count only is true");
             }
             return this.request;
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/FusiformSimilarityRequest.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/FusiformSimilarityRequest.java
index 246dbd51..2a016201 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/FusiformSimilarityRequest.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/FusiformSimilarityRequest.java
@@ -93,8 +93,8 @@ public class FusiformSimilarityRequest {
 
     public static class Builder {
 
-        private FusiformSimilarityRequest request;
-        private VerticesArgs.Builder sourcesBuilder;
+        private final FusiformSimilarityRequest request;
+        private final VerticesArgs.Builder sourcesBuilder;
 
         private Builder() {
             this.request = new FusiformSimilarityRequest();
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/JaccardSimilarity.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/JaccardSimilarity.java
index 428598cc..a4e89685 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/JaccardSimilarity.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/JaccardSimilarity.java
@@ -22,9 +22,12 @@ import java.util.Set;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 
+import lombok.Setter;
+
 public class JaccardSimilarity {
 
     @JsonProperty("jaccard_similarity")
+    @Setter
     private Map<Object, Double> similarsMap;
     @JsonProperty
     private ApiMeasure measure;
@@ -33,6 +36,12 @@ public class JaccardSimilarity {
         return this.similarsMap;
     }
 
+    // TODO: Temp implementation?
+    public Object getJaccardSimilarity() {
+        // get first element from the map
+        return this.similarsMap.entrySet().iterator().next().getValue();
+    }
+
     public ApiMeasure measure() {
         return this.measure;
     }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/KneighborRequest.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/KneighborRequest.java
index 4c9bd580..e7218a16 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/KneighborRequest.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/KneighborRequest.java
@@ -28,19 +28,19 @@ public class KneighborRequest {
     @JsonProperty("source")
     private Object source;
     @JsonProperty("steps")
-    public VESteps steps;
+    public Steps steps;
     @JsonProperty("max_depth")
     public int maxDepth;
     @JsonProperty("count_only")
-    public boolean countOnly;
+    public boolean countOnly = false;
     @JsonProperty("limit")
-    public int limit;
+    public long limit = Traverser.DEFAULT_LIMIT;
     @JsonProperty("with_vertex")
-    public boolean withVertex;
+    public boolean withVertex = false;
     @JsonProperty("with_path")
-    public boolean withPath;
+    public boolean withPath = false;
     @JsonProperty("with_edge")
-    public boolean withEdge;
+    public boolean withEdge = false;
 
     private KneighborRequest() {
         this.source = null;
@@ -62,18 +62,18 @@ public class KneighborRequest {
         return String.format("KneighborRequest{source=%s,steps=%s,maxDepth=%s" +
                              "countOnly=%s,limit=%s,withVertex=%s,withPath=%s,withEdge=%s}",
                              this.source, this.steps, this.maxDepth,
-                             this.countOnly, this.limit, this.withVertex,
-                             this.withPath, this.withEdge);
+                             this.countOnly, this.limit,
+                             this.withVertex, this.withPath, this.withEdge);
     }
 
     public static class Builder {
 
-        private KneighborRequest request;
-        private VESteps.Builder stepBuilder;
+        private final KneighborRequest request;
+        private Steps.Builder stepsBuilder;
 
         private Builder() {
             this.request = new KneighborRequest();
-            this.stepBuilder = VESteps.builder();
+            this.stepsBuilder = Steps.builder();
         }
 
         public Builder source(Object source) {
@@ -82,9 +82,9 @@ public class KneighborRequest {
             return this;
         }
 
-        public VESteps.Builder steps() {
-            VESteps.Builder builder = VESteps.builder();
-            this.stepBuilder = builder;
+        public Steps.Builder steps() {
+            Steps.Builder builder = Steps.builder();
+            this.stepsBuilder = builder;
             return builder;
         }
 
@@ -99,7 +99,7 @@ public class KneighborRequest {
             return this;
         }
 
-        public Builder limit(int limit) {
+        public Builder limit(long limit) {
             TraversersAPI.checkLimit(limit);
             this.request.limit = limit;
             return this;
@@ -122,14 +122,14 @@ public class KneighborRequest {
 
         public KneighborRequest build() {
             E.checkNotNull(this.request.source, "The source can't be null");
-            this.request.steps = this.stepBuilder.build();
+            this.request.steps = this.stepsBuilder.build();
             E.checkNotNull(this.request.steps, "steps");
             TraversersAPI.checkPositive(this.request.maxDepth, "max depth");
             TraversersAPI.checkLimit(this.request.limit);
             if (this.request.countOnly) {
                 E.checkArgument(!this.request.withVertex &&
-                                !this.request.withPath,
-                                "Can't return vertex or path " +
+                                !this.request.withPath && !this.request.withEdge,
+                                "Can't return vertex or path or edge " +
                                 "when count only is true");
             }
             return this.request;
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/KoutRequest.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/KoutRequest.java
index 97795193..dcf97593 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/KoutRequest.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/KoutRequest.java
@@ -28,23 +28,23 @@ public class KoutRequest {
     @JsonProperty("source")
     private Object source;
     @JsonProperty("steps")
-    public VESteps steps;
+    public Steps steps;
     @JsonProperty("max_depth")
     public int maxDepth;
     @JsonProperty("nearest")
-    public boolean nearest;
+    public boolean nearest = true;
     @JsonProperty("count_only")
-    public boolean countOnly;
+    public boolean countOnly = false;
     @JsonProperty("capacity")
-    public long capacity;
+    public long capacity = Traverser.DEFAULT_CAPACITY;
     @JsonProperty("limit")
-    public int limit;
+    public long limit = Traverser.DEFAULT_LIMIT;
     @JsonProperty("with_vertex")
-    public boolean withVertex;
+    public boolean withVertex = false;
     @JsonProperty("with_path")
-    public boolean withPath;
+    public boolean withPath = false;
     @JsonProperty("with_edge")
-    public boolean withEdge;
+    public boolean withEdge = false;
     @JsonProperty("traverse_mode")
     public String traverseMode;
 
@@ -81,11 +81,11 @@ public class KoutRequest {
     public static class Builder {
 
         private final KoutRequest request;
-        private VESteps.Builder stepBuilder;
+        private Steps.Builder stepsBuilder;
 
         private Builder() {
             this.request = new KoutRequest();
-            this.stepBuilder = VESteps.builder();
+            this.stepsBuilder = Steps.builder();
         }
 
         public Builder source(Object source) {
@@ -94,9 +94,9 @@ public class KoutRequest {
             return this;
         }
 
-        public VESteps.Builder steps() {
-            VESteps.Builder builder = VESteps.builder();
-            this.stepBuilder = builder;
+        public Steps.Builder steps() {
+            Steps.Builder builder = Steps.builder();
+            this.stepsBuilder = builder;
             return builder;
         }
 
@@ -122,7 +122,7 @@ public class KoutRequest {
             return this;
         }
 
-        public Builder limit(int limit) {
+        public Builder limit(long limit) {
             TraversersAPI.checkLimit(limit);
             this.request.limit = limit;
             return this;
@@ -145,15 +145,15 @@ public class KoutRequest {
 
         public KoutRequest build() {
             E.checkNotNull(this.request.source, "The source can't be null");
-            this.request.steps = this.stepBuilder.build();
-            E.checkNotNull(this.request.steps, "step");
+            this.request.steps = this.stepsBuilder.build();
+            E.checkNotNull(this.request.steps, "steps");
             TraversersAPI.checkPositive(this.request.maxDepth, "max depth");
             TraversersAPI.checkCapacity(this.request.capacity);
             TraversersAPI.checkLimit(this.request.limit);
             if (this.request.countOnly) {
                 E.checkArgument(!this.request.withVertex &&
                                 !this.request.withPath && !this.request.withEdge,
-                                "Can't return vertex or path or edge " +
+                                "Can't return vertex or path or edge" +
                                 "when count only is true");
             }
             return this.request;
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/MultiNodeShortestPathRequest.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/MultiNodeShortestPathRequest.java
index 915d5b0d..527bba3d 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/MultiNodeShortestPathRequest.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/MultiNodeShortestPathRequest.java
@@ -61,8 +61,8 @@ public class MultiNodeShortestPathRequest {
 
     public static class Builder {
 
-        private MultiNodeShortestPathRequest request;
-        private VerticesArgs.Builder verticesBuilder;
+        private final MultiNodeShortestPathRequest request;
+        private final VerticesArgs.Builder verticesBuilder;
         private EdgeStep.Builder stepBuilder;
 
         private Builder() {
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/JaccardSimilarity.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/PathOfVertices.java
similarity index 62%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/JaccardSimilarity.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/PathOfVertices.java
index 428598cc..c8742dc6 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/JaccardSimilarity.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/PathOfVertices.java
@@ -17,35 +17,37 @@
 
 package org.apache.hugegraph.structure.traverser;
 
+import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
+import org.apache.hugegraph.structure.graph.Path;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-public class JaccardSimilarity {
+public class PathOfVertices {
 
-    @JsonProperty("jaccard_similarity")
-    private Map<Object, Double> similarsMap;
+    // AllShortestPathsAPI
+    @JsonProperty("path")
+    private List<Object> path;
+    @JsonProperty("vertices")
+    private List<String> vertices;
+    @JsonProperty("edges")
+    private List<String> edges;
     @JsonProperty
-    private ApiMeasure measure;
+    private Map<String, Object> measure;
 
-    public Map<Object, Double> similarsMap() {
-        return this.similarsMap;
+    public Path getPath() {
+        return new Path(this.path);
     }
 
-    public ApiMeasure measure() {
-        return this.measure;
-    }
-
-    public int size() {
-        return this.similarsMap.size();
+    public List<String> getVertices() {
+        return this.vertices;
     }
 
-    public Set<Object> keySet() {
-        return this.similarsMap.keySet();
+    public List<String> getEdges() {
+        return this.edges;
     }
 
-    public Double get(Object key) {
-        return this.similarsMap.get(key);
+    public Map<String, Object> measure() {
+        return this.measure;
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/PathWithMeasure.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/PathWithMeasure.java
new file mode 100644
index 00000000..5aff4e88
--- /dev/null
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/PathWithMeasure.java
@@ -0,0 +1,75 @@
+/*
+ * 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.hugegraph.structure.traverser;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import lombok.Setter;
+
+import org.apache.hugegraph.structure.graph.Path;
+
+import java.util.List;
+import java.util.Map;
+
+public class PathWithMeasure {
+
+    // AllShortestPathsAPI
+    @JsonProperty("paths")
+    @Setter
+    private List<Path> paths;
+    @JsonProperty("crosspoints")
+    private List<Path> crosspoints;
+    @JsonProperty("vertices")
+    private List<String> vertices;
+    @JsonProperty("edges")
+    private List<String> edges;
+    @JsonProperty("rays")
+    private List<Path> rays;
+    @JsonProperty("rings")
+    private List<Path> rings;
+    @JsonProperty
+    private Map<String, Object> measure;
+
+    public List<Path> getPaths() {
+        return this.paths;
+    }
+
+    public List<Path> getCrosspoints() {
+        return this.crosspoints;
+    }
+
+    public List<String> getVertices() {
+        return this.vertices;
+    }
+
+    public List<String> getEdges() {
+        return this.edges;
+    }
+
+    public List<Path> getRays() {
+        return this.rays;
+    }
+
+    public List<Path> getRings() {
+        return this.rings;
+    }
+
+    public Map<String, Object> measure() {
+        return this.measure;
+    }
+}
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/PathsRequest.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/PathsRequest.java
index 11e36104..bf90cf0f 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/PathsRequest.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/PathsRequest.java
@@ -60,10 +60,10 @@ public class PathsRequest {
 
     public static class Builder {
 
-        private PathsRequest request;
+        private final PathsRequest request;
         private EdgeStep.Builder stepBuilder;
-        private VerticesArgs.Builder sourcesBuilder;
-        private VerticesArgs.Builder targetsBuilder;
+        private final VerticesArgs.Builder sourcesBuilder;
+        private final VerticesArgs.Builder targetsBuilder;
 
         private Builder() {
             this.request = new PathsRequest();
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/JaccardSimilarity.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/Prediction.java
similarity index 65%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/JaccardSimilarity.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/Prediction.java
index 428598cc..d5f6eedd 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/JaccardSimilarity.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/Prediction.java
@@ -18,34 +18,27 @@
 package org.apache.hugegraph.structure.traverser;
 
 import java.util.Map;
-import java.util.Set;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-public class JaccardSimilarity {
+public class Prediction {
 
-    @JsonProperty("jaccard_similarity")
-    private Map<Object, Double> similarsMap;
+    @JsonProperty("adamic_adar")
+    private Double adamicAdar;
+    @JsonProperty("resource_allocation")
+    private Double resourceAllocation;
     @JsonProperty
-    private ApiMeasure measure;
+    private Map<String, Object> measure;
 
-    public Map<Object, Double> similarsMap() {
-        return this.similarsMap;
+    public Double getAdamicAdar() {
+        return this.adamicAdar;
     }
 
-    public ApiMeasure measure() {
-        return this.measure;
-    }
-
-    public int size() {
-        return this.similarsMap.size();
+    public Double getResourceAllocation() {
+        return this.resourceAllocation;
     }
 
-    public Set<Object> keySet() {
-        return this.similarsMap.keySet();
-    }
-
-    public Double get(Object key) {
-        return this.similarsMap.get(key);
+    public Map<String, Object> measure() {
+        return this.measure;
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/JaccardSimilarity.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/RanksWithMeasure.java
similarity index 64%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/JaccardSimilarity.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/RanksWithMeasure.java
index 428598cc..863b01f2 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/JaccardSimilarity.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/RanksWithMeasure.java
@@ -17,35 +17,38 @@
 
 package org.apache.hugegraph.structure.traverser;
 
+import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-public class JaccardSimilarity {
+public class RanksWithMeasure {
 
-    @JsonProperty("jaccard_similarity")
-    private Map<Object, Double> similarsMap;
+    @JsonProperty("personal_rank")
+    private Ranks personalRank;
     @JsonProperty
-    private ApiMeasure measure;
+    private List<Ranks> ranks;
+    @JsonProperty
+    private Map<String, Object> measure;
 
-    public Map<Object, Double> similarsMap() {
-        return this.similarsMap;
+    public RanksWithMeasure() {
     }
 
-    public ApiMeasure measure() {
-        return this.measure;
+    public Ranks personalRanks() {
+        return this.personalRank;
     }
 
-    public int size() {
-        return this.similarsMap.size();
+    public List<Ranks> ranks() {
+        return this.ranks;
     }
 
-    public Set<Object> keySet() {
-        return this.similarsMap.keySet();
+    public Map<String, Object> measure() {
+        return this.measure;
     }
 
-    public Double get(Object key) {
-        return this.similarsMap.get(key);
+    public void setPersonalRank(Ranks personalRank) {
+        if (this.personalRank == null) {
+            this.personalRank = personalRank;
+        }
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/task/TasksWithPage.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/SameNeighbors.java
similarity index 71%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/api/task/TasksWithPage.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/SameNeighbors.java
index 44c06311..a3a91163 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/task/TasksWithPage.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/SameNeighbors.java
@@ -15,26 +15,24 @@
  * under the License.
  */
 
-package org.apache.hugegraph.api.task;
+package org.apache.hugegraph.structure.traverser;
 
 import java.util.List;
-
-import org.apache.hugegraph.structure.Task;
+import java.util.Map;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-public class TasksWithPage {
-
-    @JsonProperty
-    private String page;
+public class SameNeighbors {
+    @JsonProperty("same_neighbors")
+    private List<Object> sameNeighbors;
     @JsonProperty
-    private List<Task> tasks;
+    private Map<String, Object> measure;
 
-    public String page() {
-        return this.page;
+    public List<Object> getSameNeighbors() {
+        return this.sameNeighbors;
     }
 
-    public List<Task> tasks() {
-        return this.tasks;
+    public Map<String, Object> measure() {
+        return this.measure;
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/task/TasksWithPage.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/SameNeighborsBatch.java
similarity index 70%
copy from hugegraph-client/src/main/java/org/apache/hugegraph/api/task/TasksWithPage.java
copy to hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/SameNeighborsBatch.java
index 44c06311..98607437 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/task/TasksWithPage.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/SameNeighborsBatch.java
@@ -15,26 +15,24 @@
  * under the License.
  */
 
-package org.apache.hugegraph.api.task;
-
-import java.util.List;
-
-import org.apache.hugegraph.structure.Task;
+package org.apache.hugegraph.structure.traverser;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-public class TasksWithPage {
+import java.util.List;
+import java.util.Map;
 
+public class SameNeighborsBatch {
+    @JsonProperty("same_neighbors")
+    public List<List<Object>> sameNeighbors;
     @JsonProperty
-    private String page;
-    @JsonProperty
-    private List<Task> tasks;
+    private Map<String, Object> measure;
 
-    public String page() {
-        return this.page;
+    public List<List<Object>> getSameNeighbors() {
+        return this.sameNeighbors;
     }
 
-    public List<Task> tasks() {
-        return this.tasks;
+    public Map<String, Object> measure() {
+        return this.measure;
     }
 }
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/SameNeighborsBatchRequest.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/SameNeighborsBatchRequest.java
new file mode 100644
index 00000000..909794b6
--- /dev/null
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/SameNeighborsBatchRequest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.hugegraph.structure.traverser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.hugegraph.util.E;
+
+import org.apache.hugegraph.api.traverser.TraversersAPI;
+import org.apache.hugegraph.structure.constant.Direction;
+import org.apache.hugegraph.structure.constant.Traverser;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class SameNeighborsBatchRequest {
+
+    @JsonProperty("vertex_list")
+    private List<List<Object>> vertexList;
+    @JsonProperty("direction")
+    private String direction;
+    @JsonProperty("label")
+    private String label;
+    @JsonProperty("max_degree")
+    public long maxDegree = Traverser.DEFAULT_MAX_DEGREE;
+    @JsonProperty("limit")
+    public long limit = Traverser.DEFAULT_ELEMENTS_LIMIT;
+
+    private SameNeighborsBatchRequest() {
+        this.vertexList = new ArrayList<>();
+        this.direction = null;
+        this.label = null;
+        this.maxDegree = Traverser.DEFAULT_MAX_DEGREE;
+        this.limit = Traverser.DEFAULT_ELEMENTS_LIMIT;
+    }
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    @Override
+    public String toString() {
+
+        return String.format("SameNeighborsBatchRequest{vertex_list=%s,direction=%s,label=%s," +
+                             "max_degree=%d,limit=%d", this.vertexList, this.direction,
+                             this.label, this.maxDegree, this.limit);
+    }
+
+    public static class Builder {
+
+        private final SameNeighborsBatchRequest request;
+
+        private Builder() {
+            this.request = new SameNeighborsBatchRequest();
+        }
+
+        public Builder vertex(Object vertexId, Object otherId) {
+            List<Object> vertexPair = new ArrayList<>();
+            vertexPair.add(vertexId);
+            vertexPair.add(otherId);
+            this.request.vertexList.add(vertexPair);
+            return this;
+        }
+
+        public Builder direction(Direction direction) {
+            this.request.direction = direction.toString();
+            return this;
+        }
+
+        public Builder label(String label) {
+            this.request.label = label;
+            return this;
+        }
+
+        public Builder maxDegree(long maxDegree) {
+            TraversersAPI.checkDegree(maxDegree);
+            this.request.maxDegree = maxDegree;
+            return this;
+        }
+
+        public Builder limit(long limit) {
+            TraversersAPI.checkLimit(limit);
+            this.request.limit = limit;
+            return this;
+        }
+
+        public SameNeighborsBatchRequest build() {
+            E.checkArgument(this.request.vertexList != null &&
+                            !this.request.vertexList.isEmpty(),
+                            "The vertex_list can't be null or empty");
+            TraversersAPI.checkDegree(this.request.maxDegree);
+            TraversersAPI.checkLimit(this.request.limit);
+            return this.request;
+        }
+    }
+}
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/SingleSourceJaccardSimilarityRequest.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/SingleSourceJaccardSimilarityRequest.java
index 9eda0277..a848c2ae 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/SingleSourceJaccardSimilarityRequest.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/SingleSourceJaccardSimilarityRequest.java
@@ -54,7 +54,7 @@ public class SingleSourceJaccardSimilarityRequest {
 
     public static class Builder {
 
-        private SingleSourceJaccardSimilarityRequest request;
+        private final SingleSourceJaccardSimilarityRequest request;
         private EdgeStep.Builder stepBuilder;
 
         private Builder() {
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/Steps.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/Steps.java
new file mode 100644
index 00000000..88d7e6ac
--- /dev/null
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/Steps.java
@@ -0,0 +1,142 @@
+/*
+ * 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.hugegraph.structure.traverser;
+
+import org.apache.hugegraph.api.API;
+import org.apache.hugegraph.api.traverser.TraversersAPI;
+import org.apache.hugegraph.structure.constant.Direction;
+import org.apache.hugegraph.structure.constant.Traverser;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class Steps {
+
+    @JsonProperty("direction")
+    protected Direction direction;
+    @JsonProperty("edge_steps")
+    public List<StepEntity> eSteps;
+    @JsonProperty("vertex_steps")
+    public List<StepEntity> vSteps;
+    @JsonProperty("max_degree")
+    protected long maxDegree;
+    @JsonProperty("skip_degree")
+    protected long skipDegree;
+
+    protected Steps() {
+        this.direction = Direction.BOTH;
+        this.eSteps = new ArrayList<>();
+        this.vSteps = new ArrayList<>();
+        this.maxDegree = Traverser.DEFAULT_MAX_DEGREE;
+        this.skipDegree = Traverser.DEFAULT_SKIP_DEGREE;
+    }
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    @Override
+    public String toString() {
+        return String.format("Steps{direction=%s,eSteps=%s,vSteps=%s," +
+                             "maxDegree=%s,skipDegree=%s}",
+                             this.direction, this.eSteps, this.vSteps,
+                             this.maxDegree, this.skipDegree);
+    }
+
+    public static class Builder {
+
+        protected Steps step;
+
+        private Builder() {
+            this.step = new Steps();
+        }
+
+        public Steps.Builder direction(Direction direction) {
+            this.step.direction = direction;
+            return this;
+        }
+
+        public Steps.Builder edgeSteps(List<StepEntity> eSteps) {
+            this.step.eSteps = eSteps;
+            return this;
+        }
+
+        public Steps.Builder edgeSteps(StepEntity stepEntity) {
+            this.step.eSteps.add(stepEntity);
+            return this;
+        }
+
+        public Steps.Builder vertexSteps(List<StepEntity> vSteps) {
+            this.step.vSteps = vSteps;
+            return this;
+        }
+
+        public Steps.Builder vertexSteps(StepEntity stepEntity) {
+            this.step.vSteps.add(stepEntity);
+            return this;
+        }
+
+        public Steps.Builder degree(long degree) {
+            TraversersAPI.checkDegree(degree);
+            this.step.maxDegree = degree;
+            return this;
+        }
+
+        public Steps.Builder skipDegree(long skipDegree) {
+            TraversersAPI.checkSkipDegree(skipDegree, this.step.maxDegree,
+                                          API.NO_LIMIT);
+            this.step.skipDegree = skipDegree;
+            return this;
+        }
+
+        public Steps build() {
+            TraversersAPI.checkDegree(this.step.maxDegree);
+            TraversersAPI.checkSkipDegree(this.step.skipDegree,
+                                          this.step.maxDegree, API.NO_LIMIT);
+            return this.step;
+        }
+    }
+
+    public static class StepEntity {
+        @JsonProperty("label")
+        public String label;
+
+        @JsonProperty("properties")
+        public Map<String, Object> properties;
+
+        public StepEntity() {
+        }
+
+        public StepEntity(String label) {
+            this.label = label;
+        }
+
+        public StepEntity(String label, Map<String, Object> properties) {
+            this.label = label;
+            this.properties = properties;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("StepEntity{label=%s,properties=%s}",
+                    this.label, this.properties);
+        }
+    }
+}
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/TemplatePathsRequest.java b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/TemplatePathsRequest.java
index fad2d309..f80410ea 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/TemplatePathsRequest.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/traverser/TemplatePathsRequest.java
@@ -72,10 +72,10 @@ public class TemplatePathsRequest {
 
     public static class Builder {
 
-        private TemplatePathsRequest request;
-        private VerticesArgs.Builder sourcesBuilder;
-        private VerticesArgs.Builder targetsBuilder;
-        private List<RepeatEdgeStep.Builder> stepBuilders;
+        private final TemplatePathsRequest request;
+        private final VerticesArgs.Builder sourcesBuilder;
+        private final VerticesArgs.Builder targetsBuilder;
+        private final List<RepeatEdgeStep.Builder> stepBuilders;
 
         private Builder() {
             this.request = new TemplatePathsRequest();
diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/util/TaskCache.java b/hugegraph-client/src/main/java/org/apache/hugegraph/util/TaskCache.java
index 4a0e279e..0432a4e6 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/util/TaskCache.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/util/TaskCache.java
@@ -31,7 +31,7 @@ public class TaskCache {
 
     private static final Task FAKE_TASK = new Task();
 
-    private Map<TaskAPI, Map<Long, Task>> taskTable;
+    private final Map<TaskAPI, Map<Long, Task>> taskTable;
     private ScheduledExecutorService service;
 
     private static final TaskCache INSTANCE = new TaskCache();
@@ -95,7 +95,7 @@ public class TaskCache {
 
     private void asyncQueryTask() {
         for (Map.Entry<TaskAPI, Map<Long, Task>> query :
-             this.taskTable.entrySet()) {
+                this.taskTable.entrySet()) {
             TaskAPI api = query.getKey();
             Map<Long, Task> targets = query.getValue();
             if (targets == null || targets.isEmpty()) {
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/EdgeApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/EdgeApiTest.java
index 18705969..9e9802ca 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/EdgeApiTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/EdgeApiTest.java
@@ -613,7 +613,6 @@ public class EdgeApiTest extends BaseApiTest {
 //            edgeAPI.get(ids.get(1));
 //        });
 //    }
-
     @Test
     public void testBatchCreateWithInvalidVertexLabelButNotCheck() {
         List<Edge> edges = new ArrayList<>(2);
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/GraphsApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/GraphsApiTest.java
index 8904ead6..9f03d418 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/GraphsApiTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/GraphsApiTest.java
@@ -209,7 +209,7 @@ public class GraphsApiTest extends BaseApiTest {
 
         Assert.assertEquals(initialGraphNumber + 1, graphsAPI.list().size());
 
-        HugeClient client = new HugeClient(baseClient(), GRAPHSPACE, GRAPH3);
+        HugeClient client = new HugeClient(baseClient(), DEFAULT_GRAPHSPACE, GRAPH3);
         // Insert graph schema and data
         initPropertyKey(client);
         initVertexLabel(client);
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/auth/LoginApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/auth/LoginApiTest.java
index 4f480db2..afa3a132 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/auth/LoginApiTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/auth/LoginApiTest.java
@@ -54,7 +54,8 @@ public class LoginApiTest extends AuthApiTest {
     public void testLogin() {
         Login login = new Login();
         login.name("user1");
-        login.password("p1");
+        login.password("password1");
+        login.expire(10080);
         Assert.assertThrows(ServerException.class, () -> {
             loginAPI.login(login);
         }, e -> {
@@ -64,7 +65,7 @@ public class LoginApiTest extends AuthApiTest {
 
         User user1 = new User();
         user1.name("user1");
-        user1.password("p1");
+        user1.password("password1");
         userAPI.create(user1);
 
         LoginResult result = loginAPI.login(login);
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/auth/TargetApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/auth/TargetApiTest.java
index 79070a8e..8697c50d 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/auth/TargetApiTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/auth/TargetApiTest.java
@@ -17,7 +17,7 @@
 
 package org.apache.hugegraph.api.auth;
 
-import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
 import org.apache.hugegraph.exception.ServerException;
@@ -76,12 +76,12 @@ public class TargetApiTest extends AuthApiTest {
         Assert.assertEquals("gremlin", result1.name());
         Assert.assertEquals("hugegraph", result1.graph());
         Assert.assertEquals("127.0.0.1:8080", result1.url());
-        Assert.assertEquals(Arrays.asList(gremlin), result1.resources());
+        Assert.assertEquals(Collections.singletonList(gremlin), result1.resources());
 
         Assert.assertEquals("task", result2.name());
         Assert.assertEquals("hugegraph2", result2.graph());
         Assert.assertEquals("127.0.0.1:8081", result2.url());
-        Assert.assertEquals(Arrays.asList(task), result2.resources());
+        Assert.assertEquals(Collections.singletonList(task), result2.resources());
 
         Assert.assertThrows(ServerException.class, () -> {
             api.create(target1);
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/JaccardSimilarityApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/AdamicAdarAPITest.java
similarity index 67%
copy from hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/JaccardSimilarityApiTest.java
copy to hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/AdamicAdarAPITest.java
index 1b958081..c0595d1f 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/JaccardSimilarityApiTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/AdamicAdarAPITest.java
@@ -17,20 +17,22 @@
 
 package org.apache.hugegraph.api.traverser;
 
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.hugegraph.structure.constant.Direction;
 import org.apache.hugegraph.structure.constant.T;
 import org.apache.hugegraph.structure.graph.Vertex;
-import org.apache.hugegraph.structure.traverser.JaccardSimilarity;
+import org.apache.hugegraph.structure.traverser.Prediction;
 import org.apache.hugegraph.structure.traverser.SingleSourceJaccardSimilarityRequest;
-import org.apache.hugegraph.testutil.Assert;
 import org.junit.BeforeClass;
+import org.junit.Ignore;
 import org.junit.Test;
 
+import org.apache.hugegraph.testutil.Assert;
 import com.google.common.collect.ImmutableSet;
 
-public class JaccardSimilarityApiTest extends TraverserApiTest {
+public class AdamicAdarAPITest extends TraverserApiTest {
 
     @BeforeClass
     public static void initShortestPathGraph() {
@@ -76,69 +78,80 @@ public class JaccardSimilarityApiTest extends TraverserApiTest {
     }
 
     @Test
-    public void testJaccardSimilarity() {
-        double jaccard = jaccardSimilarityAPI.get(1, 2, Direction.BOTH,
-                                                  null, -1);
-        Assert.assertEquals(0.5D, jaccard, Double.MIN_VALUE);
+    public void testAdamicAdar() {
+        Prediction res = adamicAdarAPI.get(1, 2, Direction.BOTH,
+                                       null, -1);
+        double aa = res.getAdamicAdar();
+        Assert.assertEquals(5.7707801635558535D, aa, Double.MIN_VALUE);
     }
 
     @Test
-    public void testJaccardSimilarityWithDirection() {
-        double jaccard = jaccardSimilarityAPI.get(1, 2, Direction.OUT,
-                                                  null, -1);
-        Assert.assertEquals(0.5, jaccard, Double.MIN_VALUE);
-
-        jaccard = jaccardSimilarityAPI.get(1, 2, Direction.IN,
+    public void testJAdamicAdarWithDirection() {
+        Prediction res = adamicAdarAPI.get(1, 2, Direction.OUT,
                                            null, -1);
-        Assert.assertEquals(0.5, jaccard, Double.MIN_VALUE);
+        double aa = res.getAdamicAdar();
+        Assert.assertEquals(0.0D, aa, Double.MIN_VALUE);
+
+        res = adamicAdarAPI.get(4, 8, Direction.OUT, null, -1);
+        aa = res.getAdamicAdar();
+        Assert.assertEquals(0.9102392266268373D, aa, Double.MIN_VALUE);
     }
 
     @Test
-    public void testJaccardSimilarityWithLabel() {
-        double jaccard = jaccardSimilarityAPI.get(1, 2, Direction.BOTH,
-                                                  "link", -1);
-        Assert.assertEquals(0.3333333333333333D, jaccard, Double.MIN_VALUE);
-
-        jaccard = jaccardSimilarityAPI.get(1, 2, Direction.OUT,
-                                           "link", -1);
-        Assert.assertEquals(0.3333333333333333D, jaccard, Double.MIN_VALUE);
-
-        jaccard = jaccardSimilarityAPI.get(1, 2, Direction.IN,
+    public void testAdamicAdarWithLabel() {
+        Prediction res = adamicAdarAPI.get(1, 2, Direction.BOTH,
                                            "link", -1);
-        Assert.assertEquals(0.3333333333333333D, jaccard, Double.MIN_VALUE);
-
-        jaccard = jaccardSimilarityAPI.get(1, 2, Direction.BOTH,
-                                           "relateTo", -1);
-        Assert.assertEquals(1.0D, jaccard, Double.MIN_VALUE);
-
-        jaccard = jaccardSimilarityAPI.get(1, 2, Direction.OUT,
-                                           "relateTo", -1);
-        Assert.assertEquals(1.0D, jaccard, Double.MIN_VALUE);
-
-        jaccard = jaccardSimilarityAPI.get(1, 2, Direction.IN,
-                                           "relateTo", -1);
-        Assert.assertEquals(1.0D, jaccard, Double.MIN_VALUE);
+        double aa = res.getAdamicAdar();
+        Assert.assertEquals(2.8853900817779268D, aa, Double.MIN_VALUE);
+
+        res = adamicAdarAPI.get(1, 2, Direction.OUT,
+                                    "link", -1);
+        aa = res.getAdamicAdar();
+        Assert.assertEquals(0.0D, aa, Double.MIN_VALUE);
+
+        res = adamicAdarAPI.get(4, 7, Direction.BOTH,
+                                    "link", -1);
+        aa = res.getAdamicAdar();
+        Assert.assertEquals(0.7213475204444817D, aa, Double.MIN_VALUE);
+
+        res = adamicAdarAPI.get(1, 2, Direction.BOTH,
+                                    "relateTo", -1);
+        aa = res.getAdamicAdar();
+        Assert.assertEquals(2.8853900817779268D, aa, Double.MIN_VALUE);
+
+        res = adamicAdarAPI.get(1, 2, Direction.OUT,
+                                    "relateTo", -1);
+        aa = res.getAdamicAdar();
+        Assert.assertEquals(0.0D, aa, Double.MIN_VALUE);
+
+        res = adamicAdarAPI.get(1, 2, Direction.IN,
+                                    "relateTo", -1);
+        aa = res.getAdamicAdar();
+        Assert.assertEquals(0.0D, aa, Double.MIN_VALUE);
     }
 
     @Test
-    public void testJaccardSimilarityWithDegree() {
-        double jaccard = jaccardSimilarityAPI.get(1, 2, Direction.OUT,
-                                                  null, 6);
-        Assert.assertEquals(0.5D, jaccard, Double.MIN_VALUE);
-
-        jaccard = jaccardSimilarityAPI.get(1, 2, Direction.OUT,
-                                           null, 1);
-        Assert.assertEquals(1D, jaccard, Double.MIN_VALUE);
+    public void testAdamicAdarWithDegree() {
+        Prediction res = adamicAdarAPI.get(1, 2, Direction.BOTH,
+                                           null, 3);
+        double aa = res.getAdamicAdar();
+        Assert.assertEquals(2.8853900817779268D, aa, Double.MIN_VALUE);
+
+        res = adamicAdarAPI.get(1, 2, Direction.BOTH,
+                                    null, 1);
+        aa = res.getAdamicAdar();
+        Assert.assertEquals(1.4426950408889634D, aa, Double.MIN_VALUE);
     }
 
-    @Test
-    public void testJaccardSimilar() {
+    // Test until support post method in adamic adar
+    @Ignore
+    public void testJAdamicAdar() {
         SingleSourceJaccardSimilarityRequest.Builder builder =
                 SingleSourceJaccardSimilarityRequest.builder();
         builder.vertex(4);
         builder.step().direction(Direction.BOTH);
         SingleSourceJaccardSimilarityRequest request = builder.build();
-        JaccardSimilarity results = jaccardSimilarityAPI.post(request);
+        Map<Object, Double> results = adamicAdarAPI.post(request);
 
         Assert.assertEquals(9, results.size());
         Set<Object> expected = ImmutableSet.of("1", "2", "3", "5", "6",
@@ -156,15 +169,15 @@ public class JaccardSimilarityApiTest extends TraverserApiTest {
         Assert.assertEquals(0.0, results.get("2"));
     }
 
-    @Test
-    public void testJaccardSimilarWithTop() {
+    @Ignore
+    public void testAdamicAdarWithTop() {
         SingleSourceJaccardSimilarityRequest.Builder builder =
                 SingleSourceJaccardSimilarityRequest.builder();
         builder.vertex(4);
         builder.step().direction(Direction.BOTH);
         builder.top(5);
         SingleSourceJaccardSimilarityRequest request = builder.build();
-        JaccardSimilarity results = jaccardSimilarityAPI.post(request);
+        Map<Object, Double> results = adamicAdarAPI.post(request);
 
         Assert.assertEquals(5, results.size());
         Set<Object> expected = ImmutableSet.of("3", "5", "6", "7", "8");
@@ -177,14 +190,14 @@ public class JaccardSimilarityApiTest extends TraverserApiTest {
         Assert.assertEquals(0.5, results.get("8"));
     }
 
-    @Test
-    public void testJaccardSimilarWithLabel() {
+    @Ignore
+    public void testAdamicAdarWithLabelPost() {
         SingleSourceJaccardSimilarityRequest.Builder builder =
                 SingleSourceJaccardSimilarityRequest.builder();
         builder.vertex(4);
         builder.step().direction(Direction.BOTH).labels("link");
         SingleSourceJaccardSimilarityRequest request = builder.build();
-        JaccardSimilarity results = jaccardSimilarityAPI.post(request);
+        Map<Object, Double> results = adamicAdarAPI.post(request);
 
         Assert.assertEquals(7, results.size());
         Set<Object> expected = ImmutableSet.of("3", "7", "8", "9",
@@ -200,14 +213,14 @@ public class JaccardSimilarityApiTest extends TraverserApiTest {
         Assert.assertEquals(0.0, results.get("2"));
     }
 
-    @Test
-    public void testJaccardSimilarWithDirection() {
+    @Ignore
+    public void testAdamicAdarWithDirection() {
         SingleSourceJaccardSimilarityRequest.Builder builder =
                 SingleSourceJaccardSimilarityRequest.builder();
         builder.vertex(4);
         builder.step().direction(Direction.OUT);
         SingleSourceJaccardSimilarityRequest request = builder.build();
-        JaccardSimilarity results = jaccardSimilarityAPI.post(request);
+        Map<Object, Double> results = adamicAdarAPI.post(request);
 
         Assert.assertEquals(6, results.size());
         Set<Object> expected = ImmutableSet.of("1", "2", "3",
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/AllShortestPathsApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/AllShortestPathsApiTest.java
index b3dac5eb..4c43c380 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/AllShortestPathsApiTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/AllShortestPathsApiTest.java
@@ -24,6 +24,7 @@ import org.apache.hugegraph.structure.constant.Direction;
 import org.apache.hugegraph.structure.constant.T;
 import org.apache.hugegraph.structure.graph.Path;
 import org.apache.hugegraph.structure.graph.Vertex;
+import org.apache.hugegraph.structure.traverser.PathWithMeasure;
 import org.apache.hugegraph.testutil.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -123,8 +124,10 @@ public class AllShortestPathsApiTest extends TraverserApiTest {
 
     @Test
     public void testAllShortestPath() {
-        List<Path> paths = allShortestPathsAPI.get(1, 6, Direction.BOTH,
-                                                   null, 6, -1L, 0L, -1L);
+        PathWithMeasure res = allShortestPathsAPI.get(1, 6,
+                                                      Direction.BOTH, null,
+                                                      6, -1L, 0L, -1L);
+        List<Path> paths = res.getPaths();
         Assert.assertEquals(4, paths.size());
         List<List<Object>> expected = ImmutableList.of(
                 ImmutableList.of(1, 10, 11, 6),
@@ -139,9 +142,10 @@ public class AllShortestPathsApiTest extends TraverserApiTest {
 
     @Test
     public void testAllShortestPathWithLabel() {
-        List<Path> paths = allShortestPathsAPI.get(1, 6, Direction.BOTH,
-                                                   "link", 6, -1L, 0L,
-                                                   -1L);
+        PathWithMeasure res = allShortestPathsAPI.get(1, 6, Direction.BOTH,
+                                                      "link", 6, -1L, 0L,
+                                                      -1L);
+        List<Path> paths = res.getPaths();
         Assert.assertEquals(4, paths.size());
         List<List<Object>> expected = ImmutableList.of(
                 ImmutableList.of(1, 10, 11, 6),
@@ -156,8 +160,9 @@ public class AllShortestPathsApiTest extends TraverserApiTest {
 
     @Test
     public void testAllShortestPathWithDegree() {
-        List<Path> paths = allShortestPathsAPI.get(1, 6, Direction.OUT,
-                                                   null, 6, 1L, 0L, -1L);
+        PathWithMeasure res = allShortestPathsAPI.get(1, 6, Direction.OUT,
+                                                      null, 6, 1L, 0L, -1L);
+        List<Path> paths = res.getPaths();
         /*
          * Following results can be guaranteed in RocksDB backend,
          * but different results exist in table type backend(like Cassandra).
@@ -169,8 +174,9 @@ public class AllShortestPathsApiTest extends TraverserApiTest {
 
     @Test
     public void testAllShortestPathWithCapacity() {
-        List<Path> paths = allShortestPathsAPI.get(1, 6, Direction.BOTH,
-                                                   null, 6, -1L, 0L, -1L);
+        PathWithMeasure res = allShortestPathsAPI.get(1, 6, Direction.BOTH,
+                                                      null, 6, -1L, 0L, -1L);
+        List<Path> paths = res.getPaths();
         Assert.assertEquals(4, paths.size());
         List<List<Object>> expected = ImmutableList.of(
                 ImmutableList.of(1, 10, 11, 6),
@@ -192,14 +198,16 @@ public class AllShortestPathsApiTest extends TraverserApiTest {
 
     @Test
     public void testAllShortestPathWithMaxDepth() {
-        List<Path> paths = allShortestPathsAPI.get(14, 6, Direction.BOTH,
-                                                   null, 4, 5L, 0L, 19L);
+        PathWithMeasure res = allShortestPathsAPI.get(14, 6, Direction.BOTH,
+                                                      null, 4, 5L, 0L, 19L);
+        List<Path> paths = res.getPaths();
         Assert.assertEquals(1, paths.size());
         Path path = paths.get(0);
         Assert.assertEquals(ImmutableList.of(14, 7, 8, 9, 6), path.objects());
 
-        paths = allShortestPathsAPI.get(14, 6, Direction.BOTH,
-                                        null, 3, 5L, 0L, 19L);
+        res = allShortestPathsAPI.get(14, 6, Direction.BOTH,
+                                      null, 3, 5L, 0L, 19L);
+        paths = res.getPaths();
         Assert.assertEquals(0, paths.size());
     }
 
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/CommonTraverserApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/CommonTraverserApiTest.java
index 766008db..d946c1c6 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/CommonTraverserApiTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/CommonTraverserApiTest.java
@@ -17,8 +17,6 @@
 
 package org.apache.hugegraph.api.traverser;
 
-import static org.apache.hugegraph.structure.constant.Traverser.DEFAULT_PAGE_LIMIT;
-
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -28,6 +26,7 @@ import java.util.stream.Collectors;
 import org.apache.hugegraph.api.BaseApiTest;
 import org.apache.hugegraph.exception.ServerException;
 import org.apache.hugegraph.structure.constant.Direction;
+import org.apache.hugegraph.structure.constant.Traverser;
 import org.apache.hugegraph.structure.graph.Edge;
 import org.apache.hugegraph.structure.graph.Edges;
 import org.apache.hugegraph.structure.graph.Path;
@@ -36,6 +35,7 @@ import org.apache.hugegraph.structure.graph.Vertex;
 import org.apache.hugegraph.structure.graph.Vertices;
 import org.apache.hugegraph.structure.traverser.CrosspointsRequest;
 import org.apache.hugegraph.structure.traverser.CustomizedCrosspoints;
+import org.apache.hugegraph.structure.traverser.PathWithMeasure;
 import org.apache.hugegraph.testutil.Assert;
 import org.apache.hugegraph.testutil.Utils;
 import org.junit.BeforeClass;
@@ -63,8 +63,10 @@ public class CommonTraverserApiTest extends TraverserApiTest {
         Object lopId = getVertexId("software", "name", "lop");
         Object peterId = getVertexId("person", "name", "peter");
 
-        List<Path> paths = crosspointsAPI.get(markoId, peterId, Direction.OUT,
-                                              null, 3, -1L, -1L, 10);
+        PathWithMeasure pathWithMeasure =
+                crosspointsAPI.get(markoId, peterId, Direction.OUT,
+                                   null, 3, -1L, -1L, 10);
+        List<Path> paths = pathWithMeasure.getCrosspoints();
         Assert.assertEquals(2, paths.size());
         Path crosspoint1 = new Path(lopId,
                                     ImmutableList.of(markoId, lopId, peterId));
@@ -183,7 +185,7 @@ public class CommonTraverserApiTest extends TraverserApiTest {
 
     @Test
     public void testScanVertex() {
-        List<Shard> shards = verticesAPI.shards(1 * 1024 * 1024);
+        List<Shard> shards = verticesAPI.shards(1024 * 1024);
         List<Vertex> vertices = new LinkedList<>();
         for (Shard shard : shards) {
             Vertices results = verticesAPI.scan(shard, null, 0L);
@@ -195,12 +197,12 @@ public class CommonTraverserApiTest extends TraverserApiTest {
 
     @Test
     public void testScanVertexInPaging() {
-        List<Shard> shards = verticesAPI.shards(1 * 1024 * 1024);
+        List<Shard> shards = verticesAPI.shards(1024 * 1024);
         List<Vertex> vertices = new LinkedList<>();
         for (Shard shard : shards) {
             String page = "";
             while (page != null) {
-                Vertices results = verticesAPI.scan(shard, page, DEFAULT_PAGE_LIMIT);
+                Vertices results = verticesAPI.scan(shard, page, Traverser.DEFAULT_PAGE_LIMIT);
                 vertices.addAll(ImmutableList.copyOf(results.results()));
                 page = results.page();
             }
@@ -210,7 +212,7 @@ public class CommonTraverserApiTest extends TraverserApiTest {
 
     @Test
     public void testScanVertexInPagingWithNegativeLimit() {
-        List<Shard> shards = verticesAPI.shards(1 * 1024 * 1024);
+        List<Shard> shards = verticesAPI.shards(1024 * 1024);
         for (Shard shard : shards) {
             String page = "";
             Assert.assertThrows(ServerException.class, () -> {
@@ -224,7 +226,7 @@ public class CommonTraverserApiTest extends TraverserApiTest {
     @Test
     public void testScanVertexWithSplitSizeLt1MB() {
         Assert.assertThrows(ServerException.class, () -> {
-            verticesAPI.shards(1 * 1024 * 1024 - 1);
+            verticesAPI.shards(1024 * 1024 - 1);
         }, e -> {
             String expect = "The split-size must be >= 1048576 bytes, " +
                             "but got 1048575";
@@ -234,7 +236,7 @@ public class CommonTraverserApiTest extends TraverserApiTest {
 
     @Test
     public void testScanEdge() {
-        List<Shard> shards = edgesAPI.shards(1 * 1024 * 1024);
+        List<Shard> shards = edgesAPI.shards(1024 * 1024);
         List<Edge> edges = new LinkedList<>();
         for (Shard shard : shards) {
             Edges results = edgesAPI.scan(shard, null, 0L);
@@ -246,12 +248,12 @@ public class CommonTraverserApiTest extends TraverserApiTest {
 
     @Test
     public void testScanEdgeInPaging() {
-        List<Shard> shards = edgesAPI.shards(1 * 1024 * 1024);
+        List<Shard> shards = edgesAPI.shards(1024 * 1024);
         List<Edge> edges = new LinkedList<>();
         for (Shard shard : shards) {
             String page = "";
             while (page != null) {
-                Edges results = edgesAPI.scan(shard, page, DEFAULT_PAGE_LIMIT);
+                Edges results = edgesAPI.scan(shard, page, Traverser.DEFAULT_PAGE_LIMIT);
                 edges.addAll(ImmutableList.copyOf(results.results()));
                 page = results.page();
             }
@@ -261,7 +263,7 @@ public class CommonTraverserApiTest extends TraverserApiTest {
 
     @Test
     public void testScanEdgeInPagingWithNegativeLimit() {
-        List<Shard> shards = edgesAPI.shards(1 * 1024 * 1024);
+        List<Shard> shards = edgesAPI.shards(1024 * 1024);
         for (Shard shard : shards) {
             String page = "";
             Assert.assertThrows(ServerException.class, () -> {
@@ -276,7 +278,7 @@ public class CommonTraverserApiTest extends TraverserApiTest {
     @Test
     public void testScanEdgeWithSplitSizeLt1MB() {
         Assert.assertThrows(ServerException.class, () -> {
-            edgesAPI.shards(1 * 1024 * 1024 - 1);
+            edgesAPI.shards(1024 * 1024 - 1);
         });
     }
 }
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/CountApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/CountApiTest.java
index 50a72158..ee0d6247 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/CountApiTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/CountApiTest.java
@@ -22,6 +22,7 @@ import org.apache.hugegraph.structure.constant.Direction;
 import org.apache.hugegraph.structure.constant.T;
 import org.apache.hugegraph.structure.graph.Vertex;
 import org.apache.hugegraph.structure.traverser.CountRequest;
+import org.apache.hugegraph.structure.traverser.CountResponse;
 import org.apache.hugegraph.testutil.Assert;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
@@ -164,7 +165,8 @@ public class CountApiTest extends TraverserApiTest {
         builder.steps().direction(Direction.OUT);
         CountRequest request = builder.build();
 
-        long count = countAPI.post(request);
+        CountResponse res = countAPI.post(request);
+        long count = res.countMap().get("count").longValue();
         Assert.assertEquals(8L, count);
     }
 
@@ -177,7 +179,8 @@ public class CountApiTest extends TraverserApiTest {
         builder.steps().direction(Direction.OUT);
         CountRequest request = builder.build();
 
-        long count = countAPI.post(request);
+        CountResponse res = countAPI.post(request);
+        long count = res.countMap().get("count").longValue();
         Assert.assertEquals(19L, count);
     }
 
@@ -190,7 +193,8 @@ public class CountApiTest extends TraverserApiTest {
         builder.steps().direction(Direction.OUT);
         CountRequest request = builder.build();
 
-        long count = countAPI.post(request);
+        CountResponse res = countAPI.post(request);
+        long count = res.countMap().get("count").longValue();
         Assert.assertEquals(19L, count);
 
         builder = CountRequest.builder();
@@ -200,7 +204,8 @@ public class CountApiTest extends TraverserApiTest {
         builder.steps().direction(Direction.OUT);
         request = builder.build();
 
-        count = countAPI.post(request);
+        res = countAPI.post(request);
+        count = res.countMap().get("count").longValue();
         Assert.assertEquals(8L, count);
 
         builder = CountRequest.builder();
@@ -210,7 +215,8 @@ public class CountApiTest extends TraverserApiTest {
         builder.steps().direction(Direction.IN);
         request = builder.build();
 
-        count = countAPI.post(request);
+        res = countAPI.post(request);
+        count = res.countMap().get("count").longValue();
         Assert.assertEquals(3L, count);
 
         builder = CountRequest.builder();
@@ -220,7 +226,8 @@ public class CountApiTest extends TraverserApiTest {
         builder.steps().direction(Direction.IN);
         request = builder.build();
 
-        count = countAPI.post(request);
+        res = countAPI.post(request);
+        count = res.countMap().get("count").longValue();
         Assert.assertEquals(8L, count);
     }
 
@@ -236,7 +243,8 @@ public class CountApiTest extends TraverserApiTest {
                .labels(ImmutableList.of("link"));
         CountRequest request = builder.build();
 
-        long count = countAPI.post(request);
+        CountResponse res = countAPI.post(request);
+        long count = res.countMap().get("count").longValue();
         Assert.assertEquals(3L, count);
 
         builder = CountRequest.builder();
@@ -249,7 +257,8 @@ public class CountApiTest extends TraverserApiTest {
                .labels(ImmutableList.of("link"));
         request = builder.build();
 
-        count = countAPI.post(request);
+        res = countAPI.post(request);
+        count = res.countMap().get("count").longValue();
         Assert.assertEquals(8L, count);
     }
 
@@ -269,7 +278,8 @@ public class CountApiTest extends TraverserApiTest {
                .properties("time", "P.lt(\"2020-01-06\")");
         CountRequest request = builder.build();
 
-        long count = countAPI.post(request);
+        CountResponse res = countAPI.post(request);
+        long count = res.countMap().get("count").longValue();
         Assert.assertEquals(1L, count);
 
         builder = CountRequest.builder();
@@ -285,7 +295,8 @@ public class CountApiTest extends TraverserApiTest {
                .properties("time", "P.lt(\"2020-01-06\")");
         request = builder.build();
 
-        count = countAPI.post(request);
+        res = countAPI.post(request);
+        count = res.countMap().get("count").longValue();
         Assert.assertEquals(6L, count);
 
         builder = CountRequest.builder();
@@ -299,7 +310,8 @@ public class CountApiTest extends TraverserApiTest {
                .labels(ImmutableList.of("link"));
         request = builder.build();
 
-        count = countAPI.post(request);
+        res = countAPI.post(request);
+        count = res.countMap().get("count").longValue();
         Assert.assertEquals(1L, count);
 
         builder = CountRequest.builder();
@@ -313,7 +325,8 @@ public class CountApiTest extends TraverserApiTest {
                .labels(ImmutableList.of("link"));
         request = builder.build();
 
-        count = countAPI.post(request);
+        res = countAPI.post(request);
+        count = res.countMap().get("count").longValue();
         Assert.assertEquals(4L, count);
 
         builder = CountRequest.builder();
@@ -327,7 +340,8 @@ public class CountApiTest extends TraverserApiTest {
                .properties("time", "2020-01-07");
         request = builder.build();
 
-        count = countAPI.post(request);
+        res = countAPI.post(request);
+        count = res.countMap().get("count").longValue();
         Assert.assertEquals(1L, count);
     }
 
@@ -340,7 +354,8 @@ public class CountApiTest extends TraverserApiTest {
         builder.steps().direction(Direction.OUT);
         CountRequest request = builder.build();
 
-        long count = countAPI.post(request);
+        CountResponse res = countAPI.post(request);
+        long count = res.countMap().get("count").longValue();
         Assert.assertEquals(8L, count);
 
         builder = CountRequest.builder();
@@ -350,7 +365,8 @@ public class CountApiTest extends TraverserApiTest {
         builder.steps().direction(Direction.OUT);
         request = builder.build();
 
-        count = countAPI.post(request);
+        res = countAPI.post(request);
+        count = res.countMap().get("count").longValue();
         Assert.assertEquals(3L, count);
 
         builder = CountRequest.builder();
@@ -360,7 +376,8 @@ public class CountApiTest extends TraverserApiTest {
         builder.steps().direction(Direction.OUT);
         request = builder.build();
 
-        count = countAPI.post(request);
+        res = countAPI.post(request);
+        count = res.countMap().get("count").longValue();
         Assert.assertEquals(4L, count);
 
         builder = CountRequest.builder();
@@ -370,7 +387,8 @@ public class CountApiTest extends TraverserApiTest {
         builder.steps().direction(Direction.OUT);
         request = builder.build();
 
-        count = countAPI.post(request);
+        res = countAPI.post(request);
+        count = res.countMap().get("count").longValue();
         Assert.assertEquals(7L, count);
     }
 
@@ -383,7 +401,8 @@ public class CountApiTest extends TraverserApiTest {
         builder.steps().direction(Direction.OUT);
         CountRequest request = builder.build();
 
-        long count = countAPI.post(request);
+        CountResponse res = countAPI.post(request);
+        long count = res.countMap().get("count").longValue();
         Assert.assertEquals(8L, count);
 
         builder = CountRequest.builder();
@@ -393,7 +412,8 @@ public class CountApiTest extends TraverserApiTest {
         builder.steps().direction(Direction.OUT);
         request = builder.build();
 
-        count = countAPI.post(request);
+        res = countAPI.post(request);
+        count = res.countMap().get("count").longValue();
         Assert.assertEquals(3L, count);
 
         builder = CountRequest.builder();
@@ -403,7 +423,8 @@ public class CountApiTest extends TraverserApiTest {
         builder.steps().direction(Direction.OUT);
         request = builder.build();
 
-        count = countAPI.post(request);
+        res = countAPI.post(request);
+        count = res.countMap().get("count").longValue();
         Assert.assertEquals(0L, count);
 
         builder = CountRequest.builder();
@@ -412,7 +433,8 @@ public class CountApiTest extends TraverserApiTest {
         builder.steps().direction(Direction.OUT).degree(3).skipDegree(4);
         request = builder.build();
 
-        count = countAPI.post(request);
+        res = countAPI.post(request);
+        count = res.countMap().get("count").longValue();
         Assert.assertEquals(3L, count);
     }
 
@@ -429,8 +451,8 @@ public class CountApiTest extends TraverserApiTest {
         Assert.assertThrows(IllegalArgumentException.class, () -> {
             builder.dedupSize(-5);
         }, e -> {
-            Assert.assertContains("The dedup size must be >= 0 or == -1, but got: ",
-                                  e.getMessage());
+            Assert.assertContains("The dedup size must be >= 0 or == -1, " +
+                                  "but got: ", e.getMessage());
         });
 
         Assert.assertThrows(IllegalArgumentException.class, () -> {
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/FusiformSimilarityApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/FusiformSimilarityApiTest.java
index 82bda4f8..77ed1258 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/FusiformSimilarityApiTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/FusiformSimilarityApiTest.java
@@ -26,10 +26,10 @@ import org.apache.hugegraph.structure.constant.Direction;
 import org.apache.hugegraph.structure.constant.T;
 import org.apache.hugegraph.structure.graph.Vertex;
 import org.apache.hugegraph.structure.traverser.FusiformSimilarity;
-import org.apache.hugegraph.structure.traverser.FusiformSimilarity.Similar;
 import org.apache.hugegraph.structure.traverser.FusiformSimilarityRequest;
 import org.apache.hugegraph.testutil.Assert;
 import org.junit.BeforeClass;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import com.google.common.collect.ImmutableMap;
@@ -151,11 +151,11 @@ public class FusiformSimilarityApiTest extends TraverserApiTest {
 
         FusiformSimilarity results = fusiformSimilarityAPI.post(request);
         Assert.assertEquals(1, results.size());
-        Map.Entry<Object, Set<Similar>> entry = results.first();
+        Map.Entry<Object, Set<FusiformSimilarity.Similar>> entry = results.first();
         Assert.assertEquals(p1, entry.getKey());
         Assert.assertEquals(2, entry.getValue().size());
         Set<Object> expected = ImmutableSet.of(p2, p3);
-        Set<Object> actual = entry.getValue().stream().map(Similar::id)
+        Set<Object> actual = entry.getValue().stream().map(FusiformSimilarity.Similar::id)
                                   .collect(Collectors.toSet());
         Assert.assertEquals(expected, actual);
     }
@@ -234,11 +234,11 @@ public class FusiformSimilarityApiTest extends TraverserApiTest {
 
         FusiformSimilarity results = fusiformSimilarityAPI.post(request);
         Assert.assertEquals(1, results.size());
-        Map.Entry<Object, Set<Similar>> entry = results.first();
+        Map.Entry<Object, Set<FusiformSimilarity.Similar>> entry = results.first();
         Assert.assertEquals(p1, entry.getKey());
         Assert.assertEquals(2, entry.getValue().size());
         Set<Object> expected = ImmutableSet.of(p2, p3);
-        Set<Object> actual = entry.getValue().stream().map(Similar::id)
+        Set<Object> actual = entry.getValue().stream().map(FusiformSimilarity.Similar::id)
                                   .collect(Collectors.toSet());
         Assert.assertEquals(expected, actual);
 
@@ -255,7 +255,7 @@ public class FusiformSimilarityApiTest extends TraverserApiTest {
         Assert.assertEquals(p1, entry.getKey());
         Assert.assertEquals(1, entry.getValue().size());
         expected = ImmutableSet.of(p2);
-        actual = entry.getValue().stream().map(Similar::id)
+        actual = entry.getValue().stream().map(FusiformSimilarity.Similar::id)
                       .collect(Collectors.toSet());
         Assert.assertEquals(expected, actual);
     }
@@ -288,11 +288,11 @@ public class FusiformSimilarityApiTest extends TraverserApiTest {
 
         results = fusiformSimilarityAPI.post(request);
         Assert.assertEquals(1, results.size());
-        Map.Entry<Object, Set<Similar>> entry = results.first();
+        Map.Entry<Object, Set<FusiformSimilarity.Similar>> entry = results.first();
         Assert.assertEquals(p1, entry.getKey());
         Assert.assertEquals(2, entry.getValue().size());
         Set<Object> expected = ImmutableSet.of(p2, p3);
-        Set<Object> actual = entry.getValue().stream().map(Similar::id)
+        Set<Object> actual = entry.getValue().stream().map(FusiformSimilarity.Similar::id)
                                   .collect(Collectors.toSet());
         Assert.assertEquals(expected, actual);
 
@@ -332,11 +332,11 @@ public class FusiformSimilarityApiTest extends TraverserApiTest {
 
         FusiformSimilarity results = fusiformSimilarityAPI.post(request);
         Assert.assertEquals(1, results.size());
-        Map.Entry<Object, Set<Similar>> entry = results.first();
+        Map.Entry<Object, Set<FusiformSimilarity.Similar>> entry = results.first();
         Assert.assertEquals(p1, entry.getKey());
         Assert.assertEquals(2, entry.getValue().size());
         Set<Object> expected = ImmutableSet.of(p2, p3);
-        Set<Object> actual = entry.getValue().stream().map(Similar::id)
+        Set<Object> actual = entry.getValue().stream().map(FusiformSimilarity.Similar::id)
                                   .collect(Collectors.toSet());
         Assert.assertEquals(expected, actual);
 
@@ -353,7 +353,7 @@ public class FusiformSimilarityApiTest extends TraverserApiTest {
         Assert.assertEquals(p1, entry.getKey());
         Assert.assertEquals(1, entry.getValue().size());
         expected = ImmutableSet.of(p2);
-        actual = entry.getValue().stream().map(Similar::id)
+        actual = entry.getValue().stream().map(FusiformSimilarity.Similar::id)
                       .collect(Collectors.toSet());
         Assert.assertEquals(expected, actual);
     }
@@ -374,11 +374,11 @@ public class FusiformSimilarityApiTest extends TraverserApiTest {
 
         FusiformSimilarity results = fusiformSimilarityAPI.post(request);
         Assert.assertEquals(1, results.size());
-        Map.Entry<Object, Set<Similar>> entry = results.first();
+        Map.Entry<Object, Set<FusiformSimilarity.Similar>> entry = results.first();
         Assert.assertEquals(p1, entry.getKey());
         Assert.assertEquals(2, entry.getValue().size());
         Set<Object> expected = ImmutableSet.of(p2, p3);
-        Set<Object> actual = entry.getValue().stream().map(Similar::id)
+        Set<Object> actual = entry.getValue().stream().map(FusiformSimilarity.Similar::id)
                                   .collect(Collectors.toSet());
         Assert.assertEquals(expected, actual);
 
@@ -465,10 +465,10 @@ public class FusiformSimilarityApiTest extends TraverserApiTest {
         FusiformSimilarityRequest request = builder.build();
         FusiformSimilarity results = fusiformSimilarityAPI.post(request);
         Assert.assertEquals(1, results.size());
-        Map.Entry<Object, Set<Similar>> entry = results.first();
+        Map.Entry<Object, Set<FusiformSimilarity.Similar>> entry = results.first();
         Assert.assertEquals(id1, entry.getKey());
         Assert.assertEquals(1, entry.getValue().size());
-        Set<Object> actual = entry.getValue().stream().map(Similar::id)
+        Set<Object> actual = entry.getValue().stream().map(FusiformSimilarity.Similar::id)
                                   .collect(Collectors.toSet());
         Assert.assertEquals(ImmutableSet.of(id3), actual);
     }
@@ -495,10 +495,10 @@ public class FusiformSimilarityApiTest extends TraverserApiTest {
                 p3, ImmutableSet.of(p1, p2)
         );
 
-        for (Map.Entry<Object, Set<Similar>> e : results.similarsMap()
-                                                        .entrySet()) {
+        for (Map.Entry<Object, Set<FusiformSimilarity.Similar>> e : results.similarsMap()
+                                                                           .entrySet()) {
             Object key = e.getKey();
-            Set<Object> actual = e.getValue().stream().map(Similar::id)
+            Set<Object> actual = e.getValue().stream().map(FusiformSimilarity.Similar::id)
                                   .collect(Collectors.toSet());
             Assert.assertEquals(expected.get(key), actual);
         }
@@ -543,16 +543,16 @@ public class FusiformSimilarityApiTest extends TraverserApiTest {
 
         FusiformSimilarity results = fusiformSimilarityAPI.post(request);
         Assert.assertEquals(1, results.size());
-        Map.Entry<Object, Set<Similar>> entry = results.first();
+        Map.Entry<Object, Set<FusiformSimilarity.Similar>> entry = results.first();
         Assert.assertEquals(p1Id, entry.getKey());
 
         Assert.assertEquals(2, entry.getValue().size());
-        Set<Similar> similars = entry.getValue();
+        Set<FusiformSimilarity.Similar> similars = entry.getValue();
         Set<Object> p2Inter = ImmutableSet.of(b2Id, b3Id, b4Id, b5Id,
                                               b6Id, b7Id, b8Id, b9Id);
         Set<Object> p3Inter = ImmutableSet.of(b3Id, b4Id, b5Id, b6Id,
                                               b7Id, b8Id, b9Id);
-        for (Similar similar : similars) {
+        for (FusiformSimilarity.Similar similar : similars) {
             if (similar.id().equals(p2Id)) {
                 Assert.assertEquals(p2Inter, similar.intermediaries());
             } else {
@@ -565,6 +565,67 @@ public class FusiformSimilarityApiTest extends TraverserApiTest {
         Assert.assertEquals(vertices, results.vertices());
     }
 
+    @Test
+    @Ignore
+    public void testFusiformSimilarityWithIntermediaryWithoutVertex() {
+        Vertex p1 = getVertex("person", "name", "p1");
+        Vertex p2 = getVertex("person", "name", "p2");
+        Vertex p3 = getVertex("person", "name", "p3");
+
+        Vertex b2 = getVertex("book", "name", "b2");
+        Vertex b3 = getVertex("book", "name", "b3");
+        Vertex b4 = getVertex("book", "name", "b4");
+        Vertex b5 = getVertex("book", "name", "b5");
+        Vertex b6 = getVertex("book", "name", "b6");
+        Vertex b7 = getVertex("book", "name", "b7");
+        Vertex b8 = getVertex("book", "name", "b8");
+        Vertex b9 = getVertex("book", "name", "b9");
+
+        Object p1Id = p1.id();
+        Object p2Id = p2.id();
+        Object p3Id = p3.id();
+
+        Object b2Id = b2.id();
+        Object b3Id = b3.id();
+        Object b4Id = b4.id();
+        Object b5Id = b5.id();
+        Object b6Id = b6.id();
+        Object b7Id = b7.id();
+        Object b8Id = b8.id();
+        Object b9Id = b9.id();
+
+        FusiformSimilarityRequest.Builder builder =
+                FusiformSimilarityRequest.builder();
+        builder.sources().label("person").property("name", "p1");
+        builder.label("read").direction(Direction.OUT).minNeighbors(8)
+               .alpha(0.75D).groupProperty("city").minGroups(2)
+               .withIntermediary(true).withVertex(false);
+        builder.capacity(-1).limit(-1);
+        FusiformSimilarityRequest request = builder.build();
+
+        FusiformSimilarity results = fusiformSimilarityAPI.post(request);
+        Assert.assertEquals(1, results.size());
+        Map.Entry<Object, Set<FusiformSimilarity.Similar>> entry = results.first();
+        Assert.assertEquals(p1Id, entry.getKey());
+
+        Assert.assertEquals(2, entry.getValue().size());
+        Set<FusiformSimilarity.Similar> similars = entry.getValue();
+        Set<Object> p2Inter = ImmutableSet.of(b2Id, b3Id, b4Id, b5Id,
+                                              b6Id, b7Id, b8Id, b9Id);
+        Set<Object> p3Inter = ImmutableSet.of(b3Id, b4Id, b5Id, b6Id,
+                                              b7Id, b8Id, b9Id);
+        for (FusiformSimilarity.Similar similar : similars) {
+            if (similar.id().equals(p2Id)) {
+                Assert.assertEquals(p2Inter, similar.intermediaries());
+            } else {
+                Assert.assertEquals(p3Id, similar.id());
+                Assert.assertEquals(p3Inter, similar.intermediaries());
+            }
+        }
+        Set<Vertex> vertices = ImmutableSet.of();
+        Assert.assertEquals(vertices, results.vertices());
+    }
+
     @Test
     public void testFusiformSimilarityWithoutIntermediaryWithVertex() {
         Vertex p1 = getVertex("person", "name", "p1");
@@ -582,12 +643,12 @@ public class FusiformSimilarityApiTest extends TraverserApiTest {
 
         FusiformSimilarity results = fusiformSimilarityAPI.post(request);
         Assert.assertEquals(1, results.size());
-        Map.Entry<Object, Set<Similar>> entry = results.first();
+        Map.Entry<Object, Set<FusiformSimilarity.Similar>> entry = results.first();
         Assert.assertEquals(p1.id(), entry.getKey());
 
         Assert.assertEquals(2, entry.getValue().size());
-        Set<Similar> similars = entry.getValue();
-        for (Similar similar : similars) {
+        Set<FusiformSimilarity.Similar> similars = entry.getValue();
+        for (FusiformSimilarity.Similar similar : similars) {
             if (similar.id().equals(p2.id())) {
                 Assert.assertEquals(ImmutableSet.of(),
                                     similar.intermediaries());
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/JaccardSimilarityApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/JaccardSimilarityApiTest.java
index 1b958081..7d0b6901 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/JaccardSimilarityApiTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/JaccardSimilarityApiTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.hugegraph.api.traverser;
 
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.hugegraph.structure.constant.Direction;
@@ -77,57 +78,69 @@ public class JaccardSimilarityApiTest extends TraverserApiTest {
 
     @Test
     public void testJaccardSimilarity() {
-        double jaccard = jaccardSimilarityAPI.get(1, 2, Direction.BOTH,
-                                                  null, -1);
+        JaccardSimilarity res = jaccardSimilarityAPI.get(1, 2,
+                                                         Direction.BOTH,
+                                                         null, -1);
+        double jaccard = (Double) res.getJaccardSimilarity();
         Assert.assertEquals(0.5D, jaccard, Double.MIN_VALUE);
     }
 
     @Test
     public void testJaccardSimilarityWithDirection() {
-        double jaccard = jaccardSimilarityAPI.get(1, 2, Direction.OUT,
-                                                  null, -1);
+        JaccardSimilarity res = jaccardSimilarityAPI.get(1, 2, Direction.OUT,
+                                                      null, -1);
+        double jaccard = (Double) res.getJaccardSimilarity();
         Assert.assertEquals(0.5, jaccard, Double.MIN_VALUE);
 
-        jaccard = jaccardSimilarityAPI.get(1, 2, Direction.IN,
-                                           null, -1);
+        res = jaccardSimilarityAPI.get(1, 2, Direction.IN,
+                                         null, -1);
+        jaccard = (Double) res.getJaccardSimilarity();
         Assert.assertEquals(0.5, jaccard, Double.MIN_VALUE);
     }
 
     @Test
     public void testJaccardSimilarityWithLabel() {
-        double jaccard = jaccardSimilarityAPI.get(1, 2, Direction.BOTH,
+        JaccardSimilarity res = jaccardSimilarityAPI.get(1, 2, Direction.BOTH,
                                                   "link", -1);
+        double jaccard = (Double) res.getJaccardSimilarity();
         Assert.assertEquals(0.3333333333333333D, jaccard, Double.MIN_VALUE);
 
-        jaccard = jaccardSimilarityAPI.get(1, 2, Direction.OUT,
+        res = jaccardSimilarityAPI.get(1, 2, Direction.OUT,
                                            "link", -1);
+        jaccard = (Double) res.getJaccardSimilarity();
         Assert.assertEquals(0.3333333333333333D, jaccard, Double.MIN_VALUE);
 
-        jaccard = jaccardSimilarityAPI.get(1, 2, Direction.IN,
-                                           "link", -1);
+        res = jaccardSimilarityAPI.get(1, 2, Direction.IN,
+                                         "link", -1);
+        jaccard = (Double) res.getJaccardSimilarity();
         Assert.assertEquals(0.3333333333333333D, jaccard, Double.MIN_VALUE);
 
-        jaccard = jaccardSimilarityAPI.get(1, 2, Direction.BOTH,
-                                           "relateTo", -1);
+        res = jaccardSimilarityAPI.get(1, 2, Direction.BOTH,
+                                         "relateTo", -1);
+        jaccard = (Double) res.getJaccardSimilarity();
         Assert.assertEquals(1.0D, jaccard, Double.MIN_VALUE);
 
-        jaccard = jaccardSimilarityAPI.get(1, 2, Direction.OUT,
-                                           "relateTo", -1);
+        res = jaccardSimilarityAPI.get(1, 2, Direction.OUT,
+                                         "relateTo", -1);
+        jaccard = (Double) res.getJaccardSimilarity();
         Assert.assertEquals(1.0D, jaccard, Double.MIN_VALUE);
 
-        jaccard = jaccardSimilarityAPI.get(1, 2, Direction.IN,
-                                           "relateTo", -1);
+        res = jaccardSimilarityAPI.get(1, 2, Direction.IN,
+                                         "relateTo", -1);
+        jaccard = (Double) res.getJaccardSimilarity();
         Assert.assertEquals(1.0D, jaccard, Double.MIN_VALUE);
     }
 
     @Test
     public void testJaccardSimilarityWithDegree() {
-        double jaccard = jaccardSimilarityAPI.get(1, 2, Direction.OUT,
+        JaccardSimilarity res = jaccardSimilarityAPI.get(1, 2, Direction.OUT,
                                                   null, 6);
+        double jaccard = (Double) res.getJaccardSimilarity();
         Assert.assertEquals(0.5D, jaccard, Double.MIN_VALUE);
 
-        jaccard = jaccardSimilarityAPI.get(1, 2, Direction.OUT,
-                                           null, 1);
+        res = jaccardSimilarityAPI.get(1, 2, Direction.OUT,
+                                         null, 1);
+        jaccard = (Double) res.getJaccardSimilarity();
         Assert.assertEquals(1D, jaccard, Double.MIN_VALUE);
     }
 
@@ -138,7 +151,9 @@ public class JaccardSimilarityApiTest extends TraverserApiTest {
         builder.vertex(4);
         builder.step().direction(Direction.BOTH);
         SingleSourceJaccardSimilarityRequest request = builder.build();
-        JaccardSimilarity results = jaccardSimilarityAPI.post(request);
+        JaccardSimilarity res = jaccardSimilarityAPI.post(request);
+        Map<Object, Double> results =
+                (Map<Object, Double>) res.getJaccardSimilarity();
 
         Assert.assertEquals(9, results.size());
         Set<Object> expected = ImmutableSet.of("1", "2", "3", "5", "6",
@@ -164,7 +179,9 @@ public class JaccardSimilarityApiTest extends TraverserApiTest {
         builder.step().direction(Direction.BOTH);
         builder.top(5);
         SingleSourceJaccardSimilarityRequest request = builder.build();
-        JaccardSimilarity results = jaccardSimilarityAPI.post(request);
+        JaccardSimilarity res = jaccardSimilarityAPI.post(request);
+        Map<Object, Double> results =
+                (Map<Object, Double>) res.getJaccardSimilarity();
 
         Assert.assertEquals(5, results.size());
         Set<Object> expected = ImmutableSet.of("3", "5", "6", "7", "8");
@@ -184,7 +201,9 @@ public class JaccardSimilarityApiTest extends TraverserApiTest {
         builder.vertex(4);
         builder.step().direction(Direction.BOTH).labels("link");
         SingleSourceJaccardSimilarityRequest request = builder.build();
-        JaccardSimilarity results = jaccardSimilarityAPI.post(request);
+        JaccardSimilarity res = jaccardSimilarityAPI.post(request);
+        Map<Object, Double> results =
+                (Map<Object, Double>) res.getJaccardSimilarity();
 
         Assert.assertEquals(7, results.size());
         Set<Object> expected = ImmutableSet.of("3", "7", "8", "9",
@@ -207,7 +226,9 @@ public class JaccardSimilarityApiTest extends TraverserApiTest {
         builder.vertex(4);
         builder.step().direction(Direction.OUT);
         SingleSourceJaccardSimilarityRequest request = builder.build();
-        JaccardSimilarity results = jaccardSimilarityAPI.post(request);
+        JaccardSimilarity res = jaccardSimilarityAPI.post(request);
+        Map<Object, Double> results =
+                (Map<Object, Double>) res.getJaccardSimilarity();
 
         Assert.assertEquals(6, results.size());
         Set<Object> expected = ImmutableSet.of("1", "2", "3",
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/KneighborApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/KneighborApiTest.java
index 94ffcb96..227bdb0e 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/KneighborApiTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/KneighborApiTest.java
@@ -17,7 +17,9 @@
 
 package org.apache.hugegraph.api.traverser;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.hugegraph.api.BaseApiTest;
@@ -26,12 +28,12 @@ import org.apache.hugegraph.structure.graph.Path;
 import org.apache.hugegraph.structure.graph.Vertex;
 import org.apache.hugegraph.structure.traverser.Kneighbor;
 import org.apache.hugegraph.structure.traverser.KneighborRequest;
+import org.apache.hugegraph.structure.traverser.Steps;
 import org.apache.hugegraph.testutil.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 
 public class KneighborApiTest extends TraverserApiTest {
@@ -53,8 +55,9 @@ public class KneighborApiTest extends TraverserApiTest {
         long personId = vertexLabelAPI.get("person").id();
         long softwareId = vertexLabelAPI.get("software").id();
 
-        List<Object> vertices = kneighborAPI.get(markoId, Direction.OUT,
-                                                 null, 2, -1L, 100000);
+        Map<String, Object> res = kneighborAPI.get(markoId, Direction.OUT,
+                                                   null, 2, -1L, 100000);
+        List<Object> vertices = (List<Object>) res.get("vertices");
         Assert.assertEquals(4, vertices.size());
         Assert.assertTrue(vertices.contains(softwareId + ":lop"));
         Assert.assertTrue(vertices.contains(softwareId + ":ripple"));
@@ -76,7 +79,6 @@ public class KneighborApiTest extends TraverserApiTest {
         builder.steps().direction(Direction.BOTH);
         builder.maxDepth(1);
         builder.withVertex(true);
-        ;
         KneighborRequest request = builder.build();
 
         Kneighbor kneighborResult = kneighborAPI.post(request);
@@ -273,7 +275,8 @@ public class KneighborApiTest extends TraverserApiTest {
 
         KneighborRequest.Builder builder = KneighborRequest.builder();
         builder.source(markoId);
-        builder.steps().direction(Direction.BOTH).addEStep("created");
+        builder.steps().direction(Direction.BOTH)
+               .edgeSteps(new Steps.StepEntity("created"));
         builder.maxDepth(1);
         builder.withVertex(true);
         KneighborRequest request = builder.build();
@@ -286,7 +289,8 @@ public class KneighborApiTest extends TraverserApiTest {
 
         builder = KneighborRequest.builder();
         builder.source(markoId);
-        builder.steps().direction(Direction.BOTH).addEStep("created");
+        builder.steps().direction(Direction.BOTH)
+               .edgeSteps(new Steps.StepEntity("created"));
         builder.maxDepth(2);
         builder.withVertex(true);
         request = builder.build();
@@ -299,7 +303,8 @@ public class KneighborApiTest extends TraverserApiTest {
 
         builder = KneighborRequest.builder();
         builder.source(markoId);
-        builder.steps().direction(Direction.BOTH).addEStep("knows");
+        builder.steps().direction(Direction.BOTH)
+               .edgeSteps(new Steps.StepEntity("knows"));
         builder.maxDepth(1);
         builder.withVertex(true);
         request = builder.build();
@@ -312,7 +317,8 @@ public class KneighborApiTest extends TraverserApiTest {
 
         builder = KneighborRequest.builder();
         builder.source(markoId);
-        builder.steps().direction(Direction.BOTH).addEStep("knows");
+        builder.steps().direction(Direction.BOTH)
+               .edgeSteps(new Steps.StepEntity("knows"));
         builder.maxDepth(2);
         builder.withVertex(true);
         request = builder.build();
@@ -366,27 +372,30 @@ public class KneighborApiTest extends TraverserApiTest {
         Object joshId = getVertexId("person", "name", "josh");
         Object lopId = getVertexId("software", "name", "lop");
         Object peterId = getVertexId("person", "name", "peter");
+        Object vadasId = getVertexId("person", "name", "vadas");
 
         KneighborRequest.Builder builder = KneighborRequest.builder();
         builder.source(markoId);
-        builder.steps()
-               .direction(Direction.BOTH)
-               .addEStep("created", ImmutableMap.of("date", "P.gt(\"2014-01-01 00:00:00\")"));
+        Map<String, Object> properties = new HashMap<>();
+        properties.put("date", "P.lte(\"2014-01-01 00:00:00\")");
+        builder.steps().direction(Direction.BOTH)
+               .edgeSteps(new Steps.StepEntity("knows", properties));
         builder.maxDepth(1);
         builder.withVertex(true);
         KneighborRequest request = builder.build();
 
         Kneighbor kneighborResult = kneighborAPI.post(request);
 
-        Assert.assertEquals(1, kneighborResult.size());
-        Set<Object> expected = ImmutableSet.of(lopId);
+        Assert.assertEquals(2, kneighborResult.size());
+        Set<Object> expected = ImmutableSet.of(joshId, vadasId);
         Assert.assertEquals(expected, kneighborResult.ids());
 
         builder = KneighborRequest.builder();
         builder.source(markoId);
-        builder.steps()
-               .direction(Direction.BOTH)
-               .addEStep("created", ImmutableMap.of("date", "P.gt(\"2014-01-01 00:00:00\")"));
+        properties = new HashMap<>();
+        properties.put("date", "P.gt(\"2014-01-01 00:00:00\")");
+        builder.steps().direction(Direction.BOTH)
+               .edgeSteps(new Steps.StepEntity("created", properties));
         builder.maxDepth(2);
         builder.withVertex(true);
         request = builder.build();
@@ -399,9 +408,10 @@ public class KneighborApiTest extends TraverserApiTest {
 
         builder = KneighborRequest.builder();
         builder.source(markoId);
-        builder.steps()
-               .direction(Direction.BOTH)
-               .addEStep("created", ImmutableMap.of("date", "P.gt(\"2014-01-01 00:00:00\")"));
+        properties = new HashMap<>();
+        properties.put("date", "P.gt(\"2014-01-01 00:00:00\")");
+        builder.steps().direction(Direction.BOTH)
+               .edgeSteps(new Steps.StepEntity("created", properties));
         builder.maxDepth(3);
         builder.withVertex(true);
         request = builder.build();
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/KoutApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/KoutApiTest.java
index d07bc32f..e05ab1d1 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/KoutApiTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/KoutApiTest.java
@@ -18,6 +18,7 @@
 package org.apache.hugegraph.api.traverser;
 
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.hugegraph.api.BaseApiTest;
@@ -27,6 +28,7 @@ import org.apache.hugegraph.structure.graph.Path;
 import org.apache.hugegraph.structure.graph.Vertex;
 import org.apache.hugegraph.structure.traverser.Kout;
 import org.apache.hugegraph.structure.traverser.KoutRequest;
+import org.apache.hugegraph.structure.traverser.Steps;
 import org.apache.hugegraph.testutil.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -53,8 +55,10 @@ public class KoutApiTest extends TraverserApiTest {
 
         long softwareId = vertexLabelAPI.get("software").id();
 
-        List<Object> vertices = koutAPI.get(markoId, Direction.OUT,
-                                            null, 2, true, -1L, -1L, -1);
+        Map<String, Object> koutRes = koutAPI.get(markoId, Direction.OUT,
+                                                  null, 2, true,
+                                                  -1L, -1L, -1L);
+        List<Object> vertices = (List<Object>) koutRes.get("vertices");
         Assert.assertEquals(1, vertices.size());
         Assert.assertTrue(vertices.contains(softwareId + ":ripple"));
     }
@@ -65,8 +69,9 @@ public class KoutApiTest extends TraverserApiTest {
 
         long softwareId = vertexLabelAPI.get("software").id();
 
-        List<Object> vertices = koutAPI.get(markoId, Direction.OUT, null,
-                                            2, false, -1L, -1L, -1);
+        Map<String, Object> koutRes = koutAPI.get(markoId, Direction.OUT, null,
+                                                  2, false, -1L, -1L, -1L);
+        List<Object> vertices = (List<Object>) koutRes.get("vertices");
         Assert.assertEquals(2, vertices.size());
         Assert.assertTrue(vertices.contains(softwareId + ":lop"));
         Assert.assertTrue(vertices.contains(softwareId + ":ripple"));
@@ -79,8 +84,9 @@ public class KoutApiTest extends TraverserApiTest {
         long personId = vertexLabelAPI.get("person").id();
         long softwareId = vertexLabelAPI.get("software").id();
 
-        List<Object> vertices = koutAPI.get(markoId, Direction.BOTH,
-                                            null, 2, true, -1L, -1L, -1);
+        Map<String, Object> koutRes = koutAPI.get(markoId, Direction.BOTH, null,
+                                                  2, true, -1L, -1L, -1L);
+        List<Object> vertices = (List<Object>) koutRes.get("vertices");
         Assert.assertEquals(2, vertices.size());
         Assert.assertTrue(vertices.contains(personId + ":peter"));
         Assert.assertTrue(vertices.contains(softwareId + ":ripple"));
@@ -93,8 +99,9 @@ public class KoutApiTest extends TraverserApiTest {
         long personId = vertexLabelAPI.get("person").id();
         long softwareId = vertexLabelAPI.get("software").id();
 
-        List<Object> vertices = koutAPI.get(markoId, Direction.BOTH, null,
-                                            2, false, -1L, -1L, -1);
+        Map<String, Object> koutRes = koutAPI.get(markoId, Direction.BOTH, null,
+                                                  2, false, -1L, -1L, -1L);
+        List<Object> vertices = (List<Object>) koutRes.get("vertices");
         Assert.assertEquals(4, vertices.size());
         Assert.assertTrue(vertices.contains(personId + ":josh"));
         Assert.assertTrue(vertices.contains(personId + ":peter"));
@@ -108,7 +115,7 @@ public class KoutApiTest extends TraverserApiTest {
 
         Assert.assertThrows(ServerException.class, () -> {
             koutAPI.get(markoId, Direction.BOTH, null,
-                        2, false, -1L, 1L, 2);
+                        2, false, -1L, 1L, 2L);
         }, e -> {
             String expect = "Capacity can't be less than limit, " +
                             "but got capacity '1' and limit '2'";
@@ -122,7 +129,7 @@ public class KoutApiTest extends TraverserApiTest {
 
         Assert.assertThrows(ServerException.class, () -> {
             koutAPI.get(markoId, Direction.BOTH, null,
-                        2, false, -1L, 1L, -1);
+                        2, false, -1L, 1L, -1L);
         }, e -> {
             String expect = "Capacity can't be less than limit, " +
                             "but got capacity '1' and limit '-1'";
@@ -373,7 +380,8 @@ public class KoutApiTest extends TraverserApiTest {
 
         KoutRequest.Builder builder = KoutRequest.builder();
         builder.source(markoId);
-        builder.steps().direction(Direction.BOTH).addEStep("created");
+        builder.steps().direction(Direction.BOTH)
+               .edgeSteps(new Steps.StepEntity("created"));
         builder.maxDepth(1);
         builder.withVertex(true);
         KoutRequest request = builder.build();
@@ -386,7 +394,8 @@ public class KoutApiTest extends TraverserApiTest {
 
         builder = KoutRequest.builder();
         builder.source(markoId);
-        builder.steps().direction(Direction.BOTH).addEStep("created");
+        builder.steps().direction(Direction.BOTH)
+               .edgeSteps(new Steps.StepEntity("created"));
         builder.maxDepth(2);
         builder.withVertex(true);
         request = builder.build();
@@ -399,7 +408,8 @@ public class KoutApiTest extends TraverserApiTest {
 
         builder = KoutRequest.builder();
         builder.source(markoId);
-        builder.steps().direction(Direction.BOTH).addEStep("knows");
+        builder.steps().direction(Direction.BOTH)
+               .edgeSteps(new Steps.StepEntity("knows"));
         builder.maxDepth(1);
         builder.withVertex(true);
         request = builder.build();
@@ -412,7 +422,8 @@ public class KoutApiTest extends TraverserApiTest {
 
         builder = KoutRequest.builder();
         builder.source(markoId);
-        builder.steps().direction(Direction.BOTH).addEStep("knows");
+        builder.steps().direction(Direction.BOTH)
+               .edgeSteps(new Steps.StepEntity("knows"));
         builder.maxDepth(2);
         builder.withVertex(true);
         request = builder.build();
@@ -434,8 +445,8 @@ public class KoutApiTest extends TraverserApiTest {
         KoutRequest.Builder builder = KoutRequest.builder();
         builder.source(markoId);
         builder.steps().direction(Direction.BOTH)
-               .addEStep("knows")
-               .addEStep("created");
+               .edgeSteps(new Steps.StepEntity("knows"))
+               .edgeSteps(new Steps.StepEntity("created"));
         builder.maxDepth(1);
         builder.withVertex(true);
         KoutRequest request = builder.build();
@@ -449,8 +460,8 @@ public class KoutApiTest extends TraverserApiTest {
         builder = KoutRequest.builder();
         builder.source(markoId);
         builder.steps().direction(Direction.BOTH)
-               .addEStep("knows")
-               .addEStep("created");
+               .edgeSteps(new Steps.StepEntity("knows"))
+               .edgeSteps(new Steps.StepEntity("created"));
         builder.maxDepth(2);
         builder.withVertex(true);
         request = builder.build();
@@ -509,7 +520,9 @@ public class KoutApiTest extends TraverserApiTest {
         builder.source(markoId);
         builder.steps()
                .direction(Direction.BOTH)
-               .addEStep("created", ImmutableMap.of("date", "P.gt(\"2014-01-01 00:00:00\")"));
+               .edgeSteps(new Steps.StepEntity("created", ImmutableMap.of("date", "P.gt(\"2014-01" +
+                                                                                  "-01 00:00:00" +
+                                                                                  "\")")));
         builder.maxDepth(1);
         builder.withVertex(true);
         KoutRequest request = builder.build();
@@ -524,7 +537,9 @@ public class KoutApiTest extends TraverserApiTest {
         builder.source(markoId);
         builder.steps()
                .direction(Direction.BOTH)
-               .addEStep("created", ImmutableMap.of("date", "P.gt(\"2014-01-01 00:00:00\")"));
+               .edgeSteps(new Steps.StepEntity("created", ImmutableMap.of("date", "P.gt(\"2014-01" +
+                                                                                  "-01 00:00:00" +
+                                                                                  "\")")));
 
         builder.maxDepth(2);
         builder.withVertex(true);
@@ -540,7 +555,9 @@ public class KoutApiTest extends TraverserApiTest {
         builder.source(markoId);
         builder.steps()
                .direction(Direction.BOTH)
-               .addEStep("created", ImmutableMap.of("date", "P.gt(\"2014-01-01 00:00:00\")"));
+               .edgeSteps(new Steps.StepEntity("created", ImmutableMap.of("date", "P.gt(\"2014-01" +
+                                                                                  "-01 00:00:00" +
+                                                                                  "\")")));
         builder.maxDepth(3);
         builder.withVertex(true);
         request = builder.build();
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/MultiNodeShortestPathApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/MultiNodeShortestPathApiTest.java
index 20e68f6e..b66add56 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/MultiNodeShortestPathApiTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/MultiNodeShortestPathApiTest.java
@@ -19,7 +19,6 @@ package org.apache.hugegraph.api.traverser;
 
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 import org.apache.hugegraph.api.BaseApiTest;
@@ -74,7 +73,7 @@ public class MultiNodeShortestPathApiTest extends TraverserApiTest {
 
         MultiNodeShortestPathRequest request = builder.build();
         PathsWithVertices pathsWithVertices =
-                          multiNodeShortestPathAPI.post(request);
+                multiNodeShortestPathAPI.post(request);
         List<PathsWithVertices.Paths> paths = pathsWithVertices.paths();
         Assert.assertEquals(15, paths.size());
 
@@ -119,7 +118,7 @@ public class MultiNodeShortestPathApiTest extends TraverserApiTest {
 
         MultiNodeShortestPathRequest request = builder.build();
         PathsWithVertices pathsWithVertices =
-                          multiNodeShortestPathAPI.post(request);
+                multiNodeShortestPathAPI.post(request);
         List<PathsWithVertices.Paths> paths = pathsWithVertices.paths();
         Assert.assertEquals(12, paths.size());
 
@@ -184,7 +183,7 @@ public class MultiNodeShortestPathApiTest extends TraverserApiTest {
 
         MultiNodeShortestPathRequest request = builder.build();
         PathsWithVertices pathsWithVertices =
-                          multiNodeShortestPathAPI.post(request);
+                multiNodeShortestPathAPI.post(request);
         List<PathsWithVertices.Paths> paths = pathsWithVertices.paths();
         Assert.assertEquals(15, paths.size());
 
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/NeighborRankApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/NeighborRankApiTest.java
index 552ae5d4..235ce9b4 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/NeighborRankApiTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/NeighborRankApiTest.java
@@ -28,6 +28,7 @@ import org.apache.hugegraph.structure.constant.Direction;
 import org.apache.hugegraph.structure.constant.T;
 import org.apache.hugegraph.structure.graph.Vertex;
 import org.apache.hugegraph.structure.traverser.Ranks;
+import org.apache.hugegraph.structure.traverser.RanksWithMeasure;
 import org.apache.hugegraph.testutil.Assert;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -138,7 +139,8 @@ public class NeighborRankApiTest extends TraverserApiTest {
         builder.alpha(0.9).capacity(-1);
         NeighborRankAPI.Request request = builder.build();
 
-        List<Ranks> ranks = neighborRankAPI.post(request);
+        RanksWithMeasure res = neighborRankAPI.post(request);
+        List<Ranks> ranks = res.ranks();
         Assert.assertEquals(4, ranks.size());
         Assert.assertEquals(ImmutableMap.of("O", 1.0D), ranks.get(0));
         Assert.assertEquals(ImmutableMap.of("B", 0.4305D, "A", 0.3D, "C", 0.3D),
@@ -169,7 +171,8 @@ public class NeighborRankApiTest extends TraverserApiTest {
         builder.alpha(1.0).capacity(-1);
         NeighborRankAPI.Request request = builder.build();
 
-        List<Ranks> ranks = neighborRankAPI.post(request);
+        RanksWithMeasure res = neighborRankAPI.post(request);
+        List<Ranks> ranks = res.ranks();
         Assert.assertEquals(4, ranks.size());
         Assert.assertEquals(ImmutableMap.of("O", 1.0D), ranks.get(0));
         Assert.assertEquals(ImmutableMap.of("B", 0.5D,
@@ -202,7 +205,8 @@ public class NeighborRankApiTest extends TraverserApiTest {
         builder.alpha(0.9).capacity(-1);
         NeighborRankAPI.Request request = builder.build();
 
-        List<Ranks> ranks = neighborRankAPI.post(request);
+        RanksWithMeasure res = neighborRankAPI.post(request);
+        List<Ranks> ranks = res.ranks();
         Assert.assertEquals(4, ranks.size());
         Assert.assertEquals(ImmutableMap.of("O", 1.0D), ranks.get(0));
         Assert.assertEquals(ImmutableMap.of("A", 0.32625000000000004D,
@@ -227,7 +231,8 @@ public class NeighborRankApiTest extends TraverserApiTest {
         builder.alpha(0.9).capacity(-1);
         NeighborRankAPI.Request request = builder.build();
 
-        List<Ranks> ranks = neighborRankAPI.post(request);
+        RanksWithMeasure res = neighborRankAPI.post(request);
+        List<Ranks> ranks = res.ranks();
         Assert.assertEquals(4, ranks.size());
         Assert.assertEquals(ImmutableMap.of("O", 1.0D), ranks.get(0));
         Assert.assertEquals(ImmutableMap.of("B", 0.36075D,
@@ -260,7 +265,8 @@ public class NeighborRankApiTest extends TraverserApiTest {
         builder.alpha(0.9).capacity(-1);
         NeighborRankAPI.Request request = builder.build();
 
-        List<Ranks> ranks = neighborRankAPI.post(request);
+        RanksWithMeasure res = neighborRankAPI.post(request);
+        List<Ranks> ranks = res.ranks();
         Assert.assertEquals(4, ranks.size());
         Assert.assertEquals(ImmutableMap.of("O", 1.0D), ranks.get(0));
         Assert.assertEquals(ImmutableMap.of("B", 0.4305D, "A", 0.3D),
@@ -285,7 +291,8 @@ public class NeighborRankApiTest extends TraverserApiTest {
         builder.alpha(0.9).capacity(-1);
         NeighborRankAPI.Request request = builder.build();
 
-        List<Ranks> ranks = neighborRankAPI.post(request);
+        RanksWithMeasure res = neighborRankAPI.post(request);
+        List<Ranks> ranks = res.ranks();
         Assert.assertEquals(4, ranks.size());
         Assert.assertEquals(ImmutableMap.of("O", 1.0D), ranks.get(0));
         Assert.assertEquals(ImmutableMap.of("B", 0.855D, "A", 0.45D),
@@ -301,7 +308,8 @@ public class NeighborRankApiTest extends TraverserApiTest {
         builder.alpha(0.9).capacity(-1);
         request = builder.build();
 
-        ranks = neighborRankAPI.post(request);
+        res = neighborRankAPI.post(request);
+        ranks = res.ranks();
         Assert.assertEquals(4, ranks.size());
         Assert.assertEquals(ImmutableMap.of("O", 1.0D), ranks.get(0));
         Assert.assertEquals(ImmutableMap.of("B", 0.6525000000000001D,
@@ -346,7 +354,8 @@ public class NeighborRankApiTest extends TraverserApiTest {
         builder.steps().direction(Direction.BOTH);
         NeighborRankAPI.Request request = builder.build();
 
-        List<Ranks> ranks = neighborRankAPI.post(request);
+        RanksWithMeasure res = neighborRankAPI.post(request);
+        List<Ranks> ranks = res.ranks();
         Assert.assertEquals(2, ranks.size());
         Assert.assertEquals(ImmutableMap.of("isolate", 1.0D), ranks.get(0));
         Assert.assertEquals(ImmutableMap.of(), ranks.get(1));
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/PathsApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/PathsApiTest.java
index fc9057e6..217b36a7 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/PathsApiTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/PathsApiTest.java
@@ -26,6 +26,7 @@ import org.apache.hugegraph.structure.constant.Direction;
 import org.apache.hugegraph.structure.constant.T;
 import org.apache.hugegraph.structure.graph.Path;
 import org.apache.hugegraph.structure.graph.Vertex;
+import org.apache.hugegraph.structure.traverser.PathWithMeasure;
 import org.apache.hugegraph.structure.traverser.PathsRequest;
 import org.apache.hugegraph.structure.traverser.PathsWithVertices;
 import org.apache.hugegraph.testutil.Assert;
@@ -53,9 +54,10 @@ public class PathsApiTest extends TraverserApiTest {
         Object lopId = getVertexId("software", "name", "lop");
         Object rippleId = getVertexId("software", "name", "ripple");
 
-        List<Path> paths = pathsAPI.get(markoId, rippleId, Direction.BOTH,
-                                        null, 3, -1L, -1L, 10);
-        Assert.assertEquals(2, paths.size());
+        PathWithMeasure res = pathsAPI.get(markoId, rippleId, Direction.BOTH,
+                                           null, 3, -1L, -1L, 10);
+        List<Path> paths = res.getPaths();
+                Assert.assertEquals(2, paths.size());
         List<Object> path1 = ImmutableList.of(markoId, joshId, rippleId);
         List<Object> path2 = ImmutableList.of(markoId, lopId, joshId, rippleId);
         List<List<Object>> expectedPaths = ImmutableList.of(path1, path2);
@@ -69,8 +71,9 @@ public class PathsApiTest extends TraverserApiTest {
         Object joshId = getVertexId("person", "name", "josh");
         Object rippleId = getVertexId("software", "name", "ripple");
 
-        List<Path> paths = pathsAPI.get(markoId, rippleId, Direction.BOTH,
-                                        null, 3, -1L, -1L, 1);
+        PathWithMeasure res = pathsAPI.get(markoId, rippleId, Direction.BOTH,
+                                           null, 3, -1L, -1L, 1);
+        List<Path> paths = res.getPaths();
         Assert.assertEquals(1, paths.size());
         List<Object> path1 = ImmutableList.of(markoId, joshId, rippleId);
         Assert.assertEquals(path1, paths.get(0).objects());
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/PersonalRankApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/PersonalRankApiTest.java
index ed5d8eb0..f1dbf9cb 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/PersonalRankApiTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/PersonalRankApiTest.java
@@ -26,6 +26,7 @@ import org.apache.hugegraph.driver.GraphManager;
 import org.apache.hugegraph.driver.SchemaManager;
 import org.apache.hugegraph.structure.constant.T;
 import org.apache.hugegraph.structure.graph.Vertex;
+import org.apache.hugegraph.structure.traverser.RanksWithMeasure;
 import org.apache.hugegraph.testutil.Assert;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -99,7 +100,8 @@ public class PersonalRankApiTest extends TraverserApiTest {
         builder.source("A").label("like").alpha(0.9).maxDepth(50);
         PersonalRankAPI.Request request = builder.build();
 
-        Map<Object, Double> ranks = personalRankAPI.post(request);
+        RanksWithMeasure res = personalRankAPI.post(request);
+        Map<Object, Double> ranks = res.personalRanks();
         Map<Object, Double> expectedRanks = ImmutableMap.of(
                 "B", 0.2065750574989044D,
                 "C", 0.09839507219265439D,
@@ -117,7 +119,8 @@ public class PersonalRankApiTest extends TraverserApiTest {
                .withLabel(PersonalRankAPI.Request.WithLabel.SAME_LABEL);
         PersonalRankAPI.Request request = builder.build();
 
-        Map<Object, Double> ranks = personalRankAPI.post(request);
+        RanksWithMeasure res = personalRankAPI.post(request);
+        Map<Object, Double> ranks = res.personalRanks();
         Map<Object, Double> expectedRanks = ImmutableMap.of(
                 "B", 0.2065750574989044D,
                 "C", 0.09839507219265439D
@@ -129,7 +132,8 @@ public class PersonalRankApiTest extends TraverserApiTest {
                .withLabel(PersonalRankAPI.Request.WithLabel.OTHER_LABEL);
         request = builder.build();
 
-        ranks = personalRankAPI.post(request);
+        res = personalRankAPI.post(request);
+        ranks = res.personalRanks();
         expectedRanks = ImmutableMap.of(
                 "d", 0.08959757100230095D,
                 "b", 0.04589958822642998D
@@ -144,7 +148,8 @@ public class PersonalRankApiTest extends TraverserApiTest {
         builder.source("A").label("like").alpha(1).maxDepth(50);
         PersonalRankAPI.Request request = builder.build();
 
-        Map<Object, Double> ranks = personalRankAPI.post(request);
+        RanksWithMeasure res = personalRankAPI.post(request);
+        Map<Object, Double> ranks = res.personalRanks();
         Map<Object, Double> expectedRanks = ImmutableMap.of(
                 "B", 0.5D,
                 "C", 0.24999999999999956D,
@@ -163,26 +168,30 @@ public class PersonalRankApiTest extends TraverserApiTest {
         PersonalRankAPI.Request request = builder.build();
 
         // Removed root and direct neighbors of root
-        Map<Object, Double> ranks = personalRankAPI.post(request);
+        RanksWithMeasure res = personalRankAPI.post(request);
+        Map<Object, Double> ranks = res.personalRanks();
         assertDoublesEquals(ImmutableMap.of(), ranks);
 
-        builder.source("A").label("like").alpha(0.9).degree(1).maxDepth(3);
+        builder.source("A").label("like").alpha(0.9).degree(1).maxDepth(2);
         request = builder.build();
 
-        ranks = personalRankAPI.post(request);
+        res = personalRankAPI.post(request);
+        ranks = res.personalRanks();
         assertDoublesEquals(ImmutableMap.of(), ranks);
 
         builder.source("A").label("like").alpha(0.9).degree(2).maxDepth(2);
         request = builder.build();
 
-        ranks = personalRankAPI.post(request);
+        res = personalRankAPI.post(request);
+        ranks = res.personalRanks();
         assertDoublesEquals(ImmutableMap.of("B", 0.405D), ranks);
 
-        builder.source("A").label("like").alpha(0.9).degree(2).maxDepth(3);
+        builder.source("A").label("like").alpha(0.9).degree(2).maxDepth(2);
         request = builder.build();
 
-        ranks = personalRankAPI.post(request);
-        Assert.assertEquals(2, ranks.size());
+        res = personalRankAPI.post(request);
+        ranks = res.personalRanks();
+        assertDoublesEquals(ImmutableMap.of("B", 0.405D), ranks);
     }
 
     @Test
@@ -192,7 +201,8 @@ public class PersonalRankApiTest extends TraverserApiTest {
         builder.source("A").label("like").alpha(0.9).limit(3).maxDepth(50);
         PersonalRankAPI.Request request = builder.build();
 
-        Map<Object, Double> ranks = personalRankAPI.post(request);
+        RanksWithMeasure res = personalRankAPI.post(request);
+        Map<Object, Double> ranks = res.personalRanks();
         Map<Object, Double> expectedRanks = ImmutableMap.of(
                 "B", 0.2065750574989044D,
                 "C", 0.09839507219265439D,
@@ -208,7 +218,8 @@ public class PersonalRankApiTest extends TraverserApiTest {
         builder.source("A").label("like").alpha(0.9).maxDepth(20);
         PersonalRankAPI.Request request = builder.build();
 
-        Map<Object, Double> ranks = personalRankAPI.post(request);
+        RanksWithMeasure res = personalRankAPI.post(request);
+        Map<Object, Double> ranks = res.personalRanks();
         Map<Object, Double> expectedRanks = ImmutableMap.of(
                 "B", 0.23414889646372697D,
                 "C", 0.11218194186115384D,
@@ -225,7 +236,8 @@ public class PersonalRankApiTest extends TraverserApiTest {
         builder.source("A").label("like").alpha(0.9).maxDepth(50).sorted(false);
         PersonalRankAPI.Request request = builder.build();
 
-        Map<Object, Double> ranks = personalRankAPI.post(request);
+        RanksWithMeasure res = personalRankAPI.post(request);
+        Map<Object, Double> ranks = res.personalRanks();
         Map<Object, Double> expectedRanks = ImmutableMap.of(
                 "b", 0.04589958822642998D,
                 "B", 0.2065750574989044D,
@@ -245,7 +257,8 @@ public class PersonalRankApiTest extends TraverserApiTest {
         builder.source("isolate").label("like").alpha(0.9).maxDepth(50);
         PersonalRankAPI.Request request = builder.build();
 
-        Map<Object, Double> ranks = personalRankAPI.post(request);
+        RanksWithMeasure res = personalRankAPI.post(request);
+        Map<Object, Double> ranks = res.personalRanks();
         assertDoublesEquals(ImmutableMap.of(), ranks);
 
         graph().removeVertex(isolate.id());
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/RingsRaysApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/RingsRaysApiTest.java
index a5d8656d..cb6181c9 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/RingsRaysApiTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/RingsRaysApiTest.java
@@ -25,6 +25,7 @@ import org.apache.hugegraph.structure.constant.Direction;
 import org.apache.hugegraph.structure.constant.T;
 import org.apache.hugegraph.structure.graph.Path;
 import org.apache.hugegraph.structure.graph.Vertex;
+import org.apache.hugegraph.structure.traverser.PathWithMeasure;
 import org.apache.hugegraph.testutil.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -66,8 +67,9 @@ public class RingsRaysApiTest extends TraverserApiTest {
     @Test
     public void testRings() {
         Object markoId = getVertexId("person", "name", "marko");
-        List<Path> paths = ringsAPI.get(markoId, Direction.BOTH, null,
-                                        2, false, -1L, -1L, -1);
+        PathWithMeasure res = ringsAPI.get(markoId, Direction.BOTH, null,
+                                           2, false, -1L, -1L, -1L);
+        List<Path> paths = res.getRings();
         Assert.assertEquals(0, paths.size());
     }
 
@@ -77,8 +79,9 @@ public class RingsRaysApiTest extends TraverserApiTest {
         Object joshId = getVertexId("person", "name", "josh");
         Object lopId = getVertexId("software", "name", "lop");
 
-        List<Path> paths = ringsAPI.get(markoId, Direction.BOTH, null,
-                                        3, false, -1L, -1L, 1);
+        PathWithMeasure res = ringsAPI.get(markoId, Direction.BOTH, null,
+                                        3, false, -1L, -1L, 1L);
+        List<Path> paths = res.getRings();
         Assert.assertEquals(1, paths.size());
         List<Object> path1 = ImmutableList.of(markoId, joshId, lopId, markoId);
         List<Object> path2 = ImmutableList.of(markoId, lopId, joshId, markoId);
@@ -92,16 +95,19 @@ public class RingsRaysApiTest extends TraverserApiTest {
         Object joshId = getVertexId("person", "name", "josh");
         Object lopId = getVertexId("software", "name", "lop");
 
-        List<Path> paths = ringsAPI.get(markoId, Direction.BOTH, null,
-                                        1, false, -1L, -1L, -1);
+        PathWithMeasure res = ringsAPI.get(markoId, Direction.BOTH, null,
+                                        1, false, -1L, -1L, -1L);
+        List<Path> paths = res.getRings();
         Assert.assertEquals(0, paths.size());
 
-        paths = ringsAPI.get(markoId, Direction.BOTH, null,
-                             2, false, -1L, -1L, -1);
+        res = ringsAPI.get(markoId, Direction.BOTH, null,
+                             2, false, -1L, -1L, -1L);
+        paths = res.getRings();
         Assert.assertEquals(0, paths.size());
 
-        paths = ringsAPI.get(markoId, Direction.BOTH, null,
-                             3, false, -1L, -1L, -1);
+        res = ringsAPI.get(markoId, Direction.BOTH, null,
+                             3, false, -1L, -1L, -1L);
+        paths = res.getRings();
         Assert.assertEquals(1, paths.size());
         List<Object> path1 = ImmutableList.of(markoId, joshId, lopId, markoId);
         List<Object> path2 = ImmutableList.of(markoId, lopId, joshId, markoId);
@@ -115,7 +121,7 @@ public class RingsRaysApiTest extends TraverserApiTest {
 
         Assert.assertThrows(ServerException.class, () -> {
             ringsAPI.get(markoId, Direction.BOTH, null,
-                         2, false, -1L, 1L, -1);
+                         2, false, -1L, 1L, -1L);
         }, e -> {
             String expect = "Exceed capacity '1' while finding rings";
             Assert.assertContains(expect, e.getMessage());
@@ -124,30 +130,34 @@ public class RingsRaysApiTest extends TraverserApiTest {
 
     @Test
     public void testRingsSourceInRing() {
-        List<Path> paths = ringsAPI.get(1, Direction.BOTH, null,
-                                        3, true, -1L, -1L, -1);
+        PathWithMeasure res = ringsAPI.get(1, Direction.BOTH, null,
+                                        3, true, -1L, -1L, -1L);
+        List<Path> paths = res.getRings();
         Assert.assertEquals(1, paths.size());
         List<Object> path1 = ImmutableList.of(1, 3, 2, 1);
         List<Object> path2 = ImmutableList.of(1, 2, 3, 1);
         List<List<Object>> expectedPaths = ImmutableList.of(path1, path2);
         Assert.assertTrue(expectedPaths.contains(paths.get(0).objects()));
 
-        paths = ringsAPI.get(2, Direction.OUT, null,
-                             2, true, -1L, -1L, -1);
+        res = ringsAPI.get(2, Direction.OUT, null,
+                             2, true, -1L, -1L, -1L);
+        paths = res.getRings();
         Assert.assertEquals(1, paths.size());
         List<Object> path3 = ImmutableList.of(2, 3, 2);
         Assert.assertEquals(path3, paths.get(0).objects());
 
-        paths = ringsAPI.get(2, Direction.BOTH, null,
-                             2, true, -1L, -1L, -1);
+        res = ringsAPI.get(2, Direction.BOTH, null,
+                             2, true, -1L, -1L, -1L);
+        paths = res.getRings();
         Assert.assertEquals(1, paths.size());
         Assert.assertEquals(path3, paths.get(0).objects());
     }
 
     @Test
     public void testRingsWithoutSourceInRing() {
-        List<Path> paths = ringsAPI.get(1, Direction.BOTH, null,
-                                        3, false, -1L, -1L, -1);
+        PathWithMeasure res = ringsAPI.get(1, Direction.BOTH, null,
+                                        3, false, -1L, -1L, -1L);
+        List<Path> paths = res.getRings();
         Assert.assertEquals(3, paths.size());
         List<Object> path1 = ImmutableList.of(1, 3, 2, 3);
         List<Object> path2 = ImmutableList.of(1, 3, 2, 1);
@@ -159,8 +169,9 @@ public class RingsRaysApiTest extends TraverserApiTest {
         Assert.assertTrue(expectedPaths.contains(paths.get(1).objects()));
         Assert.assertTrue(expectedPaths.contains(paths.get(2).objects()));
 
-        paths = ringsAPI.get(2, Direction.OUT, null,
-                             3, false, -1L, -1L, -1);
+        res = ringsAPI.get(2, Direction.OUT, null,
+                             3, false, -1L, -1L, -1L);
+        paths = res.getRings();
         Assert.assertEquals(2, paths.size());
         List<Object> path5 = ImmutableList.of(2, 3, 2);
         List<Object> path6 = ImmutableList.of(2, 3, 1, 2);
@@ -168,8 +179,9 @@ public class RingsRaysApiTest extends TraverserApiTest {
         Assert.assertTrue(expectedPaths.contains(paths.get(0).objects()));
         Assert.assertTrue(expectedPaths.contains(paths.get(1).objects()));
 
-        paths = ringsAPI.get(2, Direction.BOTH, null,
-                             3, false, -1L, -1L, -1);
+        res = ringsAPI.get(2, Direction.BOTH, null,
+                             3, false, -1L, -1L, -1L);
+        paths = res.getRings();
         Assert.assertEquals(2, paths.size());
         List<Object> path7 = ImmutableList.of(2, 3, 1, 2);
         List<Object> path8 = ImmutableList.of(2, 1, 3, 2);
@@ -186,8 +198,9 @@ public class RingsRaysApiTest extends TraverserApiTest {
         Object lopId = getVertexId("software", "name", "lop");
         Object rippleId = getVertexId("software", "name", "ripple");
 
-        List<Path> paths = raysAPI.get(markoId, Direction.OUT, null,
-                                       2, -1L, -1L, -1);
+        PathWithMeasure res = raysAPI.get(markoId, Direction.OUT, null,
+                                       2, -1L, -1L, -1L);
+        List<Path> paths = res.getRays();
         Assert.assertEquals(4, paths.size());
         List<Object> path1 = ImmutableList.of(markoId, lopId);
         List<Object> path2 = ImmutableList.of(markoId, vadasId);
@@ -207,8 +220,9 @@ public class RingsRaysApiTest extends TraverserApiTest {
         Object vadasId = getVertexId("person", "name", "vadas");
         Object lopId = getVertexId("software", "name", "lop");
 
-        List<Path> paths = raysAPI.get(markoId, Direction.OUT, null,
-                                       2, -1L, -1L, 2);
+        PathWithMeasure res = raysAPI.get(markoId, Direction.OUT, null,
+                                       2, -1L, -1L, 2L);
+        List<Path> paths = res.getRays();
         Assert.assertEquals(2, paths.size());
         List<Object> path1 = ImmutableList.of(markoId, lopId);
         List<Object> path2 = ImmutableList.of(markoId, vadasId);
@@ -225,8 +239,9 @@ public class RingsRaysApiTest extends TraverserApiTest {
         Object lopId = getVertexId("software", "name", "lop");
         Object rippleId = getVertexId("software", "name", "ripple");
 
-        List<Path> paths = raysAPI.get(markoId, Direction.OUT, null,
-                                       1, -1L, -1L, -1);
+        PathWithMeasure res = raysAPI.get(markoId, Direction.OUT, null,
+                                       1, -1L, -1L, -1L);
+        List<Path> paths = res.getRays();
         Assert.assertEquals(3, paths.size());
         List<Object> path1 = ImmutableList.of(markoId, lopId);
         List<Object> path2 = ImmutableList.of(markoId, vadasId);
@@ -237,8 +252,9 @@ public class RingsRaysApiTest extends TraverserApiTest {
         Assert.assertTrue(expectedPaths.contains(paths.get(1).objects()));
         Assert.assertTrue(expectedPaths.contains(paths.get(2).objects()));
 
-        paths = raysAPI.get(markoId, Direction.OUT, null,
-                            2, -1L, -1L, -1);
+        res = raysAPI.get(markoId, Direction.OUT, null,
+                            2, -1L, -1L, -1L);
+        paths = res.getRays();
         Assert.assertEquals(4, paths.size());
         List<Object> path4 = ImmutableList.of(markoId, joshId, rippleId);
         List<Object> path5 = ImmutableList.of(markoId, joshId, lopId);
@@ -248,8 +264,9 @@ public class RingsRaysApiTest extends TraverserApiTest {
         Assert.assertTrue(expectedPaths.contains(paths.get(2).objects()));
         Assert.assertTrue(expectedPaths.contains(paths.get(3).objects()));
 
-        paths = raysAPI.get(markoId, Direction.OUT, null,
-                            3, -1L, -1L, -1);
+        res = raysAPI.get(markoId, Direction.OUT, null,
+                            3, -1L, -1L, -1L);
+        paths = res.getRays();
         Assert.assertEquals(4, paths.size());
         Assert.assertTrue(expectedPaths.contains(paths.get(0).objects()));
         Assert.assertTrue(expectedPaths.contains(paths.get(1).objects()));
@@ -263,7 +280,7 @@ public class RingsRaysApiTest extends TraverserApiTest {
 
         Assert.assertThrows(ServerException.class, () -> {
             raysAPI.get(markoId, Direction.OUT, null,
-                        2, -1L, 1L, -1);
+                        2, -1L, 1L, -1L);
         }, e -> {
             String expect = "Exceed capacity '1' while finding rays";
             Assert.assertContains(expect, e.getMessage());
@@ -279,8 +296,9 @@ public class RingsRaysApiTest extends TraverserApiTest {
         Object lopId = getVertexId("software", "name", "lop");
         Object rippleId = getVertexId("software", "name", "ripple");
 
-        List<Path> paths = raysAPI.get(markoId, Direction.BOTH, null,
-                                       1, -1L, -1L, -1);
+        PathWithMeasure res = raysAPI.get(markoId, Direction.BOTH, null,
+                                       1, -1L, -1L, -1L);
+        List<Path> paths = res.getRays();
         Assert.assertEquals(3, paths.size());
         List<Object> path1 = ImmutableList.of(markoId, lopId);
         List<Object> path2 = ImmutableList.of(markoId, vadasId);
@@ -291,8 +309,9 @@ public class RingsRaysApiTest extends TraverserApiTest {
         Assert.assertTrue(expectedPaths.contains(paths.get(1).objects()));
         Assert.assertTrue(expectedPaths.contains(paths.get(2).objects()));
 
-        paths = raysAPI.get(markoId, Direction.BOTH, null,
-                            2, -1L, -1L, -1);
+        res = raysAPI.get(markoId, Direction.BOTH, null,
+                            2, -1L, -1L, -1L);
+        paths = res.getRays();
         Assert.assertEquals(5, paths.size());
         List<Object> path4 = ImmutableList.of(markoId, vadasId);
         List<Object> path5 = ImmutableList.of(markoId, lopId, joshId);
@@ -306,8 +325,9 @@ public class RingsRaysApiTest extends TraverserApiTest {
         Assert.assertTrue(expectedPaths.contains(paths.get(3).objects()));
         Assert.assertTrue(expectedPaths.contains(paths.get(4).objects()));
 
-        paths = raysAPI.get(markoId, Direction.BOTH, null,
-                            3, -1L, -1L, -1);
+        res = raysAPI.get(markoId, Direction.BOTH, null,
+                            3, -1L, -1L, -1L);
+        paths = res.getRays();
         Assert.assertEquals(5, paths.size());
         List<Object> path9 = ImmutableList.of(markoId, vadasId);
         List<Object> path10 = ImmutableList.of(markoId, joshId, rippleId);
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/SameNeighborsApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/SameNeighborsApiTest.java
index 65a631f8..bfd1767b 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/SameNeighborsApiTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/SameNeighborsApiTest.java
@@ -22,6 +22,7 @@ import java.util.List;
 import org.apache.hugegraph.structure.constant.Direction;
 import org.apache.hugegraph.structure.constant.T;
 import org.apache.hugegraph.structure.graph.Vertex;
+import org.apache.hugegraph.structure.traverser.SameNeighbors;
 import org.apache.hugegraph.testutil.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -75,8 +76,10 @@ public class SameNeighborsApiTest extends TraverserApiTest {
 
     @Test
     public void testSameNeighbors() {
-        List<Object> neighbors = sameNeighborsAPI.get(1, 2, Direction.BOTH,
-                                                      null, -1, -1);
+        SameNeighbors res = sameNeighborsAPI.get(1, 2,
+                                                 Direction.BOTH,
+                                                 null, -1, -1L);
+        List<Object> neighbors = res.getSameNeighbors();
         Assert.assertEquals(4, neighbors.size());
 
         Assert.assertTrue(neighbors.containsAll(ImmutableList.of(3, 4, 5, 6)));
@@ -84,14 +87,16 @@ public class SameNeighborsApiTest extends TraverserApiTest {
 
     @Test
     public void testSameNeighborsWithDirection() {
-        List<Object> neighbors = sameNeighborsAPI.get(1, 2, Direction.OUT,
-                                                      null, -1, -1);
+        SameNeighbors res = sameNeighborsAPI.get(1, 2, Direction.OUT,
+                                                      null, -1, -1L);
+        List<Object> neighbors = res.getSameNeighbors();
         Assert.assertEquals(2, neighbors.size());
 
         Assert.assertTrue(neighbors.containsAll(ImmutableList.of(3, 5)));
 
-        neighbors = sameNeighborsAPI.get(1, 2, Direction.IN,
-                                         null, -1, -1);
+        res = sameNeighborsAPI.get(1, 2, Direction.IN,
+                                         null, -1, -1L);
+        neighbors = res.getSameNeighbors();
         Assert.assertEquals(2, neighbors.size());
 
         Assert.assertTrue(neighbors.containsAll(ImmutableList.of(4, 6)));
@@ -99,37 +104,44 @@ public class SameNeighborsApiTest extends TraverserApiTest {
 
     @Test
     public void testSameNeighborsWithLabel() {
-        List<Object> neighbors = sameNeighborsAPI.get(1, 2, Direction.BOTH,
-                                                      "link", -1, -1);
+        SameNeighbors res = sameNeighborsAPI.get(1, 2, Direction.BOTH,
+                                                      "link", -1, -1L);
+        List<Object> neighbors = res.getSameNeighbors();
         Assert.assertEquals(2, neighbors.size());
 
         Assert.assertTrue(neighbors.containsAll(ImmutableList.of(3, 4)));
 
-        neighbors = sameNeighborsAPI.get(1, 2, Direction.OUT, "link", -1, -1);
+        res = sameNeighborsAPI.get(1, 2, Direction.OUT,
+                                         "link", -1, -1L);
+        neighbors = res.getSameNeighbors();
         Assert.assertEquals(1, neighbors.size());
 
         Assert.assertTrue(neighbors.contains(3));
 
-        neighbors = sameNeighborsAPI.get(1, 2, Direction.IN,
-                                         "link", -1, -1);
+        res = sameNeighborsAPI.get(1, 2, Direction.IN,
+                                         "link", -1, -1L);
+        neighbors = res.getSameNeighbors();
         Assert.assertEquals(1, neighbors.size());
 
         Assert.assertTrue(neighbors.contains(4));
 
-        neighbors = sameNeighborsAPI.get(1, 2, Direction.BOTH,
-                                         "relateTo", -1, -1);
+        res = sameNeighborsAPI.get(1, 2, Direction.BOTH,
+                                         "relateTo", -1, -1L);
+        neighbors = res.getSameNeighbors();
         Assert.assertEquals(2, neighbors.size());
 
         Assert.assertTrue(neighbors.containsAll(ImmutableList.of(5, 6)));
 
-        neighbors = sameNeighborsAPI.get(1, 2, Direction.OUT,
-                                         "relateTo", -1, -1);
+        res = sameNeighborsAPI.get(1, 2, Direction.OUT,
+                                         "relateTo", -1, -1L);
+        neighbors = res.getSameNeighbors();
         Assert.assertEquals(1, neighbors.size());
 
         Assert.assertTrue(neighbors.contains(5));
 
-        neighbors = sameNeighborsAPI.get(1, 2, Direction.IN,
-                                         "relateTo", -1, -1);
+        res = sameNeighborsAPI.get(1, 2, Direction.IN,
+                                         "relateTo", -1, -1L);
+        neighbors = res.getSameNeighbors();
         Assert.assertEquals(1, neighbors.size());
 
         Assert.assertTrue(neighbors.contains(6));
@@ -137,14 +149,16 @@ public class SameNeighborsApiTest extends TraverserApiTest {
 
     @Test
     public void testSameNeighborsWithDegree() {
-        List<Object> neighbors = sameNeighborsAPI.get(1, 2, Direction.OUT,
-                                                      null, 6, -1);
+        SameNeighbors res = sameNeighborsAPI.get(1, 2, Direction.OUT,
+                                                      null, 6, -1L);
+        List<Object> neighbors = res.getSameNeighbors();
         Assert.assertEquals(2, neighbors.size());
 
         Assert.assertTrue(neighbors.containsAll(ImmutableList.of(3, 5)));
 
-        neighbors = sameNeighborsAPI.get(1, 2, Direction.OUT,
-                                         null, 1, -1);
+        res = sameNeighborsAPI.get(1, 2, Direction.OUT,
+                                         null, 1, -1L);
+        neighbors = res.getSameNeighbors();
         Assert.assertEquals(1, neighbors.size());
 
         Assert.assertTrue(neighbors.contains(3));
@@ -152,20 +166,23 @@ public class SameNeighborsApiTest extends TraverserApiTest {
 
     @Test
     public void testSameNeighborsWithLimit() {
-        List<Object> neighbors = sameNeighborsAPI.get(1, 2, Direction.BOTH,
-                                                      "link", 6, -1);
+        SameNeighbors res = sameNeighborsAPI.get(1, 2, Direction.BOTH,
+                                                      "link", 6, -1L);
+        List<Object> neighbors = res.getSameNeighbors();
         Assert.assertEquals(2, neighbors.size());
 
         Assert.assertTrue(neighbors.containsAll(ImmutableList.of(3, 4)));
 
-        neighbors = sameNeighborsAPI.get(1, 2, Direction.BOTH,
-                                         "link", 6, 2);
+        res = sameNeighborsAPI.get(1, 2, Direction.BOTH,
+                                         "link", 6, 2L);
+        neighbors = res.getSameNeighbors();
         Assert.assertEquals(2, neighbors.size());
 
         Assert.assertTrue(neighbors.containsAll(ImmutableList.of(3, 4)));
 
-        neighbors = sameNeighborsAPI.get(1, 2, Direction.BOTH,
-                                         "link", 6, 1);
+        res = sameNeighborsAPI.get(1, 2, Direction.BOTH,
+                                         "link", 6, 1L);
+        neighbors = res.getSameNeighbors();
         Assert.assertEquals(1, neighbors.size());
 
         Assert.assertTrue(neighbors.contains(3));
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/SameNeighborsBatchApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/SameNeighborsBatchApiTest.java
new file mode 100644
index 00000000..099729c8
--- /dev/null
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/SameNeighborsBatchApiTest.java
@@ -0,0 +1,331 @@
+/*
+ * 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.hugegraph.api.traverser;
+
+import org.apache.hugegraph.structure.constant.Direction;
+import org.apache.hugegraph.structure.constant.T;
+import org.apache.hugegraph.structure.graph.Vertex;
+import org.apache.hugegraph.structure.traverser.SameNeighborsBatch;
+import org.apache.hugegraph.structure.traverser.SameNeighborsBatchRequest;
+import org.apache.hugegraph.testutil.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class SameNeighborsBatchApiTest extends TraverserApiTest {
+
+    @BeforeClass
+    public static void initShortestPathGraph() {
+        schema().vertexLabel("node")
+                .useCustomizeNumberId()
+                .ifNotExist()
+                .create();
+
+        schema().edgeLabel("link")
+                .sourceLabel("node").targetLabel("node")
+                .ifNotExist()
+                .create();
+        schema().edgeLabel("relateTo")
+                .sourceLabel("node").targetLabel("node")
+                .ifNotExist()
+                .create();
+
+        Vertex v1 = graph().addVertex(T.LABEL, "node", T.ID, 1);
+        Vertex v2 = graph().addVertex(T.LABEL, "node", T.ID, 2);
+        Vertex v3 = graph().addVertex(T.LABEL, "node", T.ID, 3);
+        Vertex v4 = graph().addVertex(T.LABEL, "node", T.ID, 4);
+        Vertex v5 = graph().addVertex(T.LABEL, "node", T.ID, 5);
+        Vertex v6 = graph().addVertex(T.LABEL, "node", T.ID, 6);
+        Vertex v7 = graph().addVertex(T.LABEL, "node", T.ID, 7);
+        Vertex v8 = graph().addVertex(T.LABEL, "node", T.ID, 8);
+        Vertex v9 = graph().addVertex(T.LABEL, "node", T.ID, 9);
+        Vertex v10 = graph().addVertex(T.LABEL, "node", T.ID, 10);
+
+        v1.addEdge("link", v3);
+        v2.addEdge("link", v3);
+        v4.addEdge("link", v1);
+        v4.addEdge("link", v2);
+
+        v1.addEdge("relateTo", v5);
+        v2.addEdge("relateTo", v5);
+        v6.addEdge("relateTo", v1);
+        v6.addEdge("relateTo", v2);
+
+        v1.addEdge("link", v7);
+        v8.addEdge("link", v1);
+        v2.addEdge("link", v9);
+        v10.addEdge("link", v2);
+    }
+
+    @Test
+    public void testSameNeighborsBatchBatch() {
+        SameNeighborsBatchRequest.Builder builder = SameNeighborsBatchRequest.builder();
+        builder.vertex(1, 2);
+        builder.vertex(3, 4);
+        builder.vertex(7, 9);
+        SameNeighborsBatchRequest request = builder.build();
+        SameNeighborsBatch neighbors = sameNeighborsBatchAPI.post(request);
+        Assert.assertEquals(3, neighbors.sameNeighbors.size());
+        Assert.assertEquals(4, neighbors.sameNeighbors.get(0).size());
+        Assert.assertEquals(2, neighbors.sameNeighbors.get(1).size());
+        Assert.assertEquals(0, neighbors.sameNeighbors.get(2).size());
+
+        Assert.assertTrue(neighbors.sameNeighbors.get(0).containsAll(ImmutableList.of(3, 4, 5, 6)));
+        Assert.assertTrue(neighbors.sameNeighbors.get(1).containsAll(ImmutableList.of(1, 2)));
+    }
+
+    @Test
+    public void testSameNeighborsWithDirection() {
+        // OUT
+        SameNeighborsBatchRequest.Builder builder = SameNeighborsBatchRequest.builder();
+        builder.vertex(1, 2);
+        builder.vertex(3, 4);
+        builder.vertex(4, 6);
+        SameNeighborsBatchRequest request = builder.build();
+        builder.direction(Direction.OUT);
+        SameNeighborsBatch neighbors = sameNeighborsBatchAPI.post(request);
+        Assert.assertEquals(3, neighbors.sameNeighbors.size());
+        Assert.assertEquals(2, neighbors.sameNeighbors.get(0).size());
+        Assert.assertEquals(0, neighbors.sameNeighbors.get(1).size());
+        Assert.assertEquals(2, neighbors.sameNeighbors.get(2).size());
+
+        Assert.assertTrue(neighbors.sameNeighbors.get(0).containsAll(ImmutableList.of(3, 5)));
+        Assert.assertTrue(neighbors.sameNeighbors.get(2).containsAll(ImmutableList.of(1, 2)));
+
+        // IN
+        builder = SameNeighborsBatchRequest.builder();
+        builder.vertex(1, 2);
+        builder.vertex(3, 4);
+        builder.vertex(5, 9);
+        request = builder.build();
+        builder.direction(Direction.IN);
+        neighbors = sameNeighborsBatchAPI.post(request);
+        Assert.assertEquals(3, neighbors.sameNeighbors.size());
+        Assert.assertEquals(2, neighbors.sameNeighbors.get(0).size());
+        Assert.assertEquals(0, neighbors.sameNeighbors.get(1).size());
+        Assert.assertEquals(1, neighbors.sameNeighbors.get(2).size());
+
+        Assert.assertTrue(neighbors.sameNeighbors.get(0).containsAll(ImmutableList.of(4, 6)));
+        Assert.assertTrue(neighbors.sameNeighbors.get(2).containsAll(ImmutableList.of(2)));
+    }
+
+    @Test
+    public void testSameNeighborsWithLabel() {
+        SameNeighborsBatchRequest.Builder builder = SameNeighborsBatchRequest.builder();
+        builder.vertex(1, 2);
+        builder.vertex(3, 4);
+        builder.vertex(4, 6);
+        SameNeighborsBatchRequest request = builder.build();
+        builder.direction(Direction.BOTH);
+        builder.label("link");
+        SameNeighborsBatch neighbors = sameNeighborsBatchAPI.post(request);
+        Assert.assertEquals(3, neighbors.sameNeighbors.size());
+        Assert.assertEquals(2, neighbors.sameNeighbors.get(0).size());
+        Assert.assertEquals(2, neighbors.sameNeighbors.get(1).size());
+        Assert.assertEquals(0, neighbors.sameNeighbors.get(2).size());
+
+        Assert.assertTrue(neighbors.sameNeighbors.get(0).containsAll(ImmutableList.of(3, 4)));
+        Assert.assertTrue(neighbors.sameNeighbors.get(1).containsAll(ImmutableList.of(1, 2)));
+
+        builder = SameNeighborsBatchRequest.builder();
+        builder.vertex(1, 2);
+        builder.vertex(3, 4);
+        builder.vertex(4, 8);
+        request = builder.build();
+        builder.direction(Direction.OUT);
+        builder.label("link");
+        neighbors = sameNeighborsBatchAPI.post(request);
+        Assert.assertEquals(3, neighbors.sameNeighbors.size());
+        Assert.assertEquals(1, neighbors.sameNeighbors.get(0).size());
+        Assert.assertEquals(0, neighbors.sameNeighbors.get(1).size());
+        Assert.assertEquals(1, neighbors.sameNeighbors.get(2).size());
+
+        Assert.assertTrue(neighbors.sameNeighbors.get(0).containsAll(ImmutableList.of(3)));
+        Assert.assertTrue(neighbors.sameNeighbors.get(2).containsAll(ImmutableList.of(1)));
+
+        builder = SameNeighborsBatchRequest.builder();
+        builder.vertex(1, 2);
+        builder.vertex(3, 4);
+        builder.vertex(3, 9);
+        request = builder.build();
+        builder.direction(Direction.IN);
+        builder.label("link");
+        neighbors = sameNeighborsBatchAPI.post(request);
+        Assert.assertEquals(3, neighbors.sameNeighbors.size());
+        Assert.assertEquals(1, neighbors.sameNeighbors.get(0).size());
+        Assert.assertEquals(0, neighbors.sameNeighbors.get(1).size());
+        Assert.assertEquals(1, neighbors.sameNeighbors.get(2).size());
+
+        Assert.assertTrue(neighbors.sameNeighbors.get(0).containsAll(ImmutableList.of(4)));
+        Assert.assertTrue(neighbors.sameNeighbors.get(2).containsAll(ImmutableList.of(2)));
+
+        builder = SameNeighborsBatchRequest.builder();
+        builder.vertex(1, 2);
+        builder.vertex(3, 4);
+        builder.vertex(3, 9);
+        request = builder.build();
+        builder.direction(Direction.IN);
+        builder.label("link");
+        neighbors = sameNeighborsBatchAPI.post(request);
+        Assert.assertEquals(3, neighbors.sameNeighbors.size());
+        Assert.assertEquals(1, neighbors.sameNeighbors.get(0).size());
+        Assert.assertEquals(0, neighbors.sameNeighbors.get(1).size());
+        Assert.assertEquals(1, neighbors.sameNeighbors.get(2).size());
+
+        Assert.assertTrue(neighbors.sameNeighbors.get(0).containsAll(ImmutableList.of(4)));
+        Assert.assertTrue(neighbors.sameNeighbors.get(2).containsAll(ImmutableList.of(2)));
+
+        builder = SameNeighborsBatchRequest.builder();
+        builder.vertex(1, 2);
+        builder.vertex(3, 4);
+        builder.vertex(5, 6);
+        request = builder.build();
+        builder.direction(Direction.BOTH);
+        builder.label("relateTo");
+        neighbors = sameNeighborsBatchAPI.post(request);
+        Assert.assertEquals(3, neighbors.sameNeighbors.size());
+        Assert.assertEquals(2, neighbors.sameNeighbors.get(0).size());
+        Assert.assertEquals(0, neighbors.sameNeighbors.get(1).size());
+        Assert.assertEquals(2, neighbors.sameNeighbors.get(2).size());
+
+        Assert.assertTrue(neighbors.sameNeighbors.get(0).containsAll(ImmutableList.of(5, 6)));
+        Assert.assertTrue(neighbors.sameNeighbors.get(2).containsAll(ImmutableList.of(1, 2)));
+
+        builder = SameNeighborsBatchRequest.builder();
+        builder.vertex(1, 2);
+        builder.vertex(3, 4);
+        builder.vertex(5, 6);
+        request = builder.build();
+        builder.direction(Direction.OUT);
+        builder.label("relateTo");
+        neighbors = sameNeighborsBatchAPI.post(request);
+        Assert.assertEquals(3, neighbors.sameNeighbors.size());
+        Assert.assertEquals(1, neighbors.sameNeighbors.get(0).size());
+        Assert.assertEquals(0, neighbors.sameNeighbors.get(1).size());
+        Assert.assertEquals(0, neighbors.sameNeighbors.get(2).size());
+
+        Assert.assertTrue(neighbors.sameNeighbors.get(0).containsAll(ImmutableList.of(5)));
+
+        builder = SameNeighborsBatchRequest.builder();
+        builder.vertex(1, 2);
+        builder.vertex(3, 4);
+        builder.vertex(5, 6);
+        request = builder.build();
+        builder.direction(Direction.IN);
+        builder.label("relateTo");
+        neighbors = sameNeighborsBatchAPI.post(request);
+        Assert.assertEquals(3, neighbors.sameNeighbors.size());
+        Assert.assertEquals(1, neighbors.sameNeighbors.get(0).size());
+        Assert.assertEquals(0, neighbors.sameNeighbors.get(1).size());
+        Assert.assertEquals(0, neighbors.sameNeighbors.get(2).size());
+
+        Assert.assertTrue(neighbors.sameNeighbors.get(0).containsAll(ImmutableList.of(6)));
+    }
+
+    @Test
+    public void testSameNeighborsWithDegree() {
+        SameNeighborsBatchRequest.Builder builder = SameNeighborsBatchRequest.builder();
+        builder.vertex(1, 2);
+        builder.vertex(3, 4);
+        builder.vertex(4, 6);
+        SameNeighborsBatchRequest request = builder.build();
+        builder.direction(Direction.OUT);
+        builder.maxDegree(6L);
+        SameNeighborsBatch neighbors = sameNeighborsBatchAPI.post(request);
+        Assert.assertEquals(3, neighbors.sameNeighbors.size());
+        Assert.assertEquals(2, neighbors.sameNeighbors.get(0).size());
+        Assert.assertEquals(0, neighbors.sameNeighbors.get(1).size());
+        Assert.assertEquals(2, neighbors.sameNeighbors.get(2).size());
+
+        Assert.assertTrue(neighbors.sameNeighbors.get(0).containsAll(ImmutableList.of(3, 5)));
+        Assert.assertTrue(neighbors.sameNeighbors.get(2).containsAll(ImmutableList.of(1, 2)));
+
+        builder = SameNeighborsBatchRequest.builder();
+        builder.vertex(1, 2);
+        builder.vertex(3, 4);
+        builder.vertex(4, 6);
+        request = builder.build();
+        builder.direction(Direction.OUT);
+        builder.maxDegree(1L);
+        neighbors = sameNeighborsBatchAPI.post(request);
+        Assert.assertEquals(3, neighbors.sameNeighbors.size());
+        Assert.assertEquals(1, neighbors.sameNeighbors.get(0).size());
+        Assert.assertEquals(0, neighbors.sameNeighbors.get(1).size());
+        Assert.assertEquals(1, neighbors.sameNeighbors.get(2).size());
+
+        Assert.assertTrue(neighbors.sameNeighbors.get(0).containsAll(ImmutableList.of(3)));
+        Assert.assertTrue(neighbors.sameNeighbors.get(2).containsAll(ImmutableList.of(1)));
+    }
+
+    @Test
+    public void testSameNeighborsWithLimit() {
+        SameNeighborsBatchRequest.Builder builder = SameNeighborsBatchRequest.builder();
+        builder.vertex(1, 2);
+        builder.vertex(3, 4);
+        builder.vertex(4, 6);
+        SameNeighborsBatchRequest request = builder.build();
+        builder.direction(Direction.BOTH);
+        builder.maxDegree(6);
+        builder.label("link");
+        SameNeighborsBatch neighbors = sameNeighborsBatchAPI.post(request);
+        Assert.assertEquals(3, neighbors.sameNeighbors.size());
+        Assert.assertEquals(2, neighbors.sameNeighbors.get(0).size());
+        Assert.assertEquals(2, neighbors.sameNeighbors.get(1).size());
+        Assert.assertEquals(0, neighbors.sameNeighbors.get(2).size());
+
+        Assert.assertTrue(neighbors.sameNeighbors.get(0).containsAll(ImmutableList.of(3, 4)));
+        Assert.assertTrue(neighbors.sameNeighbors.get(1).containsAll(ImmutableList.of(1, 2)));
+
+        builder = SameNeighborsBatchRequest.builder();
+        builder.vertex(1, 2);
+        builder.vertex(3, 4);
+        builder.vertex(4, 6);
+        builder.build();
+        builder.direction(Direction.BOTH);
+        builder.maxDegree(6);
+        builder.label("link");
+        builder.limit(2L);
+        neighbors = sameNeighborsBatchAPI.post(request);
+        Assert.assertEquals(3, neighbors.sameNeighbors.size());
+        Assert.assertEquals(2, neighbors.sameNeighbors.get(0).size());
+        Assert.assertEquals(2, neighbors.sameNeighbors.get(1).size());
+        Assert.assertEquals(0, neighbors.sameNeighbors.get(2).size());
+
+        Assert.assertTrue(neighbors.sameNeighbors.get(0).containsAll(ImmutableList.of(3, 4)));
+        Assert.assertTrue(neighbors.sameNeighbors.get(1).containsAll(ImmutableList.of(1, 2)));
+
+        builder = SameNeighborsBatchRequest.builder();
+        builder.vertex(1, 2);
+        builder.vertex(3, 4);
+        builder.vertex(4, 6);
+        builder.build();
+        builder.direction(Direction.BOTH);
+        builder.maxDegree(6);
+        builder.label("link");
+        builder.limit(1L);
+        neighbors = sameNeighborsBatchAPI.post(request);
+        Assert.assertEquals(3, neighbors.sameNeighbors.size());
+        Assert.assertEquals(2, neighbors.sameNeighbors.get(0).size());
+        Assert.assertEquals(2, neighbors.sameNeighbors.get(1).size());
+        Assert.assertEquals(0, neighbors.sameNeighbors.get(2).size());
+
+        Assert.assertTrue(neighbors.sameNeighbors.get(0).containsAll(ImmutableList.of(3)));
+        Assert.assertTrue(neighbors.sameNeighbors.get(1).containsAll(ImmutableList.of(1)));
+    }
+}
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/ShortestPathApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/ShortestPathApiTest.java
index fc2e37bf..9c23f170 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/ShortestPathApiTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/ShortestPathApiTest.java
@@ -24,6 +24,7 @@ import org.apache.hugegraph.structure.constant.Direction;
 import org.apache.hugegraph.structure.constant.T;
 import org.apache.hugegraph.structure.graph.Path;
 import org.apache.hugegraph.structure.graph.Vertex;
+import org.apache.hugegraph.structure.traverser.PathOfVertices;
 import org.apache.hugegraph.testutil.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -95,24 +96,27 @@ public class ShortestPathApiTest extends TraverserApiTest {
 
     @Test
     public void testShortestPath() {
-        Path path = shortestPathAPI.get(1, 6, Direction.BOTH,
-                                        null, 6, -1L, 0L, -1L);
+        PathOfVertices res = shortestPathAPI.get(1, 6, Direction.BOTH,
+                                                 null, 6, -1L, 0L, -1L);
+        Path path = res.getPath();
         Assert.assertEquals(4, path.size());
         Assert.assertEquals(ImmutableList.of(1, 10, 11, 6), path.objects());
     }
 
     @Test
     public void testShortestPathWithLabel() {
-        Path path = shortestPathAPI.get(1, 6, Direction.BOTH,
+        PathOfVertices res = shortestPathAPI.get(1, 6, Direction.BOTH,
                                         "link", 6, -1L, 0L, -1L);
+        Path path = res.getPath();
         Assert.assertEquals(4, path.size());
         Assert.assertEquals(ImmutableList.of(1, 10, 11, 6), path.objects());
     }
 
     @Test
     public void testShortestPathWithDegree() {
-        Path path = shortestPathAPI.get(1, 6, Direction.OUT,
+        PathOfVertices res = shortestPathAPI.get(1, 6, Direction.OUT,
                                         null, 6, 1L, 0L, -1L);
+        Path path = res.getPath();
         /*
          * Following results can be guaranteed in RocksDB backend,
          * but different results exist in table type backend(like Cassandra).
@@ -123,8 +127,9 @@ public class ShortestPathApiTest extends TraverserApiTest {
 
     @Test
     public void testShortestPathWithCapacity() {
-        Path path = shortestPathAPI.get(14, 6, Direction.BOTH,
+        PathOfVertices res = shortestPathAPI.get(14, 6, Direction.BOTH,
                                         null, 6, 5L, 0L, 19L);
+        Path path = res.getPath();
         Assert.assertEquals(5, path.size());
         Assert.assertEquals(ImmutableList.of(14, 7, 8, 9, 6), path.objects());
 
@@ -138,13 +143,15 @@ public class ShortestPathApiTest extends TraverserApiTest {
 
     @Test
     public void testShortestPathWithMaxDepth() {
-        Path path = shortestPathAPI.get(14, 6, Direction.BOTH,
+        PathOfVertices res = shortestPathAPI.get(14, 6, Direction.BOTH,
                                         null, 4, 5L, 0L, 19L);
+        Path path = res.getPath();
         Assert.assertEquals(5, path.size());
         Assert.assertEquals(ImmutableList.of(14, 7, 8, 9, 6), path.objects());
 
-        path = shortestPathAPI.get(14, 6, Direction.BOTH,
+        res = shortestPathAPI.get(14, 6, Direction.BOTH,
                                    null, 3, 5L, 0L, 19L);
+        path = res.getPath();
         Assert.assertEquals(0, path.size());
     }
 
@@ -158,31 +165,36 @@ public class ShortestPathApiTest extends TraverserApiTest {
         List<Object> path3 = ImmutableList.of(1, 10, 11, 6);
 
         // (skipped degree == degree) > max degree
-        Path path = shortestPathAPI.get(1, 6, Direction.OUT,
+        PathOfVertices res = shortestPathAPI.get(1, 6, Direction.OUT,
                                         null, 5, 6L, 6L, -1L);
+        Path path = res.getPath();
         Assert.assertEquals(4, path.size());
         Assert.assertEquals(path3, path.objects());
 
         // (skipped degree == degree) == max degree
-        path = shortestPathAPI.get(1, 6, Direction.OUT,
+        res = shortestPathAPI.get(1, 6, Direction.OUT,
                                    null, 5, 5L, 5L, -1L);
+        path = res.getPath();
         Assert.assertEquals(5, path.size());
         Assert.assertEquals(path2, path.objects());
 
         // min degree < (skipped degree == degree) == middle degree < max degree
-        path = shortestPathAPI.get(1, 6, Direction.OUT,
+        res = shortestPathAPI.get(1, 6, Direction.OUT,
                                    null, 5, 4L, 4L, -1L);
+        path = res.getPath();
         Assert.assertEquals(6, path.size());
         Assert.assertEquals(path1, path.objects());
 
         // (skipped degree == degree) <= min degree
-        path = shortestPathAPI.get(1, 6, Direction.OUT,
+        res = shortestPathAPI.get(1, 6, Direction.OUT,
                                    null, 5, 3L, 3L, -1L);
+        path = res.getPath();
         Assert.assertEquals(0, path.size());
 
         // Skipped degree > max degree, degree <= min degree
-        path = shortestPathAPI.get(1, 6, Direction.OUT,
+        res = shortestPathAPI.get(1, 6, Direction.OUT,
                                    null, 5, 3L, 6L, -1L);
+        path = res.getPath();
         Assert.assertTrue(path.size() == 4 ||
                           path.size() == 5 ||
                           path.size() == 6);
@@ -190,15 +202,17 @@ public class ShortestPathApiTest extends TraverserApiTest {
         Assert.assertTrue(paths.contains(path.objects()));
 
         // Skipped degree > max degree, min degree < degree < max degree
-        path = shortestPathAPI.get(1, 6, Direction.OUT,
+        res = shortestPathAPI.get(1, 6, Direction.OUT,
                                    null, 5, 4L, 6L, -1L);
+        path = res.getPath();
         Assert.assertTrue(path.size() == 4 || path.size() == 5);
         Assert.assertTrue(path2.equals(path.objects()) ||
                           path3.equals(path.objects()));
 
         // Skipped degree > max degree, degree >= max degree
-        path = shortestPathAPI.get(1, 6, Direction.OUT,
+        res = shortestPathAPI.get(1, 6, Direction.OUT,
                                    null, 5, 5L, 6L, -1L);
+        path = res.getPath();
         Assert.assertEquals(4, path.size());
         Assert.assertEquals(path3, path.objects());
     }
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/TraverserApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/TraverserApiTest.java
index f6ab7715..062795e2 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/TraverserApiTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/TraverserApiTest.java
@@ -23,7 +23,11 @@ import org.junit.BeforeClass;
 public class TraverserApiTest extends BaseApiTest {
 
     protected static SameNeighborsAPI sameNeighborsAPI;
+    protected static SameNeighborsBatchAPI sameNeighborsBatchAPI;
     protected static JaccardSimilarityAPI jaccardSimilarityAPI;
+    protected static AdamicAdarAPI adamicAdarAPI;
+    protected static ResourceAllocationAPI resouceAllocationAPI;
+
     protected static ShortestPathAPI shortestPathAPI;
     protected static AllShortestPathsAPI allShortestPathsAPI;
     protected static SingleSourceShortestPathAPI singleSourceShortestPathAPI;
@@ -55,35 +59,39 @@ public class TraverserApiTest extends BaseApiTest {
     public static void init() {
         BaseApiTest.init();
 
-        sameNeighborsAPI = new SameNeighborsAPI(client, GRAPH);
-        jaccardSimilarityAPI = new JaccardSimilarityAPI(client, GRAPH);
-        shortestPathAPI = new ShortestPathAPI(client, GRAPH);
-        allShortestPathsAPI = new AllShortestPathsAPI(client, GRAPH);
-        singleSourceShortestPathAPI = new SingleSourceShortestPathAPI(client,
+        sameNeighborsAPI = new SameNeighborsAPI(client, GRAPHSPACE, GRAPH);
+        sameNeighborsBatchAPI = new SameNeighborsBatchAPI(client, GRAPHSPACE, GRAPH);
+        jaccardSimilarityAPI = new JaccardSimilarityAPI(client, GRAPHSPACE, GRAPH);
+        adamicAdarAPI = new AdamicAdarAPI(client, GRAPHSPACE, GRAPH);
+        resouceAllocationAPI = new ResourceAllocationAPI(client, GRAPHSPACE, GRAPH);
+
+        shortestPathAPI = new ShortestPathAPI(client, GRAPHSPACE, GRAPH);
+        allShortestPathsAPI = new AllShortestPathsAPI(client, GRAPHSPACE, GRAPH);
+        singleSourceShortestPathAPI = new SingleSourceShortestPathAPI(client, GRAPHSPACE,
                                                                       GRAPH);
-        weightedShortestPathAPI = new WeightedShortestPathAPI(client, GRAPH);
-        multiNodeShortestPathAPI = new MultiNodeShortestPathAPI(client, GRAPH);
-        pathsAPI = new PathsAPI(client, GRAPH);
-        crosspointsAPI = new CrosspointsAPI(client, GRAPH);
-        koutAPI = new KoutAPI(client, GRAPH);
-        kneighborAPI = new KneighborAPI(client, GRAPH);
+        weightedShortestPathAPI = new WeightedShortestPathAPI(client, GRAPHSPACE, GRAPH);
+        multiNodeShortestPathAPI = new MultiNodeShortestPathAPI(client, GRAPHSPACE, GRAPH);
+        pathsAPI = new PathsAPI(client, GRAPHSPACE, GRAPH);
+        crosspointsAPI = new CrosspointsAPI(client, GRAPHSPACE, GRAPH);
+        koutAPI = new KoutAPI(client, GRAPHSPACE, GRAPH);
+        kneighborAPI = new KneighborAPI(client, GRAPHSPACE, GRAPH);
 
-        ringsAPI = new RingsAPI(client, GRAPH);
-        raysAPI = new RaysAPI(client, GRAPH);
+        ringsAPI = new RingsAPI(client, GRAPHSPACE, GRAPH);
+        raysAPI = new RaysAPI(client, GRAPHSPACE, GRAPH);
 
-        countAPI = new CountAPI(client, GRAPH);
+        countAPI = new CountAPI(client, GRAPHSPACE, GRAPH);
 
-        customizedPathsAPI = new CustomizedPathsAPI(client, GRAPH);
-        customizedCrosspointsAPI = new CustomizedCrosspointsAPI(client, GRAPH);
-        fusiformSimilarityAPI = new FusiformSimilarityAPI(client, GRAPH);
-        templatePathsAPI = new TemplatePathsAPI(client, GRAPH);
+        customizedPathsAPI = new CustomizedPathsAPI(client, GRAPHSPACE, GRAPH);
+        customizedCrosspointsAPI = new CustomizedCrosspointsAPI(client, GRAPHSPACE, GRAPH);
+        fusiformSimilarityAPI = new FusiformSimilarityAPI(client, GRAPHSPACE, GRAPH);
+        templatePathsAPI = new TemplatePathsAPI(client, GRAPHSPACE, GRAPH);
 
-        neighborRankAPI = new NeighborRankAPI(client, GRAPH);
-        personalRankAPI = new PersonalRankAPI(client, GRAPH);
+        neighborRankAPI = new NeighborRankAPI(client, GRAPHSPACE, GRAPH);
+        personalRankAPI = new PersonalRankAPI(client, GRAPHSPACE, GRAPH);
 
-        verticesAPI = new VerticesAPI(client, GRAPH);
-        edgesAPI = new EdgesAPI(client, GRAPH);
+        verticesAPI = new VerticesAPI(client, GRAPHSPACE, GRAPH);
+        edgesAPI = new EdgesAPI(client, GRAPHSPACE, GRAPH);
 
-        edgeExistenceAPI = new EdgeExistenceAPI(client, GRAPH);
+        edgeExistenceAPI = new EdgeExistenceAPI(client, GRAPHSPACE, GRAPH);
     }
 }
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/functional/AuthManagerTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/functional/AuthManagerTest.java
index dd1d1881..9f124cdf 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/functional/AuthManagerTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/functional/AuthManagerTest.java
@@ -47,6 +47,7 @@ public class AuthManagerTest extends BaseFuncTest {
     @Override
     @Before
     public void setup() {
+        super.setup();
     }
 
     @Override
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/functional/BatchInsertTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/functional/BatchInsertTest.java
index d869f259..eda01594 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/functional/BatchInsertTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/functional/BatchInsertTest.java
@@ -47,9 +47,10 @@ public class BatchInsertTest extends BaseFuncTest {
 
     @Test
     public void testBatchInsertInOneLoop() {
+        int vertexCount = BATCH_SIZE;
         List<Vertex> vertices = new ArrayList<>(BATCH_SIZE);
         List<Edge> edges = new ArrayList<>(BATCH_SIZE);
-        for (int i = 1; i <= BATCH_SIZE; i++) {
+        for (int i = 1; i <= vertexCount; i++) {
             Vertex vertex1 = new Vertex("person").property("name", "P-" + i)
                                                  .property("age", i);
             Vertex vertex2 = new Vertex("software").property("name", "S-" + i)
@@ -76,9 +77,10 @@ public class BatchInsertTest extends BaseFuncTest {
 
     @Test
     public void testBatchInsertInOneLoopButAddEdgesBeforeVertices() {
+        int vertexCount = BATCH_SIZE;
         List<Vertex> vertices = new ArrayList<>(BATCH_SIZE);
         List<Edge> edges = new ArrayList<>(BATCH_SIZE);
-        for (int i = 1; i <= BATCH_SIZE; i++) {
+        for (int i = 1; i <= vertexCount; i++) {
             Vertex vertex1 = new Vertex("person").property("name", "P-" + i)
                                                  .property("age", i);
             Vertex vertex2 = new Vertex("software").property("name", "S-" + i)
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/functional/EdgeLabelTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/functional/EdgeLabelTest.java
index d78b7a5e..b186dc0f 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/functional/EdgeLabelTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/functional/EdgeLabelTest.java
@@ -42,7 +42,7 @@ public class EdgeLabelTest extends BaseFuncTest {
 
     @After
     public void teardown() throws Exception {
-        clearData();
+        BaseFuncTest.clearData();
     }
 
     @Test
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/functional/GraphManagerTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/functional/GraphManagerTest.java
index 8c7c7abb..eddb2c50 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/functional/GraphManagerTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/functional/GraphManagerTest.java
@@ -42,7 +42,7 @@ public class GraphManagerTest extends BaseFuncTest {
 
     @After
     public void teardown() throws Exception {
-        clearData();
+        BaseFuncTest.clearData();
     }
 
     @Test
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/functional/IndexLabelTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/functional/IndexLabelTest.java
index ab1a5ba0..599d76c8 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/functional/IndexLabelTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/functional/IndexLabelTest.java
@@ -40,7 +40,7 @@ public class IndexLabelTest extends BaseFuncTest {
 
     @After
     public void teardown() throws Exception {
-        clearData();
+        BaseFuncTest.clearData();
     }
 
     @Test
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/functional/PropertyKeyTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/functional/PropertyKeyTest.java
index 32351e10..4e97049b 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/functional/PropertyKeyTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/functional/PropertyKeyTest.java
@@ -36,7 +36,7 @@ public class PropertyKeyTest extends BaseFuncTest {
 
     @Before
     public void setup() {
-
+        super.setup();
     }
 
     @After
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/functional/TraverserManagerTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/functional/TraverserManagerTest.java
index 15c9618e..9fa65e8e 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/functional/TraverserManagerTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/functional/TraverserManagerTest.java
@@ -43,12 +43,12 @@ public class TraverserManagerTest extends BaseFuncTest {
 
     @After
     public void teardown() throws Exception {
-        clearData();
+        BaseFuncTest.clearData();
     }
 
     @Test
     public void testIterateVerticesByShard() {
-        List<Shard> shards = traverser().vertexShards(1 * 1024 * 1024);
+        List<Shard> shards = traverser().vertexShards(1024 * 1024);
         List<Vertex> vertices = new LinkedList<>();
         for (Shard shard : shards) {
             Iterator<Vertex> iter = traverser().iteratorVertices(shard, 1);
@@ -61,7 +61,7 @@ public class TraverserManagerTest extends BaseFuncTest {
 
     @Test
     public void testIterateEdgesByShard() {
-        List<Shard> shards = traverser().edgeShards(1 * 1024 * 1024);
+        List<Shard> shards = traverser().edgeShards(1024 * 1024);
         List<Edge> edges = new LinkedList<>();
         for (Shard shard : shards) {
             Iterator<Edge> iter = traverser().iteratorEdges(shard, 1);
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/functional/VertexLabelTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/functional/VertexLabelTest.java
index b9c51da0..fc3db04e 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/functional/VertexLabelTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/functional/VertexLabelTest.java
@@ -41,7 +41,7 @@ public class VertexLabelTest extends BaseFuncTest {
 
     @After
     public void teardown() throws Exception {
-        clearData();
+        BaseFuncTest.clearData();
     }
 
     @Test
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/functional/VertexTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/functional/VertexTest.java
index 686f63ea..aa5cc884 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/functional/VertexTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/functional/VertexTest.java
@@ -50,7 +50,7 @@ public class VertexTest extends BaseFuncTest {
     @Override
     @After
     public void teardown() throws Exception {
-        clearData();
+        BaseFuncTest.clearData();
     }
 
     @Test
diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/unit/RestResultTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/unit/RestResultTest.java
index 45f8d415..02c0cb4a 100644
--- a/hugegraph-client/src/test/java/org/apache/hugegraph/unit/RestResultTest.java
+++ b/hugegraph-client/src/test/java/org/apache/hugegraph/unit/RestResultTest.java
@@ -101,7 +101,7 @@ public class RestResultTest extends BaseUnitTest {
         Mockito.when(this.mockResponse.body().string()).thenReturn(json);
         RestResult result = new RestResult(this.mockResponse);
         Assert.assertEquals(200, result.status());
-        Assert.assertEquals(result.headers(), new RestHeaders());
+        Assert.assertEquals(new RestHeaders(), result.headers());
 
         PropertyKey propertyKey = result.readObject(PropertyKey.class);
 
@@ -135,7 +135,7 @@ public class RestResultTest extends BaseUnitTest {
         Mockito.when(this.mockResponse.body().string()).thenReturn(json);
         RestResult result = new RestResult(this.mockResponse);
         Assert.assertEquals(200, result.status());
-        Assert.assertEquals(result.headers(), new RestHeaders());
+        Assert.assertEquals(new RestHeaders(), result.headers());
 
         List<PropertyKey> propertyKeys = result.readList("propertykeys", PropertyKey.class);
         Assert.assertEquals(2, propertyKeys.size());
@@ -170,7 +170,7 @@ public class RestResultTest extends BaseUnitTest {
         Mockito.when(this.mockResponse.body().string()).thenReturn(json);
         RestResult result = new RestResult(this.mockResponse);
         Assert.assertEquals(200, result.status());
-        Assert.assertEquals(result.headers(), new RestHeaders());
+        Assert.assertEquals(new RestHeaders(), result.headers());
 
         VertexLabel vertexLabel = result.readObject(VertexLabel.class);
 
diff --git a/hugegraph-dist/scripts/dependency/known-dependencies.txt b/hugegraph-dist/scripts/dependency/known-dependencies.txt
index e610d072..e827c1e8 100644
--- a/hugegraph-dist/scripts/dependency/known-dependencies.txt
+++ b/hugegraph-dist/scripts/dependency/known-dependencies.txt
@@ -1,9 +1,15 @@
+HdrHistogram-2.1.9.jar
+HikariCP-3.2.0.jar
+LatencyUtils-2.0.3.jar
+ST4-4.0.4.jar
 accessors-smart-1.2.jar
 accessors-smart-2.4.2.jar
 aircompressor-0.10.jar
 aircompressor-0.21.jar
+animal-sniffer-annotations-1.19.jar
 annotations-13.0.jar
 annotations-17.0.0.jar
+annotations-4.1.1.4.jar
 ant-1.9.1.jar
 ant-launcher-1.9.1.jar
 antlr-runtime-3.5.2.jar
@@ -26,6 +32,7 @@ commons-beanutils-1.9.4.jar
 commons-cli-1.3.1.jar
 commons-codec-1.15.jar
 commons-collections-3.2.2.jar
+commons-collections4-4.4.jar
 commons-compress-1.21.jar
 commons-configuration-1.10.jar
 commons-configuration2-2.1.1.jar
@@ -56,6 +63,13 @@ findbugs-annotations-1.3.9-1.jar
 flatbuffers-1.2.0-3f79e055.jar
 flatbuffers-java-1.9.0.jar
 groovy-all-2.4.21.jar
+grpc-api-1.39.0.jar
+grpc-context-1.39.0.jar
+grpc-core-1.39.0.jar
+grpc-netty-shaded-1.39.0.jar
+grpc-protobuf-1.39.0.jar
+grpc-protobuf-lite-1.39.0.jar
+grpc-stub-1.39.0.jar
 gson-2.8.9.jar
 guava-30.0-jre.jar
 h2-1.4.199.jar
@@ -75,8 +89,8 @@ hadoop-yarn-client-3.3.1.jar
 hadoop-yarn-common-3.3.1.jar
 hbase-client-2.2.3.jar
 hbase-common-2.2.3.jar
-hbase-hadoop2-compat-2.2.3.jar
 hbase-hadoop-compat-2.2.3.jar
+hbase-hadoop2-compat-2.2.3.jar
 hbase-http-2.2.3.jar
 hbase-mapreduce-2.2.3.jar
 hbase-metrics-2.2.3.jar
@@ -91,9 +105,10 @@ hbase-shaded-miscellaneous-2.2.1.jar
 hbase-shaded-netty-2.2.1.jar
 hbase-shaded-protobuf-2.2.1.jar
 hbase-zookeeper-2.2.3.jar
-HdrHistogram-2.1.9.jar
+hg-pd-client-1.5.0.jar
+hg-pd-common-1.5.0.jar
+hg-pd-grpc-1.5.0.jar
 hibernate-validator-6.0.17.Final.jar
-HikariCP-3.2.0.jar
 hive-classification-3.1.3.jar
 hive-common-3.1.3.jar
 hive-exec-3.1.3.jar
@@ -219,14 +234,13 @@ kotlin-stdlib-jdk7-1.2.71.jar
 kotlin-stdlib-jdk7-1.6.10.jar
 kotlin-stdlib-jdk8-1.2.71.jar
 kotlin-stdlib-jdk8-1.6.10.jar
-LatencyUtils-2.0.3.jar
 leveldbjni-all-1.8.jar
 libthrift-0.9.3.jar
 lightning-csv-8.2.1.jar
 listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
-log4j-1.2.17.jar
 log4j-1.2-api-2.11.2.jar
 log4j-1.2-api-2.17.1.jar
+log4j-1.2.17.jar
 log4j-api-2.18.0.jar
 log4j-core-2.18.0.jar
 log4j-jul-2.11.2.jar
@@ -269,9 +283,12 @@ orc-shims-1.5.8.jar
 orc-shims-1.6.14.jar
 ow2-asm-6.2.jar
 paranamer-2.3.jar
+perfmark-api-0.23.0.jar
 postgresql-42.2.6.jar
 postgresql-42.4.1.jar
+proto-google-common-protos-2.0.1.jar
 protobuf-java-2.5.0.jar
+protobuf-java-3.17.2.jar
 re2j-1.1.jar
 sfm-converter-8.2.1.jar
 sfm-csv-8.2.1.jar
@@ -309,9 +326,8 @@ spring-jdbc-5.1.9.RELEASE.jar
 spring-tx-5.1.9.RELEASE.jar
 spring-web-5.1.9.RELEASE.jar
 spring-webmvc-5.1.9.RELEASE.jar
-ST4-4.0.4.jar
-stax2-api-4.2.1.jar
 stax-api-1.0.1.jar
+stax2-api-4.2.1.jar
 threeten-extra-1.5.0.jar
 token-provider-1.0.1.jar
 tomcat-embed-core-9.0.24.jar
diff --git a/hugegraph-hubble/hubble-be/src/main/java/org/apache/hugegraph/service/algorithm/OltpAlgoService.java b/hugegraph-hubble/hubble-be/src/main/java/org/apache/hugegraph/service/algorithm/OltpAlgoService.java
index 1335c106..a9875352 100644
--- a/hugegraph-hubble/hubble-be/src/main/java/org/apache/hugegraph/service/algorithm/OltpAlgoService.java
+++ b/hugegraph-hubble/hubble-be/src/main/java/org/apache/hugegraph/service/algorithm/OltpAlgoService.java
@@ -67,7 +67,7 @@ public class OltpAlgoService {
         Path result = traverser.shortestPath(body.getSource(), body.getTarget(),
                                              body.getDirection(), body.getLabel(),
                                              body.getMaxDepth(), body.getMaxDegree(),
-                                             body.getSkipDegree(), body.getCapacity());
+                                             body.getSkipDegree(), body.getCapacity()).getPath();
         JsonView jsonView = new JsonView();
         jsonView.setData(result.objects());
         Date createTime = HubbleUtil.nowDate();
diff --git a/hugegraph-loader/src/main/java/org/apache/hugegraph/loader/util/DataTypeUtil.java b/hugegraph-loader/src/main/java/org/apache/hugegraph/loader/util/DataTypeUtil.java
index 0689d4b7..ca1e1791 100644
--- a/hugegraph-loader/src/main/java/org/apache/hugegraph/loader/util/DataTypeUtil.java
+++ b/hugegraph-loader/src/main/java/org/apache/hugegraph/loader/util/DataTypeUtil.java
@@ -165,8 +165,8 @@ public final class DataTypeUtil {
                 break;
             case JDBC:
                 /*
-                 * Warn: it uses system default timezone,
-                 * should we think a better way to compatible differ timezone people?
+                 * Warn: it uses the system default timezone,
+                 * should we think of a better way to compatible differ timezone people?
                  */
                 long timestamp = 0L;
                 if (value instanceof Date) {
diff --git a/pom.xml b/pom.xml
index 53965294..0235df9b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -127,7 +127,7 @@
         <hadoop.version>3.3.1</hadoop.version>
         <zookeeper.version>3.6.2</zookeeper.version>
         <junit.version>4.12</junit.version>
-        <mockito.version>2.8.47</mockito.version>
+        <mockito.version>2.25.1</mockito.version>
         <lombok.version>1.18.8</lombok.version>
         <commons.io.version>2.8.0</commons.io.version>
         <commons.lang3.version>3.9</commons.lang3.version>