private void handleGraphQLRequest(final RoutingContext routingContext) {
    try {
      final String query;
      final String operationName;
      final Map<String, Object> variables;
      final HttpServerRequest request = routingContext.request();

      switch (request.method().name()) {
        case "GET":
          final String queryString = request.getParam("query");
          query = Objects.requireNonNullElse(queryString, "");
          operationName = request.getParam("operationName");
          final String variableString = request.getParam("variables");
          if (variableString != null) {
            variables = JacksonCodec.decodeValue(variableString, MAP_TYPE);
          } else {
            variables = Collections.emptyMap();
          }
          break;
        case "POST":
          final String contentType = request.getHeader(HttpHeaders.CONTENT_TYPE);
          if (contentType != null && MediaType.parse(contentType).is(MEDIA_TYPE_JUST_JSON)) {
            final String requestBody = routingContext.getBodyAsString().trim();
            final GraphQLJsonRequest jsonRequest =
                Json.decodeValue(requestBody, GraphQLJsonRequest.class);
            final String jsonQuery = jsonRequest.getQuery();
            query = Objects.requireNonNullElse(jsonQuery, "");
            operationName = jsonRequest.getOperationName();
            final Map<String, Object> jsonVariables = jsonRequest.getVariables();
            variables = Objects.requireNonNullElse(jsonVariables, Collections.emptyMap());
          } else {
            // treat all else as application/graphql
            final String requestQuery = routingContext.getBodyAsString().trim();
            query = Objects.requireNonNullElse(requestQuery, "");
            operationName = null;
            variables = Collections.emptyMap();
          }
          break;
        default:
          routingContext
              .response()
              .setStatusCode(HttpResponseStatus.METHOD_NOT_ALLOWED.code())
              .end();
          return;
      }

      final HttpServerResponse response = routingContext.response();
      vertx.executeBlocking(
          future -> {
            try {
              final GraphQLResponse graphQLResponse = process(query, operationName, variables);
              future.complete(graphQLResponse);
            } catch (final Exception e) {
              future.fail(e);
            }
          },
          false,
          (res) -> {
            if (response.closed()) {
              return;
            }
            response.putHeader("Content-Type", MediaType.JSON_UTF_8.toString());
            if (res.failed()) {
              response.setStatusCode(HttpResponseStatus.INTERNAL_SERVER_ERROR.code());
              response.end(
                  serialise(
                      new GraphQLErrorResponse(
                          Collections.singletonMap(
                              "errors",
                              Collections.singletonList(
                                  Collections.singletonMap(
                                      "message", res.cause().getMessage()))))));
            } else {
              final GraphQLResponse graphQLResponse = (GraphQLResponse) res.result();
              response.setStatusCode(status(graphQLResponse).code());
              response.end(serialise(graphQLResponse));
            }
          });

    } catch (final DecodeException ex) {
      handleGraphQLError(routingContext, ex);
    }
  }
Returns the URL of the GraphQL HTTP service.

<p>This method constructs and returns the URL that the HTTP server is bound to. If the server
is not running, it returns an empty string.

@return the URL of the HTTP server, or an empty string if the server is not running.
ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLHttpService.java