Skip to content

Commit ab7ed34

Browse files
committed
json2code: allow "$ref" for custom type references
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 97e202a commit ab7ed34

File tree

4 files changed

+25
-14
lines changed

4 files changed

+25
-14
lines changed

scripts/seastar-json2code.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -364,22 +364,22 @@ def add_operation(hfile, ccfile, path, oper):
364364
def get_base_name(param):
365365
return os.path.basename(param)
366366

367+
def get_referenced_type(schema, name):
368+
# to be backward compatible, support "type" as well
369+
type = schema.get("$ref") or schema.get("type")
370+
if type is None:
371+
raise Exception(f"neither '$ref' nor 'type' found in {name}")
372+
return type
367373

368374
def is_model_valid(name, model):
369375
if name in valid_vars:
370376
return ""
371377
properties = getitem(model[name], "properties", name)
372378
for var in properties:
373-
type = getitem(properties[var], "type", name + ":" + var)
379+
type = get_referenced_type(properties[var], name + ":" + var)
374380
if type == "array":
375381
items = getitem(properties[var], "items", name + ":" + var)
376-
try:
377-
type = getitem(items, "type", name + ":" + var + ":items")
378-
except Exception as e:
379-
try:
380-
type = getitem(items, "$ref", name + ":" + var + ":items")
381-
except:
382-
raise e
382+
type = get_referenced_type(items, name + ":" + var + ":items")
383383
if type not in valid_vars:
384384
if type not in model:
385385
raise Exception("Unknown type '" + type + "' in Model '" + name + "'")
@@ -563,7 +563,7 @@ def indent(s):
563563
fprintln(hfile, create_enum_wrapper(model_name, member_name, member["enum"]))
564564
fprintln(hfile, f" {config.jsonns}::json_element<{member_name}_wrapper> {member_name};\n")
565565
else:
566-
type_name = type_change(member["type"], member)
566+
type_name = type_change(member["type"] if "type" in member else member["$ref"], member)
567567
fprintln(hfile, f" {config.jsonns}::{type_name} {member_name};\n")
568568
member_init += f'add(&{member_name}, "{member_name}");\n'
569569
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)