Skip to content

Commit 00b7b01

Browse files
authored
feat(graphql): support http get and post json request (#6343)
1 parent deb3a56 commit 00b7b01

File tree

2 files changed

+117
-9
lines changed

2 files changed

+117
-9
lines changed

apisix/core/ctx.lua

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ local core_str = require("apisix.core.string")
1818
local core_tab = require("apisix.core.table")
1919
local request = require("apisix.core.request")
2020
local log = require("apisix.core.log")
21+
local json = require("apisix.core.json")
2122
local config_local = require("apisix.core.config_local")
2223
local tablepool = require("tablepool")
2324
local get_var = require("resty.ngxvar").fetch
@@ -36,7 +37,52 @@ local pcall = pcall
3637

3738

3839
local _M = {version = 0.2}
39-
local GRAPHQL_DEFAULT_MAX_SIZE = 1048576 -- 1MiB
40+
local GRAPHQL_DEFAULT_MAX_SIZE = 1048576 -- 1MiB
41+
local GRAPHQL_REQ_DATA_KEY = "query"
42+
local GRAPHQL_REQ_METHOD_HTTP_GET = "GET"
43+
local GRAPHQL_REQ_METHOD_HTTP_POST = "POST"
44+
local GRAPHQL_REQ_MIME_JSON = "application/json"
45+
46+
47+
local fetch_graphql_data = {
48+
[GRAPHQL_REQ_METHOD_HTTP_GET] = function(ctx, max_size)
49+
local body = request.get_uri_args(ctx)[GRAPHQL_REQ_DATA_KEY]
50+
if not body then
51+
return nil, "failed to read graphql data, args[" ..
52+
GRAPHQL_REQ_DATA_KEY .. "] is nil"
53+
end
54+
55+
if type(body) == "table" then
56+
body = body[1]
57+
end
58+
59+
return body
60+
end,
61+
62+
[GRAPHQL_REQ_METHOD_HTTP_POST] = function(ctx, max_size)
63+
local body, err = request.get_body(max_size, ctx)
64+
if not body then
65+
return nil, "failed to read graphql data, " .. (err or "request body has zero size")
66+
end
67+
68+
if request.header(ctx, "Content-Type") == GRAPHQL_REQ_MIME_JSON then
69+
local res
70+
res, err = json.decode(body)
71+
if not res then
72+
return nil, "failed to read graphql data, " .. err
73+
end
74+
75+
if not res[GRAPHQL_REQ_DATA_KEY] then
76+
return nil, "failed to read graphql data, json body[" ..
77+
GRAPHQL_REQ_DATA_KEY .. "] is nil"
78+
end
79+
80+
body = res[GRAPHQL_REQ_DATA_KEY]
81+
end
82+
83+
return body
84+
end
85+
}
4086

4187

4288
local function parse_graphql(ctx)
@@ -51,9 +97,16 @@ local function parse_graphql(ctx)
5197
max_size = size
5298
end
5399

54-
local body, err = request.get_body(max_size, ctx)
100+
local method = request.get_method()
101+
local func = fetch_graphql_data[method]
102+
if not func then
103+
return nil, "graphql not support `" .. method .. "` request"
104+
end
105+
106+
local body
107+
body, err = func(ctx, max_size)
55108
if not body then
56-
return nil, "failed to read graphql body: " .. (err or "request body has zero size")
109+
return nil, err
57110
end
58111

59112
local ok, res = pcall(gq_parse, body)

t/router/graphql.t

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ query {
232232
}
233233
--- error_code: 404
234234
--- error_log
235-
failed to read graphql body
235+
failed to read graphql data
236236
237237
238238
@@ -244,7 +244,7 @@ failed to read graphql body
244244
local code, body = t('/apisix/admin/routes/1',
245245
ngx.HTTP_PUT,
246246
[=[{
247-
"methods": ["POST"],
247+
"methods": ["POST", "GET"],
248248
"upstream": {
249249
"nodes": {
250250
"127.0.0.1:1980": 1
@@ -283,7 +283,62 @@ hello world
283283
284284
285285
286-
=== TEST 13: multiple root fields
286+
=== TEST 13: test send http post json data
287+
--- request
288+
POST /hello
289+
{"query":"query{owner{name}}"}
290+
--- more_headers
291+
Content-Type: application/json
292+
--- response_body
293+
hello world
294+
295+
296+
297+
=== TEST 14: test send http get query data
298+
--- request
299+
GET /hello?query=query{owner{name}}
300+
--- response_body
301+
hello world
302+
303+
304+
305+
=== TEST 15: test send http get multiple query data success
306+
--- request
307+
GET /hello?query=query{owner{name}}&query=query{repo{name}}
308+
--- response_body
309+
hello world
310+
311+
312+
313+
=== TEST 16: test send http get multiple query data failure
314+
--- request
315+
GET /hello?query=query{repo{name}}&query=query{owner{name}}
316+
--- error_code: 404
317+
318+
319+
320+
=== TEST 17: no body (HTTP GET)
321+
--- request
322+
GET /hello
323+
--- error_code: 404
324+
--- error_log
325+
failed to read graphql data, args[query] is nil
326+
327+
328+
329+
=== TEST 18: no body (HTTP POST JSON)
330+
--- request
331+
POST /hello
332+
{}
333+
--- more_headers
334+
Content-Type: application/json
335+
--- error_code: 404
336+
--- error_log
337+
failed to read graphql data, json body[query] is nil
338+
339+
340+
341+
=== TEST 19: multiple root fields
287342
--- request
288343
POST /hello
289344
query {
@@ -299,7 +354,7 @@ hello world
299354
300355
301356
302-
=== TEST 14: root fields mismatch
357+
=== TEST 20: root fields mismatch
303358
--- request
304359
POST /hello
305360
query {
@@ -311,9 +366,9 @@ query {
311366
312367
313368
314-
=== TEST 15: no body
369+
=== TEST 21: no body
315370
--- request
316371
POST /hello
317372
--- error_code: 404
318373
--- error_log
319-
failed to read graphql body: request body has zero size
374+
failed to read graphql data, request body has zero size

0 commit comments

Comments
 (0)