@@ -8,29 +8,32 @@ and `validate_response/4` respectively.
88
99For example, the user-defined `Module:accept_callback/4` can be implemented as follows:
1010```
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) ->
1420 ValidatorState = openapi_api:prepare_validator(),
1521 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;
3235 { error, Reason, Req1} ->
33- process_response({ error, Reason} , Req1, State )
36+ process_response({ error, Reason} , Req1, Context0 )
3437 end.
3538```
3639""".
@@ -41,10 +44,17 @@ accept_callback(Class, OperationID, Req, Context) ->
4144-ignore_xref([populate_request/3, validate_response/4]).
4245-ignore_xref([prepare_validator/0, prepare_validator/1, prepare_validator/2]).
4346
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+
4555-type request_param() :: atom().
4656
47- -export_type([operation_id/0]).
57+ -export_type([class/0, operation_id/0]).
4858
4959-dialyzer({ nowarn_function, [validate_response_body/4]} ).
5060
@@ -64,6 +74,7 @@ accept_callback(Class, OperationID, Req, Context) ->
6474 { max_length, MaxLength :: integer()} |
6575 { min_length, MaxLength :: integer()} |
6676 { pattern, Pattern :: string()} |
77+ { schema, object | list, binary()} |
6778 schema |
6879 required |
6980 not_required.
@@ -111,25 +122,25 @@ for the `OperationID` operation.
111122 Body :: jesse:json_term(),
112123 ValidatorState :: jesse_state:state()) ->
113124 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) ->
115126 validate_response_body('{ {dataType} }', '{ {baseType} }', Body, ValidatorState);
116127{ {/responses} }
117128{ {/operation} }{ {/operations} }{ {/apis} }{ {/apiInfo} }validate_response(_OperationID, _Code, _Body, _ValidatorState) ->
118129 ok.
119130
120131%%%
121132-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 } }') ->
123134 [{ {#allParams} }{ {^isBodyParam} }
124135 '{ {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} }
126137 ];
127138{ {/operation} }{ {/operations} }{ {/apis} }{ {/apiInfo} }request_params(_) ->
128139 error(unknown_operation).
129140
130141-spec request_param_info(OperationID :: operation_id(), Name :: request_param()) ->
131142 #{ 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} }) ->
133144 #{
134145 source => {{#isQueryParam} }qs_val{ {/isQueryParam} }{ {#isPathParam} }binding{ {/isPathParam} }{ {#isHeaderParam} }header{ {/isHeaderParam} }{ {#isBodyParam} }body{ {/isBodyParam} }{ {#isFormParam} }body{ {/isFormParam} },
135146 rules => [{ {#isString} }
@@ -150,8 +161,9 @@ for the `OperationID` operation.
150161 { exclusive_min, {{minimum} }},{ {/exclusiveMinimum} }{ {/minimum} }{ {#maxLength} }
151162 { max_length, {{maxLength} }},{ {/maxLength} }{ {#minLength} }
152163 { 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} }
155167 required{ {/required} }{ {^required} }
156168 not_required{ {/required} }
157169 ]
@@ -189,8 +201,6 @@ populate_request_param(OperationID, ReqParamName, Req0, ValidatorState) ->
189201 end
190202 end.
191203
192- -include_lib("kernel/include/logger.hrl").
193-
194204validate_response_body(list, ReturnBaseType, Body, ValidatorState) ->
195205 [
196206 validate(schema, Item, ReturnBaseType, ValidatorState)
@@ -281,8 +291,15 @@ validate(Rule = {pattern, Pattern}, Value, ReqParamName, _) ->
281291 { match, _} -> ok;
282292 _ -> validation_error(Rule, ReqParamName, Value)
283293 end;
284- validate(Rule = schema, Value, ReqParamName, ValidatorState) ->
294+ validate(schema, Value, ReqParamName, ValidatorState) ->
285295 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) ->
286303 try
287304 _ = validate_with_schema(Value, Definition, ValidatorState),
288305 ok
0 commit comments