class PersonalRankAPI extends API {

    private static final Logger LOG = Log.logger(PersonalRankAPI.class);

    private static final double DEFAULT_DIFF = 0.0001;
    private static final double DEFAULT_ALPHA = 0.85;
    private static final int DEFAULT_DEPTH = 5;

    @POST
    @Timed
    @Produces(APPLICATION_JSON_WITH_CHARSET)
    public String personalRank(@Context GraphManager manager,
                               @PathParam("graph") String graph,
                               RankRequest request) {<FILL_FUNCTION_BODY>}

    private static class RankRequest {

        @JsonProperty("source")
        private Object source;
        @JsonProperty("label")
        private String label;
        @JsonProperty("alpha")
        private double alpha = DEFAULT_ALPHA;
        // TODO: used for future enhancement
        @JsonProperty("max_diff")
        private double maxDiff = DEFAULT_DIFF;
        @JsonProperty("max_degree")
        private long maxDegree = Long.parseLong(DEFAULT_MAX_DEGREE);
        @JsonProperty("limit")
        private int limit = Integer.parseInt(DEFAULT_LIMIT);
        @JsonProperty("max_depth")
        private int maxDepth = DEFAULT_DEPTH;
        @JsonProperty("with_label")
        private PersonalRankTraverser.WithLabel withLabel =
                PersonalRankTraverser.WithLabel.BOTH_LABEL;
        @JsonProperty("sorted")
        private boolean sorted = true;

        @Override
        public String toString() {
            return String.format("RankRequest{source=%s,label=%s,alpha=%s," +
                                 "maxDiff=%s,maxDegree=%s,limit=%s," +
                                 "maxDepth=%s,withLabel=%s,sorted=%s}",
                                 this.source, this.label, this.alpha,
                                 this.maxDiff, this.maxDegree, this.limit,
                                 this.maxDepth, this.withLabel, this.sorted);
        }
    }
}

        E.checkArgumentNotNull(request, "The rank request body can't be null");
        E.checkArgument(request.source != null,
                        "The source vertex id of rank request can't be null");
        E.checkArgument(request.label != null,
                        "The edge label of rank request can't be null");
        E.checkArgument(request.alpha > 0 && request.alpha <= 1.0,
                        "The alpha of rank request must be in range (0, 1], " +
                        "but got '%s'", request.alpha);
        E.checkArgument(request.maxDiff > 0 && request.maxDiff <= 1.0,
                        "The max diff of rank request must be in range " +
                        "(0, 1], but got '%s'", request.maxDiff);
        E.checkArgument(request.maxDegree > 0L || request.maxDegree == NO_LIMIT,
                        "The max degree of rank request must be > 0 " +
                        "or == -1, but got: %s", request.maxDegree);
        E.checkArgument(request.limit > 0L || request.limit == NO_LIMIT,
                        "The limit of rank request must be > 0 or == -1, " +
                        "but got: %s", request.limit);
        E.checkArgument(request.maxDepth > 1L &&
                        request.maxDepth <= DEFAULT_MAX_DEPTH,
                        "The max depth of rank request must be " +
                        "in range (1, %s], but got '%s'",
                        DEFAULT_MAX_DEPTH, request.maxDepth);

        LOG.debug("Graph [{}] get personal rank from '{}' with " +
                  "edge label '{}', alpha '{}', maxDegree '{}', " +
                  "max depth '{}' and sorted '{}'",
                  graph, request.source, request.label, request.alpha,
                  request.maxDegree, request.maxDepth, request.sorted);

        Id sourceId = HugeVertex.getIdValue(request.source);
        HugeGraph g = graph(manager, graph);

        PersonalRankTraverser traverser;
        traverser = new PersonalRankTraverser(g, request.alpha, request.maxDegree,
                                              request.maxDepth);
        Map<Id, Double> ranks = traverser.personalRank(sourceId, request.label,
                                                       request.withLabel);
        ranks = HugeTraverser.topN(ranks, request.sorted, request.limit);
        return manager.serializer(g).writeMap(ranks);
    
<methods>public non-sealed void <init>() ,public static boolean checkAndParseAction(java.lang.String) ,public static R commit(org.apache.hugegraph.HugeGraph, Callable<R>) ,public static void commit(org.apache.hugegraph.HugeGraph, java.lang.Runnable) ,public static org.apache.hugegraph.HugeGraph graph(org.apache.hugegraph.core.GraphManager, java.lang.String) ,public static org.apache.hugegraph.HugeGraph graph4admin(org.apache.hugegraph.core.GraphManager, java.lang.String) ,public static java.lang.Object[] properties(Map<java.lang.String,java.lang.Object>) <variables>public static final java.lang.String ACTION_APPEND,public static final java.lang.String ACTION_CLEAR,public static final java.lang.String ACTION_ELIMINATE,public static final java.lang.String APPLICATION_JSON,public static final java.lang.String APPLICATION_JSON_WITH_CHARSET,public static final java.lang.String APPLICATION_TEXT_WITH_CHARSET,public static final java.lang.String CHARSET,private static final Meter EXPECTED_ERROR_METER,private static final Meter ILLEGAL_ARG_ERROR_METER,public static final java.lang.String JSON,protected static final Logger LOG,private static final Meter SUCCEED_METER,public static final java.lang.String TEXT_PLAIN,private static final Meter UNKNOWN_ERROR_METER