Current section
Files
Jump to
Current section
Files
src/elli_swagger_handler.erl
-module(elli_swagger_handler).
-behaviour(elli_handler).
-define(NOT_FOUND_MESSAGE, "Resource Not Found").
-export([handle/2, handle_event/3]).
-callback elli_swagger_config() -> elli_swagger:elli_swagger_t().
%% elli
handle(Req, PathConfig) ->
Method = elli_request:method(Req),
Path = elli_request:path(Req),
handle_docs_request(Method, Path, PathConfig).
handle_event(_Atom, _Req, _Config) ->
ignore.
%% internal functions
handle_docs_request('GET', [<<"api-docs">>], _PathConfiguration) ->
{302, [{<<"Location">>, <<"/api-docs/index.html">>}], <<"">>};
handle_docs_request('GET', [<<"api-docs">>, <<"swagger.json">>], PathConfiguration) ->
{ok, [{<<"Content-Type">>, <<"application/json">>}], fetch_documentation_from_configuration(PathConfiguration)};
handle_docs_request('GET', [<<"api-docs">>, Filename], _PathConfiguration) ->
StringFilename = binary_to_list(Filename),
case elli_swagger_file:file_exists("swagger", StringFilename) of
true ->
{ok, [], {file, "swagger/"++StringFilename}};
false ->
{404, [], ?NOT_FOUND_MESSAGE}
end;
handle_docs_request(_Method, _Path, _PathConfiguration) ->
ignore. % Redirect to some other module
fetch_documentation_from_configuration(PathConfiguration) ->
SwaggerMetadata = application:get_env(elli_swagger,
swagger_metadata,
#{openapi => <<"3.0.0">>}),
BuiltDocumentation =
maps:fold(fun(Key, #{metadata := Metadata}, Acc) ->
Path = [<<"/">> | lists:join(<<"/">>, Key)],
Acc#{list_to_binary(Path) => Metadata}
end,
#{}, PathConfiguration),
jsx:encode(maps:merge(SwaggerMetadata, #{paths => BuiltDocumentation})).