chore(swagger): support check_schema option, default is false.
This commit is contained in:
parent
39423665e9
commit
96fad3d225
|
@ -41,7 +41,7 @@
|
||||||
namespace() -> "dashboard".
|
namespace() -> "dashboard".
|
||||||
|
|
||||||
api_spec() ->
|
api_spec() ->
|
||||||
emqx_dashboard_swagger:spec(?MODULE).
|
emqx_dashboard_swagger:spec(?MODULE, #{check_schema => true}).
|
||||||
|
|
||||||
paths() -> ["/login", "/logout", "/users",
|
paths() -> ["/login", "/logout", "/users",
|
||||||
"/users/:username", "/users/:username/change_pwd"].
|
"/users/:username", "/users/:username/change_pwd"].
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
-include_lib("hocon/include/hoconsc.hrl").
|
-include_lib("hocon/include/hoconsc.hrl").
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([spec/1]).
|
-export([spec/1, spec/2]).
|
||||||
-export([translate_req/2]).
|
-export([translate_req/2]).
|
||||||
|
|
||||||
-ifdef(TEST).
|
-ifdef(TEST).
|
||||||
|
@ -24,23 +24,37 @@
|
||||||
-define(TO_REF(_N_, _F_), iolist_to_binary([to_bin(_N_), ".", to_bin(_F_)])).
|
-define(TO_REF(_N_, _F_), iolist_to_binary([to_bin(_N_), ".", to_bin(_F_)])).
|
||||||
-define(TO_COMPONENTS(_M_, _F_), iolist_to_binary([<<"#/components/schemas/">>, ?TO_REF(namespace(_M_), _F_)])).
|
-define(TO_COMPONENTS(_M_, _F_), iolist_to_binary([<<"#/components/schemas/">>, ?TO_REF(namespace(_M_), _F_)])).
|
||||||
|
|
||||||
-spec(spec(module()) -> {list({Path, Specs, OperationId, Options}), list(Component)} when
|
%% @equiv spec(Module, #{check_schema => false})
|
||||||
|
-spec(spec(module()) ->
|
||||||
|
{list({Path, Specs, OperationId, Options}), list(Component)} when
|
||||||
Path :: string()|binary(),
|
Path :: string()|binary(),
|
||||||
Specs :: map(),
|
Specs :: map(),
|
||||||
OperationId :: atom(),
|
OperationId :: atom(),
|
||||||
Options :: #{filter => fun((map(),
|
Options :: #{filter => fun((map(),
|
||||||
#{module => module(), path => string(), method => atom()}) -> map())},
|
#{module => module(), path => string(), method => atom()}) -> map())},
|
||||||
Component :: map()).
|
Component :: map()).
|
||||||
spec(Module) ->
|
spec(Module) -> spec(Module, #{check_schema => false}).
|
||||||
|
|
||||||
|
-spec(spec(module(), #{check_schema => boolean()}) ->
|
||||||
|
{list({Path, Specs, OperationId, Options}), list(Component)} when
|
||||||
|
Path :: string()|binary(),
|
||||||
|
Specs :: map(),
|
||||||
|
OperationId :: atom(),
|
||||||
|
Options :: #{filter => fun((map(),
|
||||||
|
#{module => module(), path => string(), method => atom()}) -> map())},
|
||||||
|
Component :: map()).
|
||||||
|
spec(Module, Options) ->
|
||||||
Paths = apply(Module, paths, []),
|
Paths = apply(Module, paths, []),
|
||||||
{ApiSpec, AllRefs} =
|
{ApiSpec, AllRefs} =
|
||||||
lists:foldl(fun(Path, {AllAcc, AllRefsAcc}) ->
|
lists:foldl(fun(Path, {AllAcc, AllRefsAcc}) ->
|
||||||
{OperationId, Specs, Refs} = parse_spec_ref(Module, Path),
|
{OperationId, Specs, Refs} = parse_spec_ref(Module, Path),
|
||||||
{[{Path, Specs, OperationId, ?DEFAULT_FILTER} | AllAcc],
|
CheckSchema = support_check_schema(Options),
|
||||||
|
{[{Path, Specs, OperationId, CheckSchema} | AllAcc],
|
||||||
Refs ++ AllRefsAcc}
|
Refs ++ AllRefsAcc}
|
||||||
end, {[], []}, Paths),
|
end, {[], []}, Paths),
|
||||||
{ApiSpec, components(lists:usort(AllRefs))}.
|
{ApiSpec, components(lists:usort(AllRefs))}.
|
||||||
|
|
||||||
|
|
||||||
-spec(translate_req(#{binding => list(), query_string => list(), body => map()},
|
-spec(translate_req(#{binding => list(), query_string => list(), body => map()},
|
||||||
#{module => module(), path => string(), method => atom()}) ->
|
#{module => module(), path => string(), method => atom()}) ->
|
||||||
{ok, #{binding => list(), query_string => list(), body => map()}}|
|
{ok, #{binding => list(), query_string => list(), body => map()}}|
|
||||||
|
@ -59,6 +73,10 @@ translate_req(Request, #{module := Module, path := Path, method := Method}) ->
|
||||||
{400, 'BAD_REQUEST', iolist_to_binary(io_lib:format("~s : ~p", [Key, Reason]))}
|
{400, 'BAD_REQUEST', iolist_to_binary(io_lib:format("~s : ~p", [Key, Reason]))}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
support_check_schema(#{check_schema := true}) -> ?DEFAULT_FILTER;
|
||||||
|
support_check_schema(#{check_schema := Func})when is_function(Func, 2) -> #{filter => Func};
|
||||||
|
support_check_schema(_) -> #{filter => undefined}.
|
||||||
|
|
||||||
parse_spec_ref(Module, Path) ->
|
parse_spec_ref(Module, Path) ->
|
||||||
Schema =
|
Schema =
|
||||||
try
|
try
|
||||||
|
|
|
@ -162,7 +162,13 @@ t_in_mix_trans_error(_Config) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
t_api_spec(_Config) ->
|
t_api_spec(_Config) ->
|
||||||
emqx_dashboard_swagger:spec(?MODULE),
|
{Spec, _Components} = emqx_dashboard_swagger:spec(?MODULE),
|
||||||
|
Filter = fun(V, S) -> lists:all(fun({_, _, _, #{filter := Filter}}) -> Filter =:= V end, S) end,
|
||||||
|
?assertEqual(true, Filter(undefined, Spec)),
|
||||||
|
{Spec1, _Components1} = emqx_dashboard_swagger:spec(?MODULE, #{check_schema => true}),
|
||||||
|
?assertEqual(true, Filter(fun emqx_dashboard_swagger:translate_req/2, Spec1)),
|
||||||
|
{Spec2, _Components2} = emqx_dashboard_swagger:spec(?MODULE, #{check_schema => fun emqx_dashboard_swagger:translate_req/2}),
|
||||||
|
?assertEqual(true, Filter(fun emqx_dashboard_swagger:translate_req/2, Spec2)),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
validate(Path, ExpectParams) ->
|
validate(Path, ExpectParams) ->
|
||||||
|
|
Loading…
Reference in New Issue