Добавлен Swagger #20
This commit is contained in:
96
src/handlers/swagger_docs_handler.erl
Normal file
96
src/handlers/swagger_docs_handler.erl
Normal file
@@ -0,0 +1,96 @@
|
||||
-module(swagger_docs_handler).
|
||||
-behaviour(cowboy_handler).
|
||||
|
||||
-export([init/2]).
|
||||
|
||||
init(Req, _Opts) ->
|
||||
Path = cowboy_req:path(Req),
|
||||
handle(Path, Req).
|
||||
|
||||
handle(<<"/">>, Req) ->
|
||||
serve_index(Req);
|
||||
handle(<<"/admin">>, Req) ->
|
||||
redirect_to_slash(<<"/admin/">>, Req);
|
||||
handle(<<"/admin/">>, Req) ->
|
||||
serve_ui(admin, Req);
|
||||
handle(<<"/admin/swagger.json">>, Req) ->
|
||||
serve_json(admin, Req);
|
||||
handle(<<"/client">>, Req) ->
|
||||
redirect_to_slash(<<"/client/">>, Req);
|
||||
handle(<<"/client/">>, Req) ->
|
||||
serve_ui(client, Req);
|
||||
handle(<<"/client/swagger.json">>, Req) ->
|
||||
serve_json(client, Req);
|
||||
handle(_, Req) ->
|
||||
cowboy_req:reply(404, #{}, <<"Not Found">>, Req),
|
||||
{ok, [], []}.
|
||||
|
||||
%% Главная страница с выбором API
|
||||
serve_index(Req) ->
|
||||
Html = <<"<!DOCTYPE html>
|
||||
<html>
|
||||
<head><title>EventHub API Docs</title></head>
|
||||
<body>
|
||||
<h1>EventHub API Documentation</h1>
|
||||
<ul>
|
||||
<li><a href=\"/admin/\">Admin API</a></li>
|
||||
<li><a href=\"/client/\">Client API</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>">>,
|
||||
cowboy_req:reply(200, #{<<"content-type">> => <<"text/html">>}, Html, Req),
|
||||
{ok, Html, []}.
|
||||
|
||||
%% Swagger UI для конкретного API
|
||||
serve_ui(Api, Req) ->
|
||||
{Title, SpecUrl} = case Api of
|
||||
admin -> {<<"EventHub Admin API">>, <<"/admin/swagger.json">>};
|
||||
client -> {<<"EventHub Client API">>, <<"/client/swagger.json">>}
|
||||
end,
|
||||
Html = iolist_to_binary([
|
||||
"<!DOCTYPE html><html><head><title>", Title,
|
||||
"</title><link rel=\"stylesheet\" href=\"https://unpkg.com/swagger-ui-dist@5/swagger-ui.css\">",
|
||||
"</head><body><div id=\"swagger-ui\"></div>",
|
||||
"<script src=\"https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js\"></script>",
|
||||
"<script>window.onload=function(){SwaggerUIBundle({url:'", SpecUrl,
|
||||
"',dom_id:'#swagger-ui',presets:[SwaggerUIBundle.presets.apis,SwaggerUIBundle.SwaggerUIStandalonePreset],layout:'BaseLayout'});}</script>",
|
||||
"</body></html>"
|
||||
]),
|
||||
cowboy_req:reply(200, #{<<"content-type">> => <<"text/html">>}, Html, Req),
|
||||
{ok, Html, []}.
|
||||
|
||||
%% Генерация OpenAPI JSON
|
||||
serve_json(Api, Req) ->
|
||||
Trails = case Api of
|
||||
admin -> trails:admin();
|
||||
client -> trails:client()
|
||||
end,
|
||||
OpenApi = #{
|
||||
openapi => <<"3.0.3">>,
|
||||
info => #{
|
||||
title => case Api of
|
||||
admin -> <<"EventHub Admin API">>;
|
||||
client -> <<"EventHub Client API">>
|
||||
end,
|
||||
version => <<"1.0.0">>
|
||||
},
|
||||
servers => [#{url => <<"http://localhost:8445">>, description => <<"API server">>}],
|
||||
paths => build_paths(Trails)
|
||||
},
|
||||
Json = jsx:encode(OpenApi),
|
||||
cowboy_req:reply(200, #{<<"content-type">> => <<"application/json">>}, Json, Req),
|
||||
{ok, Json, []}.
|
||||
|
||||
build_paths(Trails) ->
|
||||
lists:foldl(fun(Trail, Acc) ->
|
||||
Path = maps:get(path, Trail, <<"/">>),
|
||||
Method0 = maps:get(method, Trail, <<"get">>),
|
||||
Method = string:lowercase(Method0),
|
||||
TrailData = maps:without([path, method], Trail),
|
||||
PathItem = #{Method => TrailData},
|
||||
maps:merge_with(fun(_, V1, V2) -> maps:merge(V1, V2) end, Acc, #{Path => PathItem})
|
||||
end, #{}, Trails).
|
||||
|
||||
redirect_to_slash(Location, Req) ->
|
||||
cowboy_req:reply(301, #{<<"location">> => Location}, <<>>, Req),
|
||||
{ok, [], []}.
|
||||
Reference in New Issue
Block a user