Skip to content

Commit 0548195

Browse files
committed
Json2code: full $ref support
Swagger only allows to refer to custom composite types via "$ref", not via "type", whether it is about array elements or individual items. Disallowing "type" would break existing use, so allow "$ref" to be used interchangeably. Signed-off-by: Alexey Bashtanov <[email protected]>
1 parent 1147ac2 commit 0548195

File tree

4 files changed

+24
-7
lines changed

4 files changed

+24
-7
lines changed

scripts/seastar-json2code.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,13 @@ def is_model_valid(name, model):
370370
return ""
371371
properties = getitem(model[name], "properties", name)
372372
for var in properties:
373-
type = getitem(properties[var], "type", name + ":" + var)
373+
try:
374+
type = getitem(properties[var], "type", name + ":" + var)
375+
except Exception as e:
376+
try:
377+
type = getitem(properties[var], "$ref", name + ":" + var)
378+
except:
379+
raise e
374380
if type == "array":
375381
items = getitem(properties[var], "items", name + ":" + var)
376382
try:
@@ -563,7 +569,7 @@ def indent(s):
563569
fprintln(hfile, create_enum_wrapper(model_name, member_name, member["enum"]))
564570
fprintln(hfile, f" {config.jsonns}::json_element<{member_name}_wrapper> {member_name};\n")
565571
else:
566-
type_name = type_change(member["type"], member)
572+
type_name = type_change(member["type"] if "type" in member else member["$ref"], member)
567573
fprintln(hfile, f" {config.jsonns}::{type_name} {member_name};\n")
568574
member_init += f'add(&{member_name}, "{member_name}");\n'
569575
member_assignment += f'{member_name} = e.{member_name};\n'

tests/unit/api.json

+11-2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@
5454
}
5555
],
5656
"models": {
57+
"var2_referred": {
58+
"type": "object",
59+
"properties": {
60+
"var21": {
61+
"type": "string",
62+
"description": "The inner part of the second parameter"
63+
}
64+
}
65+
},
5766
"my_object": {
5867
"id": "my_object",
5968
"description": "Demonstrate an object",
@@ -63,8 +72,8 @@
6372
"description": "The first parameter in the path"
6473
},
6574
"var2": {
66-
"type": "string",
67-
"description": "The second parameter in the path"
75+
"$ref": "var2_referred",
76+
"description": "The second parameter in the path wrapped in an object"
6877
},
6978
"enum_var": {
7079
"type": "string",

tests/unit/json2code_test.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def test_path_params(self):
5757
with urllib.request.urlopen(url) as f:
5858
response = json.loads(f.read().decode('utf-8'))
5959
self.assertEqual(response['var1'], f'/{var1}')
60-
self.assertEqual(response['var2'], f'/{var2}')
60+
self.assertEqual(response['var2']['var21'], f'/{var2}')
6161
self.assertEqual(response['enum_var'], query_enum)
6262

6363
def test_bad_enum(self):
@@ -69,7 +69,7 @@ def test_bad_enum(self):
6969
with urllib.request.urlopen(url) as f:
7070
response = json.loads(f.read().decode('utf-8'))
7171
self.assertEqual(response['var1'], f'/{var1}')
72-
self.assertEqual(response['var2'], f'/{var2}')
72+
self.assertEqual(response['var2']['var21'], f'/{var2}')
7373
self.assertEqual(response['enum_var'], 'Unknown')
7474

7575
def test_missing_path_param(self):

tests/unit/rest_api_httpd.cc

+3-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ void set_routes(routes& r) {
4343
api_json::hello_world.set(r, [] (const_req req) {
4444
api_json::my_object obj;
4545
obj.var1 = req.param.at("var1");
46-
obj.var2 = req.param.at("var2");
46+
api_json::var2_referred var2_wrapped;
47+
var2_wrapped.var21 = req.param.at("var2");
48+
obj.var2 = var2_wrapped;
4749
api_json::ns_hello_world::query_enum v = api_json::ns_hello_world::str2query_enum(req.query_parameters.at("query_enum"));
4850
// This demonstrate enum conversion
4951
obj.enum_var = v;

0 commit comments

Comments
 (0)