@@ -8,29 +8,32 @@ and `validate_response/4` respectively.
8
8
9
9
For example, the user-defined `Module:accept_callback/4` can be implemented as follows:
10
10
```
11
- -spec accept_callback(atom(), openapi_api:operation_id(), cowboy_req:req(), context()) ->
12
- { cowboy:http_status(), cowboy:http_headers(), json:encode_value()} .
13
- accept_callback(Class, OperationID, Req, Context) ->
11
+ -spec accept_callback(
12
+ Class :: openapi_api:class(),
13
+ OperationID :: openapi_api:operation_id(),
14
+ Req :: cowboy_req:req(),
15
+ Context :: openapi_logic_handler:context()) ->
16
+ { openapi_logic_handler:accept_callback_return(),
17
+ cowboy_req:req(),
18
+ openapi_logic_handler:context()} .
19
+ accept_callback(Class, OperationID, Req0, Context0) ->
14
20
ValidatorState = openapi_api:prepare_validator(),
15
21
case openapi_api:populate_request(OperationID, Req0, ValidatorState) of
16
- { ok, Populated, Req1} ->
17
- { Code, Headers, Body} = openapi_logic_handler:handle_request(
18
- LogicHandler,
19
- OperationID,
20
- Req1,
21
- maps:merge(State#state.context, Populated)
22
- ),
23
- _ = openapi_api:validate_response(
24
- OperationID,
25
- Code,
26
- Body,
27
- ValidatorState
28
- ),
29
- PreparedBody = prepare_body(Code, Body),
30
- Response = { ok, {Code, Headers, PreparedBody} },
31
- process_response(Response, Req1, State);
22
+ { ok, Model, Req1} ->
23
+ Context1 = maps:merge(Context0, Model),
24
+ case do_accept_callback(Class, OperationID, Req1, Context1) of
25
+ { false , Req2, Context2} ->
26
+ { false , Req2, Context2} ;
27
+ { {true , Code, Body} , Req2, Context2} ->
28
+ case validate_response(OperationID, Code, Body, ValidatorState) of
29
+ ok ->
30
+ process_response({ ok, Code, Body} , Req2, Context2);
31
+ { error, Reason} ->
32
+ process_response({ error, Reason} , Req2, Context2)
33
+ end
34
+ end;
32
35
{ error, Reason, Req1} ->
33
- process_response({ error, Reason} , Req1, State )
36
+ process_response({ error, Reason} , Req1, Context0 )
34
37
end.
35
38
```
36
39
""".
@@ -41,10 +44,17 @@ accept_callback(Class, OperationID, Req, Context) ->
41
44
-ignore_xref([populate_request/3, validate_response/4]).
42
45
-ignore_xref([prepare_validator/0, prepare_validator/1, prepare_validator/2]).
43
46
44
- -type operation_id() :: atom().
47
+ -type class() ::
48
+ { {#apiInfo} }{ {#apis} }{ {#operations} } { {^-first} }| { {/-first} }'{ {pathPrefix} }'{ {#-last} }.{ {/-last} }
49
+ { {/operations} }{ {/apis} }{ {/apiInfo} }
50
+
51
+ -type operation_id() ::
52
+ { {#apiInfo} }{ {#apis} }{ {#operations} }{ {#operation} } '{ {operationIdOriginal} }' | %% { {summary} }
53
+ { {/operation} }{ {/operations} }{ {/apis} }{ {/apiInfo} } { error, unknown_operation} .
54
+
45
55
-type request_param() :: atom().
46
56
47
- -export_type([operation_id/0]).
57
+ -export_type([class/0, operation_id/0]).
48
58
49
59
-dialyzer({ nowarn_function, [validate_response_body/4]} ).
50
60
@@ -64,6 +74,7 @@ accept_callback(Class, OperationID, Req, Context) ->
64
74
{ max_length, MaxLength :: integer()} |
65
75
{ min_length, MaxLength :: integer()} |
66
76
{ pattern, Pattern :: string()} |
77
+ { schema, object | list, binary()} |
67
78
schema |
68
79
required |
69
80
not_required.
@@ -111,25 +122,25 @@ for the `OperationID` operation.
111
122
Body :: jesse:json_term(),
112
123
ValidatorState :: jesse_state:state()) ->
113
124
ok | { ok, term()} | [ok | { ok, term()} ] | no_return().
114
- { {#apiInfo} }{ {#apis} }{ {#operations} }{ {#operation} }{ {#responses} }validate_response('{ {operationId } }', { {code} }, Body, ValidatorState) ->
125
+ { {#apiInfo} }{ {#apis} }{ {#operations} }{ {#operation} }{ {#responses} }validate_response('{ {operationIdOriginal } }', { {code} }, Body, ValidatorState) ->
115
126
validate_response_body('{ {dataType} }', '{ {baseType} }', Body, ValidatorState);
116
127
{ {/responses} }
117
128
{ {/operation} }{ {/operations} }{ {/apis} }{ {/apiInfo} }validate_response(_OperationID, _Code, _Body, _ValidatorState) ->
118
129
ok.
119
130
120
131
%%%
121
132
-spec request_params(OperationID :: operation_id()) -> [Param :: request_param()].
122
- { {#apiInfo} }{ {#apis} }{ {#operations} }{ {#operation} }request_params('{ {operationId } }') ->
133
+ { {#apiInfo} }{ {#apis} }{ {#operations} }{ {#operation} }request_params('{ {operationIdOriginal } }') ->
123
134
[{ {#allParams} }{ {^isBodyParam} }
124
135
'{ {baseName} }'{ {/isBodyParam} }{ {#isBodyParam} }
125
- '{ {dataType} }'{ {/isBodyParam} }{ {^-last} },{ {/-last} }{ {/allParams} }
136
+ { {#content.application/json.schema.openApiType } } '{ {content.application/json.schema.openApiType } }' { {/content.application/json.schema.openApiType } } { {^content.application/json.schema.openApiType } }' { { dataType} }'{ {/content.application/json.schema.openApiType } } { {/isBodyParam} }{ {^-last} },{ {/-last} }{ {/allParams} }
126
137
];
127
138
{ {/operation} }{ {/operations} }{ {/apis} }{ {/apiInfo} }request_params(_) ->
128
139
error(unknown_operation).
129
140
130
141
-spec request_param_info(OperationID :: operation_id(), Name :: request_param()) ->
131
142
#{ source => qs_val | binding | header | body, rules => [rule()]} .
132
- { {#apiInfo} }{ {#apis} }{ {#operations} }{ {#operation} }{ {#allParams} }request_param_info('{ {operationId } }', { {^isBodyParam} }'{ {baseName} }'{ {/isBodyParam} }{ {#isBodyParam} }'{ {dataType} }'{ {/isBodyParam} }) ->
143
+ { {#apiInfo} }{ {#apis} }{ {#operations} }{ {#operation} }{ {#allParams} }request_param_info('{ {operationIdOriginal } }', { {^isBodyParam} }'{ {baseName} }'{ {/isBodyParam} }{ {#isBodyParam} }{ {#content.application/json.schema.openApiType } } '{ {content.application/json.schema.openApiType } }' { {/content.application/json.schema.openApiType } } { {^content.application/json.schema.openApiType } }' { { dataType} }'{ {/content.application/json.schema.openApiType } } { {/isBodyParam} }) ->
133
144
#{
134
145
source => {{#isQueryParam} }qs_val{ {/isQueryParam} }{ {#isPathParam} }binding{ {/isPathParam} }{ {#isHeaderParam} }header{ {/isHeaderParam} }{ {#isBodyParam} }body{ {/isBodyParam} }{ {#isFormParam} }body{ {/isFormParam} },
135
146
rules => [{ {#isString} }
@@ -150,8 +161,9 @@ for the `OperationID` operation.
150
161
{ exclusive_min, {{minimum} }},{ {/exclusiveMinimum} }{ {/minimum} }{ {#maxLength} }
151
162
{ max_length, {{maxLength} }},{ {/maxLength} }{ {#minLength} }
152
163
{ min_length, {{minLength} }},{ {/minLength} }{ {#pattern} }
153
- { pattern, " {{{pattern}}}" } ,{ {/pattern} }{ {#isBodyParam} }
154
- schema,{ {/isBodyParam} }{ {#required} }
164
+ { pattern, " {{{pattern}}}" } ,{ {/pattern} }{ {#isBodyParam} }{ {#content.application/json.schema.ref} }
165
+ { schema, object, << " {{content.application/json.schema.ref}}" >> } ,{ {/content.application/json.schema.ref} }{ {#content.application/json.schema.items.ref} }
166
+ { schema, list, << " {{content.application/json.schema.items.ref}}" >> } ,{ {/content.application/json.schema.items.ref} }{ {/isBodyParam} }{ {#required} }
155
167
required{ {/required} }{ {^required} }
156
168
not_required{ {/required} }
157
169
]
@@ -189,8 +201,6 @@ populate_request_param(OperationID, ReqParamName, Req0, ValidatorState) ->
189
201
end
190
202
end.
191
203
192
- -include_lib("kernel/include/logger.hrl").
193
-
194
204
validate_response_body(list, ReturnBaseType, Body, ValidatorState) ->
195
205
[
196
206
validate(schema, Item, ReturnBaseType, ValidatorState)
@@ -281,8 +291,15 @@ validate(Rule = {pattern, Pattern}, Value, ReqParamName, _) ->
281
291
{ match, _} -> ok;
282
292
_ -> validation_error(Rule, ReqParamName, Value)
283
293
end;
284
- validate(Rule = schema, Value, ReqParamName, ValidatorState) ->
294
+ validate(schema, Value, ReqParamName, ValidatorState) ->
285
295
Definition = iolist_to_binary(["#/components/schemas/", atom_to_binary(ReqParamName, utf8)]),
296
+ validate({ schema, object, Definition} , Value, ReqParamName, ValidatorState);
297
+ validate({ schema, list, Definition} , Value, ReqParamName, ValidatorState) ->
298
+ lists:foreach(
299
+ fun(Item) ->
300
+ validate({ schema, object, Definition} , Item, ReqParamName, ValidatorState)
301
+ end, Value);
302
+ validate(Rule = { schema, object, Definition} , Value, ReqParamName, ValidatorState) ->
286
303
try
287
304
_ = validate_with_schema(Value, Definition, ValidatorState),
288
305
ok
0 commit comments