diff --git a/rebar.config b/rebar.config index fbc5e68..f2fe4ca 100644 --- a/rebar.config +++ b/rebar.config @@ -80,7 +80,7 @@ {cowboy_swagger_handler, trails, 1}, {cowboy_swagger_json_handler, handle_get, 2}, {cowboy_swagger, add_definition_array, 2}, - {cowboy_swagger, get_existing_definitions, 1}]}. + {cowboy_swagger, get_existing_definitions, 2}]}. %% == Dialyzer == diff --git a/src/cowboy_swagger.erl b/src/cowboy_swagger.erl index 5106ff4..366983f 100644 --- a/src/cowboy_swagger.erl +++ b/src/cowboy_swagger.erl @@ -9,7 +9,7 @@ -export([enc_json/1, dec_json/1]). -export([swagger_paths/1, validate_metadata/1]). -export([filter_cowboy_swagger_handler/1]). --export([get_existing_definitions/1]). +-export([get_existing_definitions/2]). % is_visible is used as a maps:filter/2 predicate, which requires a /2 arity function -hank([{unnecessary_function_arguments, [is_visible/2]}]). @@ -116,12 +116,20 @@ add_definition(Name, Properties) -> ok. add_definition(Definition) -> CurrentSpec = application:get_env(cowboy_swagger, global_spec, #{}), - NewDefinitions = maps:merge( get_existing_definitions(CurrentSpec) + Type = definition_type(Definition), + NewDefinitions = maps:merge( get_existing_definitions(CurrentSpec, Type) , Definition ), - NewSpec = prepare_new_global_spec(CurrentSpec, NewDefinitions), + NewSpec = prepare_new_global_spec(CurrentSpec, NewDefinitions, Type), application:set_env(cowboy_swagger, global_spec, NewSpec). +definition_type(Definition) -> + case maps:values(Definition) of + [#{in := In}] when In =:= query orelse In =:= path orelse In =:= header -> + parameters; + _ -> schemas + end. + -spec schema(DefinitionName::parameter_definition_name()) -> map(). schema(DefinitionName) -> @@ -175,18 +183,18 @@ filter_cowboy_swagger_handler(Trails) -> end, lists:filter(F, Trails). --spec get_existing_definitions(CurrentSpec :: map()) -> +-spec get_existing_definitions(CurrentSpec :: map(), Type :: scheams | parameters) -> Definition :: parameters_definitions() | parameters_definition_array(). -get_existing_definitions(CurrentSpec) -> +get_existing_definitions(CurrentSpec, Type) -> case swagger_version() of swagger_2_0 -> maps:get(definitions, CurrentSpec, #{}); openapi_3_0_0 -> case CurrentSpec of #{components := - #{schemas := Schemas }} -> Schemas; - _Other -> #{} + #{Type := Def }} -> Def; + _Other -> #{} end end. @@ -310,7 +318,7 @@ validate_swagger_map_params(Params) -> ValidateParams = fun(E) -> case maps:get(name, E, undefined) of - undefined -> false; + undefined -> maps:is_key(<<"$ref">>, E); _ -> {true, E#{in => maps:get(in, E, <<"path">>)}} end end, @@ -347,9 +355,10 @@ build_definition_array(Name, Properties) -> -spec prepare_new_global_spec( CurrentSpec :: map() , Definitions :: parameters_definitions() | parameters_definition_array() + , Type ::schemas|parameters ) -> NewSpec :: map(). -prepare_new_global_spec(CurrentSpec, Definitions) -> +prepare_new_global_spec(CurrentSpec, Definitions, Type) -> case swagger_version() of swagger_2_0 -> CurrentSpec#{definitions => Definitions @@ -357,7 +366,7 @@ prepare_new_global_spec(CurrentSpec, Definitions) -> openapi_3_0_0 -> Components = maps:get(components, CurrentSpec, #{}), CurrentSpec#{components => - Components#{ schemas => Definitions + Components#{ Type => Definitions } } end. diff --git a/test/cowboy_swagger_SUITE.erl b/test/cowboy_swagger_SUITE.erl index 4bf7e69..fd6582b 100644 --- a/test/cowboy_swagger_SUITE.erl +++ b/test/cowboy_swagger_SUITE.erl @@ -13,6 +13,7 @@ , add_definition_test/1 , add_definition_array_test/1 , schema_test/1 + , parameters_ref_test/1 ]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -173,6 +174,20 @@ schema_test(_Config) -> {comment, ""}. +-spec parameters_ref_test(Config::cowboy_swagger_test_utils:config()) -> + {comment, string()}. +parameters_ref_test(_Config) -> + set_swagger_version(openapi_3_0_0), + cowboy_swagger:add_definition( + #{<<"page">> => + #{description => <<"results per page (max 100)">>, example => 1, + in => query, name => per_page, + schema => #{example => 1, maximum => 100, minimum => 1, type => integer}}}), + {ok, SwaggerSpec1} = application:get_env(cowboy_swagger, global_spec), + JsonDefinitions = cowboy_swagger:get_existing_definitions(SwaggerSpec1, parameters), + true = maps:is_key(<<"page">>, JsonDefinitions), + {comment, ""}. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Internal functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -208,7 +223,7 @@ perform_add_completed_definition_test() -> %% Then %% {ok, SwaggerSpec1} = application:get_env(cowboy_swagger, global_spec), - JsonDefinitions = cowboy_swagger:get_existing_definitions(SwaggerSpec1), + JsonDefinitions = cowboy_swagger:get_existing_definitions(SwaggerSpec1, schemas), true = maps:is_key(Name1, JsonDefinitions), true = maps:is_key(Name2, JsonDefinitions), ok. @@ -236,7 +251,7 @@ perform_add_definition_test() -> %% Then %% {ok, SwaggerSpec1} = application:get_env(cowboy_swagger, global_spec), - JsonDefinitions = cowboy_swagger:get_existing_definitions(SwaggerSpec1), + JsonDefinitions = cowboy_swagger:get_existing_definitions(SwaggerSpec1, schemas), true = maps:is_key(Name1, JsonDefinitions), true = maps:is_key(Name2, JsonDefinitions), ok. @@ -264,7 +279,7 @@ perform_add_definition_array_test() -> %% Then %% {ok, SwaggerSpec1} = application:get_env(cowboy_swagger, global_spec), - JsonDefinitions = cowboy_swagger:get_existing_definitions(SwaggerSpec1), + JsonDefinitions = cowboy_swagger:get_existing_definitions(SwaggerSpec1, schemas), true = maps:is_key(items, maps:get(Name1, JsonDefinitions)), true = maps:is_key(items, maps:get(Name2, JsonDefinitions)), <<"array">> = maps:get(type, maps:get(Name1, JsonDefinitions)),