使用RestTemplate进行GraphQL查询时,要么返回400错误,要么返回无效语法消息。

huangapple go评论68阅读模式
英文:

Call to GraphQL Query with RestTemplate is giving either 400 or invalid syntax message

问题

我一直在尝试使用SpringBoot框架中的RestTemplate调用GraphQL查询时遇到奇怪的问题。我说它奇怪,因为只有这个特定的查询发生了问题。

这是我正在使用的代码(因为这是公司内部的标准):

var queryString = String.format("{ \"query\": \"{ parameterByName(name:%s) { name, value }}\" }", "Limit50-120");
var httpHeaders = new HttpHeaders(...在这里设置所有必需的标头...);
var endpoint = "http://myservice.com/graphql";
var endpointAsUri = new URI(endpoint);

ResponseEntity<ParametersResponse> parametersResponseEntity =
                this.restTemplate.postForEntity(serviceUri, new HttpEntity<>(queryString, httpHeaders), ParametersResponse.class);

响应实体中的数据为null,并且在GraphQL错误中,我收到以下消息:

无效的语法:在第1行第34列处的标记识别错误:'-120R'

似乎它认为我没有发送一个字符串(尽管在其他服务中我们有类似的实现,没有任何问题),这就是为什么我尝试将查询字符串更改为使用双引号:

var queryString = String.format("{ \"query\": \"{ parameterByName(name:%s) { name, value }}\" }", "\"Limit50-120\"");

然后我得到:

400响应:没有正文。

这很奇怪,因为只有这个特定的调用发生了问题,正如我之前提到的,我们有许多服务都使用相同的方法,没有任何问题。

不确定我是否遗漏了什么。顺便说一下,我使用以下依赖项(我受限于使用这些依赖项进行调用,无法切换到另一个库或更现代版本的GraphQL):

<!-- GraphQL Tools  -->
<dependency>
    <groupId>com.graphql-java</groupId>
    <artifactId>graphql-spring-boot-starter</artifactId>
    <version>5.0.2</version>
</dependency>
<dependency>
    <groupId>com.graphql-java</groupId>
    <artifactId>graphql-java-tools</artifactId>
    <version>5.2.4</version>
</dependency>

任何线索或帮助将不胜感激。提前感谢。

英文:

I have been experiencing a weird issue trying to call a GraphQL query using RestTemplate from the SpringBoot framework. I say it is weird because it is only happening with this particular query.

This is the code I am using (because that is the standard being used at the company):

var queryString = String.format(&quot;{ \&quot;query\&quot;: \&quot;{ parameterByName(name:%s) { name, value }}\&quot; }&quot;, &quot;Limit50-120&quot;);
var httpHeaders = new HttpHeaders(...Here I set all the required headers...);
var endpoint = &quot;http://myservice.com/graphql&quot;;
var endpointAsUri = new URI(endpoint);

ResponseEntity&lt;ParametersResponse&gt; parametersResponseEntity =
                this.restTemplate.postForEntity(serviceUri, new HttpEntity&lt;&gt;(queryString, httpHeaders), ParametersResponse.class);

The response entity holds data as null and in GraphQL errors I am getting the following message:

Invalid Syntax : token recognition error at: &#39;-120R&#39; at line 1 column 34

Seems like it is considering that I am not sending a String (although in other services we have similar implementation and there are no issues), that's why I tried changing the query string to use double quotes:

var queryString = String.format(&quot;{ \&quot;query\&quot;: \&quot;{ parameterByName(name:%s) { name, value }}\&quot; }&quot;, &quot;\&quot;Limit50-120\&quot;&quot;);

Then I get:

400 response: no body.

It is weird because it is only happening with this particular call, as mentioned, we have many services that are working with this same approach and we are not having any issues.

Not sure if I am missing something. By the way, I am using the following dependencies (and I am limited to make this call using these dependencies, I cannot switch to another library or a more modern version of GraphQL):

<!-- GraphQL Tools -->
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>5.0.2</version>
</dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-tools</artifactId>
<version>5.2.4</version>
</dependency>

Any clue or help will be highly appreciated. Thanks in advance

答案1

得分: 0

我成功找到了一个解决方案,不确定这是否是实现它的最佳方式,但它解决了我的问题,如果我想出了一个更有效的解决方案,我肯定会在这里发布。

到目前为止,我所做的是在我的资源文件夹中创建了一个名为 parameterByName.graphql 的文件,其中包含以下查询规范:

query ($name: String) {
    parameterByName(name: $name) {
        name
        value
    }
}

然后,在调用服务时,我进行了以下操作:

创建了一个自定义的 GraphQLRequest POJO:

@AllArgsConstructor
@Data
public class GraphQLRequest {
    private final String query;
    private Map<String, Object> variables = new HashMap<>();
}

然后,我使用以下代码通过 RestTemplate 创建了请求:

Map<String, Object> variables = new HashMap<>();
variables.put("name", "Limit50-120");
var request = new GraphQLRequest(query, variables);
ResponseEntity<String> response = restTemplate.postForEntity(endpointUrl, new HttpEntity<>(request, headers), String.class);

现在,我能够无问题地获取响应。不确定为什么 GraphQL 在之前无法识别它为有效值,但使用这种方式,它可以工作。

英文:

I managed to find a solution, not sure if this is the best way to achieve it, but it solved my problem, if I come up with a more efficient solution, I will post it here for sure.

What I did so far was to create a parameterByName.graphql file in my resources folder with the query spec:

query ($name: String) {
    parameterByName(name: $name) {
        name
        value
    }
}

Then, when I call the service I did the following:

Create a GraphQLRequest custom POJO:

@AllArgsConstructor
@Data
public class GraphQLRequest {
    private final String query;
    private Map&lt;String, Object&gt; variables = new HashMap&lt;&gt;();
}

Then, I create the request through RestTemplate using the following code:

Map&lt;String, Object&gt; variables = new HashMap&lt;&gt;();
variables.put(&quot;name&quot;, &quot;Limit50-120&quot;);
var request = new GraphQLRequest(query, variables);
ResponseEntity&lt;String&gt; response = restTemplate.postForEntity(endpointUrl, new HttpEntity&lt;&gt;(request, headers), String.class);

And now I am able to get the response without issues. Not sure why GraphQL does not recognized it as a valid value before, but with this, it works.

huangapple
  • 本文由 发表于 2023年6月16日 12:14:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76486918.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定