Erlang Server – cowboy return types improvements (#19561)

* Declare the correct types for cowboy rest requests

* Adding myself to the erlang team
This commit is contained in:
Nelson Vides 2024-09-12 10:59:06 +02:00 committed by GitHub
parent ca378b424a
commit d02aae7469
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 161 additions and 140 deletions

View File

@ -1074,7 +1074,7 @@ Here is a list of template creators:
* C++ (Qt5 QHttpEngine): @etherealjoy
* C++ Pistache: @sebymiano
* C++ Restbed: @stkrwork
* Erlang Server: @galaxie
* Erlang Server: @galaxie @nelsonvides
* F# (Giraffe) Server: @nmfisher
* Go Server: @guohuang
* Go Server (refactored in 7.0.0): @lwj5
@ -1185,7 +1185,7 @@ If you want to join the committee, please kindly apply by sending an email to te
| Eiffel | @jvelilla (2017/09) |
| Elixir | @mrmstn (2018/12) |
| Elm | @eriktim (2018/09) |
| Erlang | @tsloughter (2017/11) @jfacorro (2018/10) @robertoaloi (2018/10) |
| Erlang | @tsloughter (2017/11) @jfacorro (2018/10) @robertoaloi (2018/10) @nelsonvides (2024/09) |
| F# | @nmfisher (2019/05) |
| Go | @antihax (2017/11) @grokify (2018/07) @kemokemo (2018/09) @jirikuncar (2021/01) @ph4r5h4d (2021/04) @lwj5 (2023/04) |
| GraphQL | @renepardon (2018/12) |

View File

@ -109,21 +109,21 @@ is_authorized(Req, State) ->
-spec delete_resource(cowboy_req:req(), state()) ->
{boolean(), cowboy_req:req(), state()}.
delete_resource(Req, State) ->
case handle_type_accepted(Req, State) of
true ->
{true, Req, State};
_ ->
{false, Req, State}
end.
{Res, Req1, State} = handle_type_accepted(Req, State),
{true =:= Res, Req1, State}.
-spec handle_type_accepted(cowboy_req:req(), state()) ->
boolean() | {created, iodata()} | {see_other, iodata()}.
{ {{packageName}}_logic_handler:accept_callback_return(), cowboy_req:req(), state()}.
handle_type_accepted(Req, #state{operation_id = OperationID,
accept_callback = Handler} = State) ->
Handler({{operations.pathPrefix}}, OperationID, Req, State#state.context).
accept_callback = Handler,
context = Context} = State) ->
{Res, Req1, Context1} = Handler({{operations.pathPrefix}}, OperationID, Req, Context),
{Res, Req1, State#state{context = Context1}}.
-spec handle_type_provided(cowboy_req:req(), state()) ->
{cowboy_req:resp_body(), cowboy_req:req(), {{packageName}}_logic_handler:context()}.
{cowboy_req:resp_body(), cowboy_req:req(), state()}.
handle_type_provided(Req, #state{operation_id = OperationID,
provide_callback = Handler} = State) ->
Handler({{operations.pathPrefix}}, OperationID, Req, State#state.context).
provide_callback = Handler,
context = Context} = State) ->
{Res, Req1, Context1} = Handler({{operations.pathPrefix}}, OperationID, Req, Context),
{Res, Req1, State#state{context = Context1}}.

View File

@ -2,17 +2,24 @@
-include_lib("kernel/include/logger.hrl").
-type accept_callback_return() ::
stop
| boolean()
| {true, iodata()}
| {created, iodata()}
| {see_other, iodata()}.
-type api_key_callback() ::
fun(({{packageName}}_api:operation_id(), binary()) -> {true, context()} | {false, iodata()}).
-type accept_callback() ::
fun((atom(), {{packageName}}_api:operation_id(), cowboy_req:req(), context()) ->
boolean() | {created, iodata()} | {see_other, iodata()}).
{accept_callback_return(), cowboy_req:req(), context()}).
-type provide_callback() ::
fun((atom(), {{packageName}}_api:operation_id(), cowboy_req:req(), context()) ->
{cowboy_req:resp_body(), cowboy_req:req(), context()}).
-type context() :: #{binary() => any()}.
-type context() :: #{_ := _}.
-export_type([context/0, api_key_callback/0, accept_callback/0, provide_callback/0]).
-export_type([context/0, api_key_callback/0,
accept_callback_return/0, accept_callback/0, provide_callback/0]).
-optional_callbacks([api_key_callback/2]).
@ -20,7 +27,7 @@
{true, context()} | {false, iodata()}.
-callback accept_callback(atom(), {{packageName}}_api:operation_id(), cowboy_req:req(), context()) ->
boolean() | {created, iodata()} | {see_other, iodata()}.
{accept_callback_return(), cowboy_req:req(), context()}.
-callback provide_callback(atom(), {{packageName}}_api:operation_id(), cowboy_req:req(), context()) ->
{cowboy_req:resp_body(), cowboy_req:req(), context()}.
@ -36,14 +43,14 @@ api_key_callback(OperationID, ApiKey) ->
{true, #{}}.
-spec accept_callback(atom(), {{packageName}}_api:operation_id(), cowboy_req:req(), context()) ->
{cowboy:http_status(), cowboy:http_headers(), json:encode_value()}.
{accept_callback_return(), cowboy_req:req(), context()}.
accept_callback(Class, OperationID, Req, Context) ->
?LOG_ERROR(#{what => "Got not implemented request to process",
class => Class,
operation_id => OperationID,
request => Req,
context => Context}),
{501, #{}, #{}}.
{false, Req, Context}.
-spec provide_callback(atom(), {{packageName}}_api:operation_id(), cowboy_req:req(), context()) ->
{cowboy_req:resp_body(), cowboy_req:req(), context()}.

View File

@ -106,21 +106,21 @@ content_types_provided(Req, State) ->
-spec delete_resource(cowboy_req:req(), state()) ->
{boolean(), cowboy_req:req(), state()}.
delete_resource(Req, State) ->
case handle_type_accepted(Req, State) of
true ->
{true, Req, State};
_ ->
{false, Req, State}
end.
{Res, Req1, State} = handle_type_accepted(Req, State),
{true =:= Res, Req1, State}.
-spec handle_type_accepted(cowboy_req:req(), state()) ->
boolean() | {created, iodata()} | {see_other, iodata()}.
{ openapi_logic_handler:accept_callback_return(), cowboy_req:req(), state()}.
handle_type_accepted(Req, #state{operation_id = OperationID,
accept_callback = Handler} = State) ->
Handler(auth, OperationID, Req, State#state.context).
accept_callback = Handler,
context = Context} = State) ->
{Res, Req1, Context1} = Handler(auth, OperationID, Req, Context),
{Res, Req1, State#state{context = Context1}}.
-spec handle_type_provided(cowboy_req:req(), state()) ->
{cowboy_req:resp_body(), cowboy_req:req(), openapi_logic_handler:context()}.
{cowboy_req:resp_body(), cowboy_req:req(), state()}.
handle_type_provided(Req, #state{operation_id = OperationID,
provide_callback = Handler} = State) ->
Handler(auth, OperationID, Req, State#state.context).
provide_callback = Handler,
context = Context} = State) ->
{Res, Req1, Context1} = Handler(auth, OperationID, Req, Context),
{Res, Req1, State#state{context = Context1}}.

View File

@ -186,21 +186,21 @@ content_types_provided(Req, State) ->
-spec delete_resource(cowboy_req:req(), state()) ->
{boolean(), cowboy_req:req(), state()}.
delete_resource(Req, State) ->
case handle_type_accepted(Req, State) of
true ->
{true, Req, State};
_ ->
{false, Req, State}
end.
{Res, Req1, State} = handle_type_accepted(Req, State),
{true =:= Res, Req1, State}.
-spec handle_type_accepted(cowboy_req:req(), state()) ->
boolean() | {created, iodata()} | {see_other, iodata()}.
{ openapi_logic_handler:accept_callback_return(), cowboy_req:req(), state()}.
handle_type_accepted(Req, #state{operation_id = OperationID,
accept_callback = Handler} = State) ->
Handler(body, OperationID, Req, State#state.context).
accept_callback = Handler,
context = Context} = State) ->
{Res, Req1, Context1} = Handler(body, OperationID, Req, Context),
{Res, Req1, State#state{context = Context1}}.
-spec handle_type_provided(cowboy_req:req(), state()) ->
{cowboy_req:resp_body(), cowboy_req:req(), openapi_logic_handler:context()}.
{cowboy_req:resp_body(), cowboy_req:req(), state()}.
handle_type_provided(Req, #state{operation_id = OperationID,
provide_callback = Handler} = State) ->
Handler(body, OperationID, Req, State#state.context).
provide_callback = Handler,
context = Context} = State) ->
{Res, Req1, Context1} = Handler(body, OperationID, Req, Context),
{Res, Req1, State#state{context = Context1}}.

View File

@ -104,21 +104,21 @@ content_types_provided(Req, State) ->
-spec delete_resource(cowboy_req:req(), state()) ->
{boolean(), cowboy_req:req(), state()}.
delete_resource(Req, State) ->
case handle_type_accepted(Req, State) of
true ->
{true, Req, State};
_ ->
{false, Req, State}
end.
{Res, Req1, State} = handle_type_accepted(Req, State),
{true =:= Res, Req1, State}.
-spec handle_type_accepted(cowboy_req:req(), state()) ->
boolean() | {created, iodata()} | {see_other, iodata()}.
{ openapi_logic_handler:accept_callback_return(), cowboy_req:req(), state()}.
handle_type_accepted(Req, #state{operation_id = OperationID,
accept_callback = Handler} = State) ->
Handler(form, OperationID, Req, State#state.context).
accept_callback = Handler,
context = Context} = State) ->
{Res, Req1, Context1} = Handler(form, OperationID, Req, Context),
{Res, Req1, State#state{context = Context1}}.
-spec handle_type_provided(cowboy_req:req(), state()) ->
{cowboy_req:resp_body(), cowboy_req:req(), openapi_logic_handler:context()}.
{cowboy_req:resp_body(), cowboy_req:req(), state()}.
handle_type_provided(Req, #state{operation_id = OperationID,
provide_callback = Handler} = State) ->
Handler(form, OperationID, Req, State#state.context).
provide_callback = Handler,
context = Context} = State) ->
{Res, Req1, Context1} = Handler(form, OperationID, Req, Context),
{Res, Req1, State#state{context = Context1}}.

View File

@ -78,21 +78,21 @@ content_types_provided(Req, State) ->
-spec delete_resource(cowboy_req:req(), state()) ->
{boolean(), cowboy_req:req(), state()}.
delete_resource(Req, State) ->
case handle_type_accepted(Req, State) of
true ->
{true, Req, State};
_ ->
{false, Req, State}
end.
{Res, Req1, State} = handle_type_accepted(Req, State),
{true =:= Res, Req1, State}.
-spec handle_type_accepted(cowboy_req:req(), state()) ->
boolean() | {created, iodata()} | {see_other, iodata()}.
{ openapi_logic_handler:accept_callback_return(), cowboy_req:req(), state()}.
handle_type_accepted(Req, #state{operation_id = OperationID,
accept_callback = Handler} = State) ->
Handler(header, OperationID, Req, State#state.context).
accept_callback = Handler,
context = Context} = State) ->
{Res, Req1, Context1} = Handler(header, OperationID, Req, Context),
{Res, Req1, State#state{context = Context1}}.
-spec handle_type_provided(cowboy_req:req(), state()) ->
{cowboy_req:resp_body(), cowboy_req:req(), openapi_logic_handler:context()}.
{cowboy_req:resp_body(), cowboy_req:req(), state()}.
handle_type_provided(Req, #state{operation_id = OperationID,
provide_callback = Handler} = State) ->
Handler(header, OperationID, Req, State#state.context).
provide_callback = Handler,
context = Context} = State) ->
{Res, Req1, Context1} = Handler(header, OperationID, Req, Context),
{Res, Req1, State#state{context = Context1}}.

View File

@ -2,17 +2,24 @@
-include_lib("kernel/include/logger.hrl").
-type accept_callback_return() ::
stop
| boolean()
| {true, iodata()}
| {created, iodata()}
| {see_other, iodata()}.
-type api_key_callback() ::
fun((openapi_api:operation_id(), binary()) -> {true, context()} | {false, iodata()}).
-type accept_callback() ::
fun((atom(), openapi_api:operation_id(), cowboy_req:req(), context()) ->
boolean() | {created, iodata()} | {see_other, iodata()}).
{accept_callback_return(), cowboy_req:req(), context()}).
-type provide_callback() ::
fun((atom(), openapi_api:operation_id(), cowboy_req:req(), context()) ->
{cowboy_req:resp_body(), cowboy_req:req(), context()}).
-type context() :: #{binary() => any()}.
-type context() :: #{_ := _}.
-export_type([context/0, api_key_callback/0, accept_callback/0, provide_callback/0]).
-export_type([context/0, api_key_callback/0,
accept_callback_return/0, accept_callback/0, provide_callback/0]).
-optional_callbacks([api_key_callback/2]).
@ -20,7 +27,7 @@
{true, context()} | {false, iodata()}.
-callback accept_callback(atom(), openapi_api:operation_id(), cowboy_req:req(), context()) ->
boolean() | {created, iodata()} | {see_other, iodata()}.
{accept_callback_return(), cowboy_req:req(), context()}.
-callback provide_callback(atom(), openapi_api:operation_id(), cowboy_req:req(), context()) ->
{cowboy_req:resp_body(), cowboy_req:req(), context()}.
@ -36,14 +43,14 @@ api_key_callback(OperationID, ApiKey) ->
{true, #{}}.
-spec accept_callback(atom(), openapi_api:operation_id(), cowboy_req:req(), context()) ->
{cowboy:http_status(), cowboy:http_headers(), json:encode_value()}.
{accept_callback_return(), cowboy_req:req(), context()}.
accept_callback(Class, OperationID, Req, Context) ->
?LOG_ERROR(#{what => "Got not implemented request to process",
class => Class,
operation_id => OperationID,
request => Req,
context => Context}),
{501, #{}, #{}}.
{false, Req, Context}.
-spec provide_callback(atom(), openapi_api:operation_id(), cowboy_req:req(), context()) ->
{cowboy_req:resp_body(), cowboy_req:req(), context()}.

View File

@ -78,21 +78,21 @@ content_types_provided(Req, State) ->
-spec delete_resource(cowboy_req:req(), state()) ->
{boolean(), cowboy_req:req(), state()}.
delete_resource(Req, State) ->
case handle_type_accepted(Req, State) of
true ->
{true, Req, State};
_ ->
{false, Req, State}
end.
{Res, Req1, State} = handle_type_accepted(Req, State),
{true =:= Res, Req1, State}.
-spec handle_type_accepted(cowboy_req:req(), state()) ->
boolean() | {created, iodata()} | {see_other, iodata()}.
{ openapi_logic_handler:accept_callback_return(), cowboy_req:req(), state()}.
handle_type_accepted(Req, #state{operation_id = OperationID,
accept_callback = Handler} = State) ->
Handler(path, OperationID, Req, State#state.context).
accept_callback = Handler,
context = Context} = State) ->
{Res, Req1, Context1} = Handler(path, OperationID, Req, Context),
{Res, Req1, State#state{context = Context1}}.
-spec handle_type_provided(cowboy_req:req(), state()) ->
{cowboy_req:resp_body(), cowboy_req:req(), openapi_logic_handler:context()}.
{cowboy_req:resp_body(), cowboy_req:req(), state()}.
handle_type_provided(Req, #state{operation_id = OperationID,
provide_callback = Handler} = State) ->
Handler(path, OperationID, Req, State#state.context).
provide_callback = Handler,
context = Context} = State) ->
{Res, Req1, Context1} = Handler(path, OperationID, Req, Context),
{Res, Req1, State#state{context = Context1}}.

View File

@ -168,21 +168,21 @@ content_types_provided(Req, State) ->
-spec delete_resource(cowboy_req:req(), state()) ->
{boolean(), cowboy_req:req(), state()}.
delete_resource(Req, State) ->
case handle_type_accepted(Req, State) of
true ->
{true, Req, State};
_ ->
{false, Req, State}
end.
{Res, Req1, State} = handle_type_accepted(Req, State),
{true =:= Res, Req1, State}.
-spec handle_type_accepted(cowboy_req:req(), state()) ->
boolean() | {created, iodata()} | {see_other, iodata()}.
{ openapi_logic_handler:accept_callback_return(), cowboy_req:req(), state()}.
handle_type_accepted(Req, #state{operation_id = OperationID,
accept_callback = Handler} = State) ->
Handler(query, OperationID, Req, State#state.context).
accept_callback = Handler,
context = Context} = State) ->
{Res, Req1, Context1} = Handler(query, OperationID, Req, Context),
{Res, Req1, State#state{context = Context1}}.
-spec handle_type_provided(cowboy_req:req(), state()) ->
{cowboy_req:resp_body(), cowboy_req:req(), openapi_logic_handler:context()}.
{cowboy_req:resp_body(), cowboy_req:req(), state()}.
handle_type_provided(Req, #state{operation_id = OperationID,
provide_callback = Handler} = State) ->
Handler(query, OperationID, Req, State#state.context).
provide_callback = Handler,
context = Context} = State) ->
{Res, Req1, Context1} = Handler(query, OperationID, Req, Context),
{Res, Req1, State#state{context = Context1}}.

View File

@ -2,17 +2,24 @@
-include_lib("kernel/include/logger.hrl").
-type accept_callback_return() ::
stop
| boolean()
| {true, iodata()}
| {created, iodata()}
| {see_other, iodata()}.
-type api_key_callback() ::
fun((openapi_api:operation_id(), binary()) -> {true, context()} | {false, iodata()}).
-type accept_callback() ::
fun((atom(), openapi_api:operation_id(), cowboy_req:req(), context()) ->
boolean() | {created, iodata()} | {see_other, iodata()}).
{accept_callback_return(), cowboy_req:req(), context()}).
-type provide_callback() ::
fun((atom(), openapi_api:operation_id(), cowboy_req:req(), context()) ->
{cowboy_req:resp_body(), cowboy_req:req(), context()}).
-type context() :: #{binary() => any()}.
-type context() :: #{_ := _}.
-export_type([context/0, api_key_callback/0, accept_callback/0, provide_callback/0]).
-export_type([context/0, api_key_callback/0,
accept_callback_return/0, accept_callback/0, provide_callback/0]).
-optional_callbacks([api_key_callback/2]).
@ -20,7 +27,7 @@
{true, context()} | {false, iodata()}.
-callback accept_callback(atom(), openapi_api:operation_id(), cowboy_req:req(), context()) ->
boolean() | {created, iodata()} | {see_other, iodata()}.
{accept_callback_return(), cowboy_req:req(), context()}.
-callback provide_callback(atom(), openapi_api:operation_id(), cowboy_req:req(), context()) ->
{cowboy_req:resp_body(), cowboy_req:req(), context()}.
@ -36,14 +43,14 @@ api_key_callback(OperationID, ApiKey) ->
{true, #{}}.
-spec accept_callback(atom(), openapi_api:operation_id(), cowboy_req:req(), context()) ->
{cowboy:http_status(), cowboy:http_headers(), json:encode_value()}.
{accept_callback_return(), cowboy_req:req(), context()}.
accept_callback(Class, OperationID, Req, Context) ->
?LOG_ERROR(#{what => "Got not implemented request to process",
class => Class,
operation_id => OperationID,
request => Req,
context => Context}),
{501, #{}, #{}}.
{false, Req, Context}.
-spec provide_callback(atom(), openapi_api:operation_id(), cowboy_req:req(), context()) ->
{cowboy_req:resp_body(), cowboy_req:req(), context()}.

View File

@ -231,21 +231,21 @@ content_types_provided(Req, State) ->
-spec delete_resource(cowboy_req:req(), state()) ->
{boolean(), cowboy_req:req(), state()}.
delete_resource(Req, State) ->
case handle_type_accepted(Req, State) of
true ->
{true, Req, State};
_ ->
{false, Req, State}
end.
{Res, Req1, State} = handle_type_accepted(Req, State),
{true =:= Res, Req1, State}.
-spec handle_type_accepted(cowboy_req:req(), state()) ->
boolean() | {created, iodata()} | {see_other, iodata()}.
{ openapi_logic_handler:accept_callback_return(), cowboy_req:req(), state()}.
handle_type_accepted(Req, #state{operation_id = OperationID,
accept_callback = Handler} = State) ->
Handler(pet, OperationID, Req, State#state.context).
accept_callback = Handler,
context = Context} = State) ->
{Res, Req1, Context1} = Handler(pet, OperationID, Req, Context),
{Res, Req1, State#state{context = Context1}}.
-spec handle_type_provided(cowboy_req:req(), state()) ->
{cowboy_req:resp_body(), cowboy_req:req(), openapi_logic_handler:context()}.
{cowboy_req:resp_body(), cowboy_req:req(), state()}.
handle_type_provided(Req, #state{operation_id = OperationID,
provide_callback = Handler} = State) ->
Handler(pet, OperationID, Req, State#state.context).
provide_callback = Handler,
context = Context} = State) ->
{Res, Req1, Context1} = Handler(pet, OperationID, Req, Context),
{Res, Req1, State#state{context = Context1}}.

View File

@ -119,21 +119,21 @@ content_types_provided(Req, State) ->
-spec delete_resource(cowboy_req:req(), state()) ->
{boolean(), cowboy_req:req(), state()}.
delete_resource(Req, State) ->
case handle_type_accepted(Req, State) of
true ->
{true, Req, State};
_ ->
{false, Req, State}
end.
{Res, Req1, State} = handle_type_accepted(Req, State),
{true =:= Res, Req1, State}.
-spec handle_type_accepted(cowboy_req:req(), state()) ->
boolean() | {created, iodata()} | {see_other, iodata()}.
{ openapi_logic_handler:accept_callback_return(), cowboy_req:req(), state()}.
handle_type_accepted(Req, #state{operation_id = OperationID,
accept_callback = Handler} = State) ->
Handler(store, OperationID, Req, State#state.context).
accept_callback = Handler,
context = Context} = State) ->
{Res, Req1, Context1} = Handler(store, OperationID, Req, Context),
{Res, Req1, State#state{context = Context1}}.
-spec handle_type_provided(cowboy_req:req(), state()) ->
{cowboy_req:resp_body(), cowboy_req:req(), openapi_logic_handler:context()}.
{cowboy_req:resp_body(), cowboy_req:req(), state()}.
handle_type_provided(Req, #state{operation_id = OperationID,
provide_callback = Handler} = State) ->
Handler(store, OperationID, Req, State#state.context).
provide_callback = Handler,
context = Context} = State) ->
{Res, Req1, Context1} = Handler(store, OperationID, Req, Context),
{Res, Req1, State#state{context = Context1}}.

View File

@ -200,21 +200,21 @@ content_types_provided(Req, State) ->
-spec delete_resource(cowboy_req:req(), state()) ->
{boolean(), cowboy_req:req(), state()}.
delete_resource(Req, State) ->
case handle_type_accepted(Req, State) of
true ->
{true, Req, State};
_ ->
{false, Req, State}
end.
{Res, Req1, State} = handle_type_accepted(Req, State),
{true =:= Res, Req1, State}.
-spec handle_type_accepted(cowboy_req:req(), state()) ->
boolean() | {created, iodata()} | {see_other, iodata()}.
{ openapi_logic_handler:accept_callback_return(), cowboy_req:req(), state()}.
handle_type_accepted(Req, #state{operation_id = OperationID,
accept_callback = Handler} = State) ->
Handler(user, OperationID, Req, State#state.context).
accept_callback = Handler,
context = Context} = State) ->
{Res, Req1, Context1} = Handler(user, OperationID, Req, Context),
{Res, Req1, State#state{context = Context1}}.
-spec handle_type_provided(cowboy_req:req(), state()) ->
{cowboy_req:resp_body(), cowboy_req:req(), openapi_logic_handler:context()}.
{cowboy_req:resp_body(), cowboy_req:req(), state()}.
handle_type_provided(Req, #state{operation_id = OperationID,
provide_callback = Handler} = State) ->
Handler(user, OperationID, Req, State#state.context).
provide_callback = Handler,
context = Context} = State) ->
{Res, Req1, Context1} = Handler(user, OperationID, Req, Context),
{Res, Req1, State#state{context = Context1}}.