Skip to content

Commit e0e6bc2

Browse files
committed
improve query param handling fixes #58
1 parent 0f5d66d commit e0e6bc2

File tree

7 files changed

+76
-37
lines changed

7 files changed

+76
-37
lines changed

graphql-spqr-spring-boot-autoconfigure/src/main/java/io/leangen/graphql/spqr/spring/autoconfigure/SpqrMvcAutoConfiguration.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.leangen.graphql.spqr.spring.autoconfigure;
22

3+
import com.fasterxml.jackson.databind.ObjectMapper;
34
import graphql.GraphQL;
45
import graphql.schema.GraphQLSchema;
56
import io.leangen.graphql.spqr.spring.web.GraphQLController;
@@ -40,8 +41,8 @@ public GraphQLServletExecutor graphQLExecutor(ServletContextFactory contextFacto
4041
@ConditionalOnProperty(name = "graphql.spqr.http.enabled", havingValue = "true", matchIfMissing = true)
4142
@ConditionalOnMissingBean(GraphQLController.class)
4243
@ConditionalOnBean(GraphQLSchema.class)
43-
public DefaultGraphQLController graphQLController(GraphQL graphQL, GraphQLServletExecutor executor) {
44-
return new DefaultGraphQLController(graphQL, executor);
44+
public DefaultGraphQLController graphQLController(GraphQL graphQL, GraphQLServletExecutor executor, ObjectMapper objectMapper) {
45+
return new DefaultGraphQLController(graphQL, executor, objectMapper);
4546
}
4647

4748
@Bean

graphql-spqr-spring-boot-autoconfigure/src/main/java/io/leangen/graphql/spqr/spring/autoconfigure/SpqrReactiveAutoConfiguration.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
package io.leangen.graphql.spqr.spring.autoconfigure;
22

3+
import com.fasterxml.jackson.databind.ObjectMapper;
34
import graphql.GraphQL;
45
import graphql.schema.GraphQLSchema;
56
import io.leangen.graphql.module.Module;
67
import io.leangen.graphql.spqr.spring.autoconfigure.reactive.FluxAdapter;
78
import io.leangen.graphql.spqr.spring.autoconfigure.reactive.MonoAdapter;
89
import io.leangen.graphql.spqr.spring.web.GraphQLController;
9-
import io.leangen.graphql.spqr.spring.web.reactive.GraphQLReactiveExecutor;
1010
import io.leangen.graphql.spqr.spring.web.GuiController;
11-
import io.leangen.graphql.spqr.spring.web.reactive.DefaultGraphQLExecutor;
1211
import io.leangen.graphql.spqr.spring.web.reactive.DefaultGraphQLController;
12+
import io.leangen.graphql.spqr.spring.web.reactive.DefaultGraphQLExecutor;
13+
import io.leangen.graphql.spqr.spring.web.reactive.GraphQLReactiveExecutor;
1314
import org.springframework.beans.factory.annotation.Autowired;
1415
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
1516
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -53,8 +54,8 @@ public GraphQLReactiveExecutor graphQLExecutor(ReactiveContextFactory contextFac
5354
@ConditionalOnProperty(name = "graphql.spqr.http.enabled", havingValue = "true", matchIfMissing = true)
5455
@ConditionalOnMissingBean(GraphQLController.class)
5556
@ConditionalOnBean(GraphQLSchema.class)
56-
public DefaultGraphQLController graphQLController(GraphQL graphQL, GraphQLReactiveExecutor executor) {
57-
return new DefaultGraphQLController(graphQL, executor);
57+
public DefaultGraphQLController graphQLController(GraphQL graphQL, GraphQLReactiveExecutor executor, ObjectMapper objectMapper) {
58+
return new DefaultGraphQLController(graphQL, executor, objectMapper);
5859
}
5960

6061
@Bean

graphql-spqr-spring-boot-autoconfigure/src/main/java/io/leangen/graphql/spqr/spring/web/GraphQLController.java

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,27 @@
11
package io.leangen.graphql.spqr.spring.web;
22

3+
import java.io.IOException;
4+
import java.util.Collections;
5+
import java.util.Map;
6+
7+
import com.fasterxml.jackson.databind.ObjectMapper;
38
import graphql.GraphQL;
49
import io.leangen.graphql.spqr.spring.web.dto.GraphQLRequest;
510
import org.springframework.http.MediaType;
611
import org.springframework.util.StringUtils;
7-
import org.springframework.web.bind.annotation.GetMapping;
8-
import org.springframework.web.bind.annotation.PostMapping;
9-
import org.springframework.web.bind.annotation.RequestBody;
10-
import org.springframework.web.bind.annotation.RequestMapping;
11-
import org.springframework.web.bind.annotation.RequestMethod;
12-
import org.springframework.web.bind.annotation.RequestParam;
13-
import org.springframework.web.bind.annotation.ResponseBody;
14-
import org.springframework.web.bind.annotation.RestController;
15-
16-
import java.util.Map;
12+
import org.springframework.web.bind.annotation.*;
1713

1814
@RestController
1915
public abstract class GraphQLController<R> {
2016

2117
protected final GraphQL graphQL;
2218
protected final GraphQLExecutor<R> executor;
19+
private ObjectMapper objectMapper;
2320

24-
public GraphQLController(GraphQL graphQL, GraphQLExecutor<R> executor) {
21+
public GraphQLController(GraphQL graphQL, GraphQLExecutor<R> executor, ObjectMapper objectMapper) {
2522
this.graphQL = graphQL;
2623
this.executor = executor;
24+
this.objectMapper = objectMapper;
2725
}
2826

2927
@PostMapping(
@@ -33,11 +31,14 @@ public GraphQLController(GraphQL graphQL, GraphQLExecutor<R> executor) {
3331
)
3432
@ResponseBody
3533
public Object executeJsonPost(@RequestBody GraphQLRequest requestBody,
36-
GraphQLRequest requestParams,
37-
R request) {
38-
String query = requestParams.getQuery() == null ? requestBody.getQuery() : requestParams.getQuery();
39-
String operationName = requestParams.getOperationName() == null ? requestBody.getOperationName() : requestParams.getOperationName();
40-
Map<String, Object> variables = requestParams.getVariables() == null ? requestBody.getVariables() : requestParams.getVariables();
34+
@RequestParam(value = "query", required = false) String requestQuery,
35+
@RequestParam(value = "operationName", required = false) String requestOperationName,
36+
@RequestParam(value = "variables", required = false) String variablesJsonString,
37+
R request) throws IOException {
38+
String query = requestQuery == null ? requestBody.getQuery() : requestQuery;
39+
String operationName = requestOperationName == null ? requestBody.getOperationName() : requestOperationName;
40+
//noinspection unchecked
41+
Map<String, Object> variables = variablesJsonString == null ? requestBody.getVariables() : objectMapper.readValue(variablesJsonString, Map.class);
4142

4243
return executor.execute(graphQL, new GraphQLRequest(query, operationName, variables), request);
4344
}
@@ -80,7 +81,12 @@ public Object executeFormPost(@RequestParam Map<String, String> queryParams,
8081
headers = "Connection!=Upgrade"
8182
)
8283
@ResponseBody
83-
public Object executeGet(GraphQLRequest graphQLRequest, R request) {
84-
return executor.execute(graphQL, graphQLRequest, request);
84+
public Object executeGet(@RequestParam(value = "query") String requestQuery,
85+
@RequestParam(value = "operationName", required = false) String requestOperationName,
86+
@RequestParam(value = "variables", required = false) String variablesJsonString,
87+
R request) throws IOException {
88+
//noinspection unchecked
89+
Map<String, Object> variables = variablesJsonString == null ? Collections.emptyMap() : objectMapper.readValue(variablesJsonString, Map.class);
90+
return executor.execute(graphQL, new GraphQLRequest(requestQuery, requestOperationName, variables), request);
8591
}
8692
}

graphql-spqr-spring-boot-autoconfigure/src/main/java/io/leangen/graphql/spqr/spring/web/reactive/DefaultGraphQLController.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.leangen.graphql.spqr.spring.web.reactive;
22

3+
import com.fasterxml.jackson.databind.ObjectMapper;
34
import graphql.GraphQL;
45
import io.leangen.graphql.spqr.spring.web.GraphQLController;
56
import org.springframework.beans.factory.annotation.Autowired;
@@ -12,7 +13,7 @@
1213
public class DefaultGraphQLController extends GraphQLController<ServerWebExchange> {
1314

1415
@Autowired
15-
public DefaultGraphQLController(GraphQL graphQL, GraphQLReactiveExecutor executor) {
16-
super(graphQL, executor);
16+
public DefaultGraphQLController(GraphQL graphQL, GraphQLReactiveExecutor executor, ObjectMapper objectMapper) {
17+
super(graphQL, executor, objectMapper);
1718
}
1819
}

graphql-spqr-spring-boot-autoconfigure/src/main/java/io/leangen/graphql/spqr/spring/web/servlet/DefaultGraphQLController.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.leangen.graphql.spqr.spring.web.servlet;
22

3+
import com.fasterxml.jackson.databind.ObjectMapper;
34
import graphql.GraphQL;
45
import io.leangen.graphql.spqr.spring.web.GraphQLController;
56
import org.springframework.beans.factory.annotation.Autowired;
@@ -12,7 +13,7 @@
1213
public class DefaultGraphQLController extends GraphQLController<NativeWebRequest> {
1314

1415
@Autowired
15-
public DefaultGraphQLController(GraphQL graphQL, GraphQLServletExecutor executor) {
16-
super(graphQL, executor);
16+
public DefaultGraphQLController(GraphQL graphQL, GraphQLServletExecutor executor, ObjectMapper objectMapper) {
17+
super(graphQL, executor, objectMapper);
1718
}
1819
}

graphql-spqr-spring-boot-autoconfigure/src/test/java/io/leangen/graphql/spqr/spring/test/ResolverBuilder_TestConfig.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package io.leangen.graphql.spqr.spring.test;
22

3+
import java.lang.reflect.Method;
4+
import java.util.Arrays;
5+
36
import io.leangen.graphql.ExtensionProvider;
47
import io.leangen.graphql.GeneratorConfiguration;
8+
import io.leangen.graphql.annotations.GraphQLArgument;
59
import io.leangen.graphql.annotations.GraphQLQuery;
610
import io.leangen.graphql.metadata.strategy.query.BeanResolverBuilder;
711
import io.leangen.graphql.metadata.strategy.query.PublicResolverBuilder;
@@ -14,9 +18,6 @@
1418
import org.springframework.context.annotation.Configuration;
1519
import org.springframework.stereotype.Component;
1620

17-
import java.lang.reflect.Method;
18-
import java.util.Arrays;
19-
2021
@Configuration
2122
public class ResolverBuilder_TestConfig {
2223
//------------------------------------------------------------------------------------------
@@ -41,11 +42,16 @@ protected boolean isQuery(Method method, ResolverBuilderParams params) {
4142

4243
@Component("annotatedOperationSourceBean")
4344
@GraphQLApi
44-
private static class AnnotatedOperationSourceBean {
45+
public static class AnnotatedOperationSourceBean {
4546
@GraphQLQuery(name = "greetingFromAnnotatedSource_wiredAsComponent")
4647
public String getGreeting(){
4748
return "Hello world !";
4849
}
50+
51+
@GraphQLQuery(name = "echo")
52+
public String echo(@GraphQLArgument(name = "content", defaultValue = "") String content) {
53+
return content;
54+
}
4955
}
5056

5157
@Bean

graphql-spqr-spring-boot-autoconfigure/src/test/java/io/leangen/graphql/spqr/spring/web/GraphQLControllerTest.java

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package io.leangen.graphql.spqr.spring.web;
22

3+
import java.net.URLEncoder;
4+
import java.nio.charset.StandardCharsets;
5+
36
import io.leangen.graphql.spqr.spring.autoconfigure.SpqrAutoConfiguration;
47
import io.leangen.graphql.spqr.spring.autoconfigure.SpqrMvcAutoConfiguration;
58
import io.leangen.graphql.spqr.spring.test.ResolverBuilder_TestConfig;
@@ -14,9 +17,6 @@
1417
import org.springframework.test.context.junit4.SpringRunner;
1518
import org.springframework.test.web.servlet.MockMvc;
1619

17-
import java.net.URLEncoder;
18-
import java.nio.charset.StandardCharsets;
19-
2020
import static org.hamcrest.Matchers.containsString;
2121
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
2222
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
@@ -109,14 +109,37 @@ public void defaultControllerTest_POST_applicationJson_INVALID() throws Exceptio
109109
@Test
110110
public void defaultControllerTest_POST_applicationJson_overridingQueryParams() throws Exception {
111111
mockMvc.perform(
112-
post("/"+apiContext)
113-
.param("query","{greetingFromBeanSource_wiredAsComponent_byAnnotation}")
112+
post("/" + apiContext)
113+
.param("query", "{greetingFromBeanSource_wiredAsComponent_byAnnotation}")
114114
.contentType(MediaType.APPLICATION_JSON_UTF8)
115115
.content("{\"query\":\"{INVALID_QUERY}\",\"variables\":null,\"operationName\":null}"))
116116
.andExpect(status().isOk())
117117
.andExpect(content().string(containsString("Hello world")));
118118
}
119119

120+
@Test
121+
public void defaultControllerTest_GET_with_variables() throws Exception {
122+
mockMvc.perform(
123+
get("/" + apiContext)
124+
.param("query", "query Echo($contentInput: String){ echo(content: $contentInput)}")
125+
.param("variables", "{\"contentInput\": \"Hello world\"}")
126+
)
127+
.andExpect(status().isOk())
128+
.andExpect(content().json("{\"data\":{\"echo\":\"Hello world\"}}", true));
129+
}
130+
131+
@Test
132+
public void defaultControllerTest_POST_with_variables() throws Exception {
133+
mockMvc.perform(
134+
post("/" + apiContext)
135+
.contentType(MediaType.APPLICATION_JSON_UTF8)
136+
.content("{\"query\":\"{INVALID_QUERY}\",\"variables\":{\"contentInput\": \"Hello world2\"},\"operationName\":null}")
137+
.param("query", "query Echo($contentInput: String){ echo(content: $contentInput)}")
138+
.param("variables", "{\"contentInput\": \"Hello world1\"}"))
139+
.andExpect(status().isOk())
140+
.andExpect(content().json("{\"data\":{\"echo\":\"Hello world1\"}}", true));
141+
}
142+
120143
@Test
121144
public void defaultControllerTest_POST_formUrlEncoded_INVALID() throws Exception {
122145
mockMvc.perform(

0 commit comments

Comments
 (0)