Skip to content

Commit

Permalink
Support openapi 3.0.0 'components' section
Browse files Browse the repository at this point in the history
  • Loading branch information
brucify committed Dec 16, 2019
1 parent 5c4cd20 commit fe4d3f0
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 7 deletions.
67 changes: 62 additions & 5 deletions src/cowboy_swagger.erl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,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]).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Types.
Expand Down Expand Up @@ -68,6 +69,12 @@
-type metadata() :: trails:metadata(swagger_map()).
-export_type([swagger_map/0, metadata/0]).

-define(SWAGGER_2_0, swagger_2_0).
-define(OPENAPI_3_0_0, openapi_3_0_0).
-type swagger_version() :: ?SWAGGER_2_0
| ?OPENAPI_3_0_0.
-export_type([swagger_version/0]).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Public API.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Expand Down Expand Up @@ -107,16 +114,19 @@ add_definition(Name, Properties) ->
ok.
add_definition(Definition) ->
CurrentSpec = application:get_env(cowboy_swagger, global_spec, #{}),
ExistingDefinitions = maps:get(definitions, CurrentSpec, #{}),
NewSpec = CurrentSpec#{definitions => maps:merge( ExistingDefinitions
, Definition
)},
ExistingDefinitions = get_existing_definitions(CurrentSpec),
NewSpec = prepare_new_global_spec(CurrentSpec, Definition, ExistingDefinitions),
application:set_env(cowboy_swagger, global_spec, NewSpec).

-spec schema(DefinitionName::parameter_definition_name()) ->
map().
schema(DefinitionName) ->
#{<<"$ref">> => <<"#/definitions/", DefinitionName/binary>>}.
case swagger_version() of
?SWAGGER_2_0 ->
#{<<"$ref">> => <<"#/definitions/", DefinitionName/binary>>};
?OPENAPI_3_0_0 ->
#{<<"$ref">> => <<"#/components/schemas/", DefinitionName/binary>>}
end.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Expand Down Expand Up @@ -156,10 +166,34 @@ filter_cowboy_swagger_handler(Trails) ->
end,
lists:filter(F, Trails).

-spec get_existing_definitions(CurrentSpec :: map()) ->
Definition :: parameters_definitions()
| parameters_definition_array().
get_existing_definitions(CurrentSpec) ->
case swagger_version() of
?SWAGGER_2_0 ->
maps:get(definitions, CurrentSpec, #{});
?OPENAPI_3_0_0 ->
case CurrentSpec of
#{components :=
#{schemas := Schemas }} -> Schemas;
_Other -> #{}
end
end.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Private API.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% @private
-spec swagger_version() -> swagger_version().
swagger_version() ->
case application:get_env(cowboy_swagger, global_spec, #{}) of
#{openapi := "3.0.0"} -> ?OPENAPI_3_0_0;
#{swagger := "2.0"} -> ?SWAGGER_2_0;
_Other -> ?SWAGGER_2_0
end.

%% @private
is_visible(_Method, Metadata) ->
not maps:get(hidden, Metadata, false).
Expand Down Expand Up @@ -263,3 +297,26 @@ build_definition_array(Name, Properties) ->
}
}}.

%% @private
-spec prepare_new_global_spec( CurrentSpec :: map()
, Definition :: parameters_definitions()
| parameters_definition_array()
, ExistingDefinitions :: parameters_definitions()
| parameters_definition_array()
) ->
NewSpec :: map().
prepare_new_global_spec(CurrentSpec, Definition, ExistingDefinitions) ->
case swagger_version() of
?SWAGGER_2_0 ->
CurrentSpec#{definitions => maps:merge( ExistingDefinitions
, Definition
)
};
?OPENAPI_3_0_0 ->
CurrentSpec#{components =>
#{ schemas => maps:merge( ExistingDefinitions
, Definition
)
}
}
end.
4 changes: 2 additions & 2 deletions test/cowboy_swagger_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ add_definition_test(_Config) ->
%% Then
%%
{ok, SwaggerSpec1} = application:get_env(cowboy_swagger, global_spec),
JsonDefinitions = maps:get(definitions, SwaggerSpec1),
JsonDefinitions = cowboy_swagger:get_existing_definitions(SwaggerSpec1),
true = maps:is_key(Name1, JsonDefinitions),
true = maps:is_key(Name2, JsonDefinitions),

Expand Down Expand Up @@ -189,7 +189,7 @@ add_definition_array_test(_Config) ->
%% Then
%%
{ok, SwaggerSpec1} = application:get_env(cowboy_swagger, global_spec),
JsonDefinitions = maps:get(definitions, SwaggerSpec1),
JsonDefinitions = cowboy_swagger:get_existing_definitions(SwaggerSpec1),
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)),
Expand Down

0 comments on commit fe4d3f0

Please sign in to comment.