private static HttpData convertHttpDataForResponseBody(String responseBody, HttpData data) {
        final byte[] array = data.array();
        try {
            final JsonNode jsonNode = mapper.readValue(array, JsonNode.class);

            // we try to convert lower snake case response body to camel case
            final String lowerCamelCaseResponseBody =
                    CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, responseBody);
            final Iterator<Entry<String, JsonNode>> fields = jsonNode.fields();
            while (fields.hasNext()) {
                final Entry<String, JsonNode> entry = fields.next();
                final String fieldName = entry.getKey();
                final JsonNode responseBodyJsonNode = entry.getValue();
                // try to match field name and response body
                // 1. by default the marshaller would use lowerCamelCase in json field
                // 2. when the marshaller use original name in .proto file when serializing messages
                if (fieldName.equals(lowerCamelCaseResponseBody) ||
                    fieldName.equals(responseBody)) {
                    final byte[] bytes = mapper.writeValueAsBytes(responseBodyJsonNode);
                    return HttpData.wrap(bytes);
                }
            }
            return HttpData.ofUtf8("null");
        } catch (IOException e) {
            logger.warn("Unexpected exception while extracting responseBody '{}' from {}",
                        responseBody, data, e);
            return HttpData.wrap(array);
        }
    }
Creates a new {@link GrpcService} instance from the given {@code delegate}. If it is possible
to support HTTP/JSON to gRPC transcoding, a new {@link HttpJsonTranscodingService} instance
would be returned. Otherwise, the {@code delegate} would be returned.
grpc/src/main/java/com/linecorp/armeria/server/grpc/HttpJsonTranscodingService.java