From 3d3a30a5337c890ad77c57616b20b04f151a4fd1 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Mon, 27 Nov 2017 00:11:14 -0800 Subject: [PATCH] [Erlang] erlang client: properly handle optional parameters (#7042) * erlang client: properly handle optional parameters * [Erlang Client] handle multiple path params in the same path --- .../languages/ErlangClientCodegen.java | 44 +++++++-- .../main/resources/erlang-client/api.mustache | 24 ++--- .../resources/erlang-client/model.mustache | 8 +- .../src/swagger_api_response.erl | 8 +- .../erlang-client/src/swagger_category.erl | 8 +- .../erlang-client/src/swagger_order.erl | 8 +- .../erlang-client/src/swagger_pet.erl | 8 +- .../erlang-client/src/swagger_pet_api.erl | 90 +++++++++++++------ .../erlang-client/src/swagger_store_api.erl | 38 +++++--- .../erlang-client/src/swagger_tag.erl | 8 +- .../erlang-client/src/swagger_user.erl | 8 +- .../erlang-client/src/swagger_user_api.erl | 66 ++++++++++---- 12 files changed, 214 insertions(+), 104 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ErlangClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ErlangClientCodegen.java index ae4d4c9fad8..d41daa8576c 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ErlangClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ErlangClientCodegen.java @@ -163,10 +163,12 @@ public class ErlangClientCodegen extends DefaultCodegen implements CodegenConfig public String qsEncode(Object o) { String r = new String(); CodegenParameter q = (CodegenParameter) o; - if (q.isListContainer) { - r += "[{<<\"" + q.baseName + "\">>, X} || X <- " + q.paramName + "]"; - } else { - r += "{<<\"" + q.baseName + "\">>, " + q.paramName + "}"; + if (q.required) { + if (q.isListContainer) { + r += "[{<<\"" + q.baseName + "\">>, X} || X <- " + q.paramName + "]"; + } else { + r += "{<<\"" + q.baseName + "\">>, " + q.paramName + "}"; + } } return r; } @@ -257,7 +259,7 @@ public class ErlangClientCodegen extends DefaultCodegen implements CodegenConfig Map operations = (Map) objs.get("operations"); List os = (List) operations.get("operation"); List newOs = new ArrayList(); - Pattern pattern = Pattern.compile("(.*)\\{([^\\}]+)\\}(.*)"); + Pattern pattern = Pattern.compile("\\{([^\\}]+)\\}"); for (CodegenOperation o : os) { // force http method to lower case o.httpMethod = o.httpMethod.toLowerCase(); @@ -270,10 +272,12 @@ public class ErlangClientCodegen extends DefaultCodegen implements CodegenConfig Matcher matcher = pattern.matcher(o.path); StringBuffer buffer = new StringBuffer(); while (matcher.find()) { - String pathTemplateName = matcher.group(2); - matcher.appendReplacement(buffer, "$1" + "\", " + camelize(pathTemplateName) + ", \"" + "$3"); + String pathTemplateName = matcher.group(1); + matcher.appendReplacement(buffer, "\", " + camelize(pathTemplateName) + ", \""); pathTemplateNames.add(pathTemplateName); } + matcher.appendTail(buffer); + ExtendedCodegenOperation eco = new ExtendedCodegenOperation(o); if (buffer.toString().isEmpty()) { eco.setReplacedPathName(o.path); @@ -295,8 +299,26 @@ public class ErlangClientCodegen extends DefaultCodegen implements CodegenConfig this.packageVersion = packageVersion; } - String length(Object o) { - return Integer.toString((((ExtendedCodegenOperation) o).allParams).size()); + String length(Object os) { + int l = 1; + for (CodegenParameter o : ((ExtendedCodegenOperation) os).allParams) { + CodegenParameter q = (CodegenParameter) o; + if (q.required) + l++; + } + + return Integer.toString(l); + } + + int lengthRequired(List allParams) { + int l = 0; + for (CodegenParameter o : allParams) { + CodegenParameter q = (CodegenParameter) o; + if (q.required || q.isBodyParam) + l++; + } + + return l; } @Override @@ -313,6 +335,8 @@ public class ErlangClientCodegen extends DefaultCodegen implements CodegenConfig class ExtendedCodegenOperation extends CodegenOperation { private List pathTemplateNames = new ArrayList(); private String replacedPathName; + String arityRequired; + String arityOptional; public ExtendedCodegenOperation(CodegenOperation o) { super(); @@ -355,6 +379,8 @@ public class ErlangClientCodegen extends DefaultCodegen implements CodegenConfig this.produces = o.produces; this.bodyParam = o.bodyParam; this.allParams = o.allParams; + this.arityRequired = Integer.toString(lengthRequired(o.allParams)); + this.arityOptional = Integer.toString(lengthRequired(o.allParams)+1); this.bodyParams = o.bodyParams; this.pathParams = o.pathParams; this.queryParams = o.queryParams; diff --git a/modules/swagger-codegen/src/main/resources/erlang-client/api.mustache b/modules/swagger-codegen/src/main/resources/erlang-client/api.mustache index a14ee991912..21f040192f0 100644 --- a/modules/swagger-codegen/src/main/resources/erlang-client/api.mustache +++ b/modules/swagger-codegen/src/main/resources/erlang-client/api.mustache @@ -1,23 +1,27 @@ -module({{classname}}_api). -export([{{#operations}}{{#operation}}{{^-first}}, - {{/-first}}{{operationId}}/{{#length}}{{allParams}}{{/length}}{{/operation}}{{/operations}}]). + {{/-first}}{{operationId}}/{{arityRequired}}, {{operationId}}/{{arityOptional}}{{/operation}}{{/operations}}]). -define(BASE_URL, <<"{{{basePath}}}">>). {{#operations}} {{#operation}} -%% @doc {{summary}} +%% @doc {{{summary}}} {{^notes.isEmpty}} -%% {{notes}} +%% {{{notes}}} {{/notes.isEmpty}} --spec {{operationId}}({{#allParams}}{{^-first}}, {{/-first}}{{dataType}}{{/allParams}}) -> {{#returnType}}{ok, list(), {{returnType}}} | {error, string()}{{/returnType}}{{^returnType}}ok | {error, integer()}{{/returnType}}. -{{operationId}}({{#allParams}}{{^-first}}, {{/-first}}{{paramName}}{{/allParams}}) -> +-spec {{operationId}}({{#allParams}}{{#required}}{{^-first}}, {{/-first}}{{{dataType}}}{{/required}}{{/allParams}}{{^bodyParams.isEmpty}}{{#bodyParams}}, term(){{/bodyParams}}{{/bodyParams.isEmpty}}) -> {{#returnType}}{ok, list(), {{{returnType}}}} | {error, string()}{{/returnType}}{{^returnType}}ok | {error, integer()}{{/returnType}}. +{{operationId}}({{#allParams}}{{#required}}{{^-first}}, {{/-first}}{{paramName}}{{/required}}{{/allParams}}{{^bodyParams.isEmpty}}{{#bodyParams}}, {{paramName}}{{/bodyParams}}{{/bodyParams.isEmpty}}) -> + {{operationId}}({{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}{{^bodyParams.isEmpty}}{{#bodyParams}}{{paramName}}, {{/bodyParams}}{{/bodyParams.isEmpty}}#{}). + +-spec {{operationId}}({{#allParams}}{{#required}}{{{dataType}}}, {{/required}}{{/allParams}}{{^bodyParams.isEmpty}}{{#bodyParams}}term(), {{/bodyParams}}{{/bodyParams.isEmpty}}maps:map()) -> {{#returnType}}{ok, list(), {{{returnType}}}} | {error, string()}{{/returnType}}{{^returnType}}ok | {error, integer()}{{/returnType}}. +{{operationId}}({{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}{{^bodyParams.isEmpty}}{{#bodyParams}}{{paramName}}{{/bodyParams}}, {{/bodyParams.isEmpty}}_Optional) -> Method = {{httpMethod}}, Path = ["{{{replacedPathName}}}"], - QS = {{#queryParams.isEmpty}}[]{{/queryParams.isEmpty}}{{^queryParams.isEmpty}}lists:flatten([{{#queryParams}}{{^-first}}, {{/-first}}{{#qsEncode}}{{this}}{{/qsEncode}}{{/queryParams}}]){{/queryParams.isEmpty}}, - Headers = [{{^headerParams.isEmpty}}{{#headerParams}}{{^-first}}, {{/-first}}{<<"{{baseName}}">>, {{paramName}}}{{/headerParams}}{{/headerParams.isEmpty}}], - Body1 = {{^formParams.isEmpty}}{form, [{{#formParams}}{{^-first}}, {{/-first}}{<<"{{baseName}}">>, {{paramName}}}{{/formParams}}]}{{/formParams.isEmpty}}{{#formParams.isEmpty}}{{#bodyParams.isEmpty}}[]{{/bodyParams.isEmpty}}{{^bodyParams.isEmpty}}{{#bodyParams}}{{paramName}}{{/bodyParams}}{{/bodyParams.isEmpty}}{{/formParams.isEmpty}}, + QS = {{#queryParams.isEmpty}}[]{{/queryParams.isEmpty}}{{^queryParams.isEmpty}}lists:flatten([{{#queryParams}}{{#required}}{{^-first}}, {{/-first}}{{#qsEncode}}{{this}}{{/qsEncode}}{{/required}}{{/queryParams}}])++[{X, maps:get(X, _Optional)} || X <- [{{#queryParams}}{{^required}}{{^-first}}, {{/-first}}'{{baseName}}'{{/required}}{{/queryParams}}], maps:is_key(X, _Optional)]{{/queryParams.isEmpty}}, + Headers = {{#headerParams.isEmpty}}[]{{/headerParams.isEmpty}}{{^headerParams.isEmpty}}[{{#headerParams}}{{#required}}{{^-first}}, {{/-first}}{<<"{{baseName}}">>, {{paramName}}}{{/required}}{{/headerParams}}]++[{X, maps:get(X, _Optional)} || X <- [{{#headerParams}}{{^required}}{{^-first}}, {{/-first}}'{{baseName}}'{{/required}}{{/headerParams}}], maps:is_key(X, _Optional)]{{/headerParams.isEmpty}}, + Body1 = {{^formParams.isEmpty}}{form, [{{#formParams}}{{#required}}{{^-first}}, {{/-first}}{<<"{{baseName}}">>, {{paramName}}}{{/required}}{{/formParams}}]++[{X, maps:get(X, _Optional)} || X <- [{{#formParams}}{{^required}}{{^-first}}, {{/-first}}'{{baseName}}'{{/required}}{{/formParams}}], maps:is_key(X, _Optional)]}{{/formParams.isEmpty}}{{#formParams.isEmpty}}{{#bodyParams.isEmpty}}[]{{/bodyParams.isEmpty}}{{^bodyParams.isEmpty}}{{#bodyParams}}{{paramName}}{{/bodyParams}}{{/bodyParams.isEmpty}}{{/formParams.isEmpty}}, Opts = [], Url = hackney_url:make_url(?BASE_URL, Path, QS), @@ -26,8 +30,8 @@ {{#responses}} {{#isDefault}} {ok, {{code}}, RespHeaders, ClientRef} -> - {ok, Body} = hackney:body(ClientRef), - {ok, RespHeaders, jsx:decode(Body, [returns_maps, {labels, attempt_atom}])}{{#hasMore}}; {{/hasMore}} + {ok, ResponseBody} = hackney:body(ClientRef), + {ok, RespHeaders, jsx:decode(ResponseBody, [return_maps])}{{#hasMore}}; {{/hasMore}} {{/isDefault}} {{^isDefault}} {ok, {{code}}, _RespHeaders, _ClientRef} -> diff --git a/modules/swagger-codegen/src/main/resources/erlang-client/model.mustache b/modules/swagger-codegen/src/main/resources/erlang-client/model.mustache index da0e8672ca0..79db4433316 100644 --- a/modules/swagger-codegen/src/main/resources/erlang-client/model.mustache +++ b/modules/swagger-codegen/src/main/resources/erlang-client/model.mustache @@ -2,9 +2,9 @@ {{#model}} -module({{classname}}). --export_type([{{classname}}/0, - encode/1, - decode/1]). +-export([encode/1]). + +-export_type([{{classname}}/0]). -type {{classname}}() :: #{ {{#vars}}'{{name}}' {{#required}}:={{/required}}{{^required}}=>{{/required}} {{{datatype}}}{{#hasMore}}, @@ -16,6 +16,6 @@ encode(#{ {{#vars}}'{{name}}' := {{{nameInCamelCase}}}{{#hasMore}}, }) -> #{ {{#vars}}'{{baseName}}' => {{{nameInCamelCase}}}{{#hasMore}}, {{/hasMore}}{{/vars}} - } + }. {{/model}} {{/models}} diff --git a/samples/client/petstore/erlang-client/src/swagger_api_response.erl b/samples/client/petstore/erlang-client/src/swagger_api_response.erl index 33826528dc4..6457d81358f 100644 --- a/samples/client/petstore/erlang-client/src/swagger_api_response.erl +++ b/samples/client/petstore/erlang-client/src/swagger_api_response.erl @@ -1,8 +1,8 @@ -module(swagger_api_response). --export_type([swagger_api_response/0, - encode/1, - decode/1]). +-export([encode/1]). + +-export_type([swagger_api_response/0]). -type swagger_api_response() :: #{ 'code' => integer(), @@ -17,4 +17,4 @@ encode(#{ 'code' := Code, #{ 'code' => Code, 'type' => Type, 'message' => Message - } + }. diff --git a/samples/client/petstore/erlang-client/src/swagger_category.erl b/samples/client/petstore/erlang-client/src/swagger_category.erl index 0bd89b55087..7019ba681a8 100644 --- a/samples/client/petstore/erlang-client/src/swagger_category.erl +++ b/samples/client/petstore/erlang-client/src/swagger_category.erl @@ -1,8 +1,8 @@ -module(swagger_category). --export_type([swagger_category/0, - encode/1, - decode/1]). +-export([encode/1]). + +-export_type([swagger_category/0]). -type swagger_category() :: #{ 'id' => integer(), @@ -14,4 +14,4 @@ encode(#{ 'id' := Id, }) -> #{ 'id' => Id, 'name' => Name - } + }. diff --git a/samples/client/petstore/erlang-client/src/swagger_order.erl b/samples/client/petstore/erlang-client/src/swagger_order.erl index 06a9a1a270a..057727f6cfc 100644 --- a/samples/client/petstore/erlang-client/src/swagger_order.erl +++ b/samples/client/petstore/erlang-client/src/swagger_order.erl @@ -1,8 +1,8 @@ -module(swagger_order). --export_type([swagger_order/0, - encode/1, - decode/1]). +-export([encode/1]). + +-export_type([swagger_order/0]). -type swagger_order() :: #{ 'id' => integer(), @@ -26,4 +26,4 @@ encode(#{ 'id' := Id, 'shipDate' => ShipDate, 'status' => Status, 'complete' => Complete - } + }. diff --git a/samples/client/petstore/erlang-client/src/swagger_pet.erl b/samples/client/petstore/erlang-client/src/swagger_pet.erl index c9484fa0fea..aa7358c46ca 100644 --- a/samples/client/petstore/erlang-client/src/swagger_pet.erl +++ b/samples/client/petstore/erlang-client/src/swagger_pet.erl @@ -1,8 +1,8 @@ -module(swagger_pet). --export_type([swagger_pet/0, - encode/1, - decode/1]). +-export([encode/1]). + +-export_type([swagger_pet/0]). -type swagger_pet() :: #{ 'id' => integer(), @@ -26,4 +26,4 @@ encode(#{ 'id' := Id, 'photoUrls' => PhotoUrls, 'tags' => Tags, 'status' => Status - } + }. diff --git a/samples/client/petstore/erlang-client/src/swagger_pet_api.erl b/samples/client/petstore/erlang-client/src/swagger_pet_api.erl index 7eaef8fed81..997fd7820b9 100644 --- a/samples/client/petstore/erlang-client/src/swagger_pet_api.erl +++ b/samples/client/petstore/erlang-client/src/swagger_pet_api.erl @@ -1,19 +1,23 @@ -module(swagger_pet_api). --export([add_pet/1, - delete_pet/2, - find_pets_by_status/1, - find_pets_by_tags/1, - get_pet_by_id/1, - update_pet/1, - update_pet_with_form/3, - upload_file/3]). +-export([add_pet/1, add_pet/2, + delete_pet/1, delete_pet/2, + find_pets_by_status/1, find_pets_by_status/2, + find_pets_by_tags/1, find_pets_by_tags/2, + get_pet_by_id/1, get_pet_by_id/2, + update_pet/1, update_pet/2, + update_pet_with_form/1, update_pet_with_form/2, + upload_file/1, upload_file/2]). -define(BASE_URL, <<"http://petstore.swagger.io/v2">>). %% @doc Add a new pet to the store --spec add_pet(swagger_pet:swagger_pet()) -> ok | {error, integer()}. +-spec add_pet(swagger_pet:swagger_pet(), term()) -> ok | {error, integer()}. add_pet(Body) -> + add_pet(Body, Body, #{}). + +-spec add_pet(swagger_pet:swagger_pet(), term(), maps:map()) -> ok | {error, integer()}. +add_pet(Body, Body, _Optional) -> Method = post, Path = ["/pet"], QS = [], @@ -30,12 +34,16 @@ add_pet(Body) -> end. %% @doc Deletes a pet --spec delete_pet(integer(), binary()) -> ok | {error, integer()}. -delete_pet(PetId, ApiKey) -> +-spec delete_pet(integer()) -> ok | {error, integer()}. +delete_pet(PetId) -> + delete_pet(PetId, , #{}). + +-spec delete_pet(integer(), maps:map()) -> ok | {error, integer()}. +delete_pet(PetId, _Optional) -> Method = delete, Path = ["/pet/", PetId, ""], QS = [], - Headers = [{<<"api_key">>, ApiKey}], + Headers = []++[{X, maps:get(X, _Optional)} || X <- ['api_key'], maps:is_key(X, _Optional)], Body1 = [], Opts = [], Url = hackney_url:make_url(?BASE_URL, Path, QS), @@ -51,9 +59,13 @@ delete_pet(PetId, ApiKey) -> %% Multiple status values can be provided with comma separated strings -spec find_pets_by_status(list()) -> {ok, list(), [swagger_pet:swagger_pet()]} | {error, string()}. find_pets_by_status(Status) -> + find_pets_by_status(Status, , #{}). + +-spec find_pets_by_status(list(), maps:map()) -> {ok, list(), [swagger_pet:swagger_pet()]} | {error, string()}. +find_pets_by_status(Status, _Optional) -> Method = get, Path = ["/pet/findByStatus"], - QS = lists:flatten([[{<<"status">>, X} || X <- Status]]), + QS = lists:flatten([[{<<"status">>, X} || X <- Status]])++[{X, maps:get(X, _Optional)} || X <- [], maps:is_key(X, _Optional)], Headers = [], Body1 = [], Opts = [], @@ -61,8 +73,8 @@ find_pets_by_status(Status) -> case hackney:request(Method, Url, Headers, Body1, Opts) of {ok, 200, RespHeaders, ClientRef} -> - {ok, Body} = hackney:body(ClientRef), - {ok, RespHeaders, jsx:decode(Body, [returns_maps, {labels, attempt_atom}])}; + {ok, ResponseBody} = hackney:body(ClientRef), + {ok, RespHeaders, jsx:decode(ResponseBody, [return_maps])}; {ok, 400, _RespHeaders, _ClientRef} -> {error, "Invalid status value"} end. @@ -71,9 +83,13 @@ find_pets_by_status(Status) -> %% Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. -spec find_pets_by_tags(list()) -> {ok, list(), [swagger_pet:swagger_pet()]} | {error, string()}. find_pets_by_tags(Tags) -> + find_pets_by_tags(Tags, , #{}). + +-spec find_pets_by_tags(list(), maps:map()) -> {ok, list(), [swagger_pet:swagger_pet()]} | {error, string()}. +find_pets_by_tags(Tags, _Optional) -> Method = get, Path = ["/pet/findByTags"], - QS = lists:flatten([[{<<"tags">>, X} || X <- Tags]]), + QS = lists:flatten([[{<<"tags">>, X} || X <- Tags]])++[{X, maps:get(X, _Optional)} || X <- [], maps:is_key(X, _Optional)], Headers = [], Body1 = [], Opts = [], @@ -81,8 +97,8 @@ find_pets_by_tags(Tags) -> case hackney:request(Method, Url, Headers, Body1, Opts) of {ok, 200, RespHeaders, ClientRef} -> - {ok, Body} = hackney:body(ClientRef), - {ok, RespHeaders, jsx:decode(Body, [returns_maps, {labels, attempt_atom}])}; + {ok, ResponseBody} = hackney:body(ClientRef), + {ok, RespHeaders, jsx:decode(ResponseBody, [return_maps])}; {ok, 400, _RespHeaders, _ClientRef} -> {error, "Invalid tag value"} end. @@ -91,6 +107,10 @@ find_pets_by_tags(Tags) -> %% Returns a single pet -spec get_pet_by_id(integer()) -> {ok, list(), swagger_pet:swagger_pet()} | {error, string()}. get_pet_by_id(PetId) -> + get_pet_by_id(PetId, , #{}). + +-spec get_pet_by_id(integer(), maps:map()) -> {ok, list(), swagger_pet:swagger_pet()} | {error, string()}. +get_pet_by_id(PetId, _Optional) -> Method = get, Path = ["/pet/", PetId, ""], QS = [], @@ -101,8 +121,8 @@ get_pet_by_id(PetId) -> case hackney:request(Method, Url, Headers, Body1, Opts) of {ok, 200, RespHeaders, ClientRef} -> - {ok, Body} = hackney:body(ClientRef), - {ok, RespHeaders, jsx:decode(Body, [returns_maps, {labels, attempt_atom}])}; + {ok, ResponseBody} = hackney:body(ClientRef), + {ok, RespHeaders, jsx:decode(ResponseBody, [return_maps])}; {ok, 400, _RespHeaders, _ClientRef} -> {error, "Invalid ID supplied"}; {ok, 404, _RespHeaders, _ClientRef} -> @@ -110,8 +130,12 @@ get_pet_by_id(PetId) -> end. %% @doc Update an existing pet --spec update_pet(swagger_pet:swagger_pet()) -> ok | {error, integer()}. +-spec update_pet(swagger_pet:swagger_pet(), term()) -> ok | {error, integer()}. update_pet(Body) -> + update_pet(Body, Body, #{}). + +-spec update_pet(swagger_pet:swagger_pet(), term(), maps:map()) -> ok | {error, integer()}. +update_pet(Body, Body, _Optional) -> Method = put, Path = ["/pet"], QS = [], @@ -128,13 +152,17 @@ update_pet(Body) -> end. %% @doc Updates a pet in the store with form data --spec update_pet_with_form(integer(), binary(), binary()) -> ok | {error, integer()}. -update_pet_with_form(PetId, Name, Status) -> +-spec update_pet_with_form(integer()) -> ok | {error, integer()}. +update_pet_with_form(PetId) -> + update_pet_with_form(PetId, , #{}). + +-spec update_pet_with_form(integer(), maps:map()) -> ok | {error, integer()}. +update_pet_with_form(PetId, _Optional) -> Method = post, Path = ["/pet/", PetId, ""], QS = [], Headers = [], - Body1 = {form, [{<<"name">>, Name}, {<<"status">>, Status}]}, + Body1 = {form, []++[{X, maps:get(X, _Optional)} || X <- ['name', 'status'], maps:is_key(X, _Optional)]}, Opts = [], Url = hackney_url:make_url(?BASE_URL, Path, QS), @@ -146,20 +174,24 @@ update_pet_with_form(PetId, Name, Status) -> end. %% @doc uploads an image --spec upload_file(integer(), binary(), binary()) -> {ok, list(), swagger_api_response:swagger_api_response()} | {error, string()}. -upload_file(PetId, AdditionalMetadata, File) -> +-spec upload_file(integer()) -> {ok, list(), swagger_api_response:swagger_api_response()} | {error, string()}. +upload_file(PetId) -> + upload_file(PetId, , #{}). + +-spec upload_file(integer(), maps:map()) -> {ok, list(), swagger_api_response:swagger_api_response()} | {error, string()}. +upload_file(PetId, _Optional) -> Method = post, Path = ["/pet/", PetId, "/uploadImage"], QS = [], Headers = [], - Body1 = {form, [{<<"additionalMetadata">>, AdditionalMetadata}, {<<"file">>, File}]}, + Body1 = {form, []++[{X, maps:get(X, _Optional)} || X <- ['additionalMetadata', 'file'], maps:is_key(X, _Optional)]}, Opts = [], Url = hackney_url:make_url(?BASE_URL, Path, QS), case hackney:request(Method, Url, Headers, Body1, Opts) of {ok, 200, RespHeaders, ClientRef} -> - {ok, Body} = hackney:body(ClientRef), - {ok, RespHeaders, jsx:decode(Body, [returns_maps, {labels, attempt_atom}])} + {ok, ResponseBody} = hackney:body(ClientRef), + {ok, RespHeaders, jsx:decode(ResponseBody, [return_maps])} end. diff --git a/samples/client/petstore/erlang-client/src/swagger_store_api.erl b/samples/client/petstore/erlang-client/src/swagger_store_api.erl index 1061556f5f6..acb72dd415d 100644 --- a/samples/client/petstore/erlang-client/src/swagger_store_api.erl +++ b/samples/client/petstore/erlang-client/src/swagger_store_api.erl @@ -1,9 +1,9 @@ -module(swagger_store_api). --export([delete_order/1, - get_inventory/0, - get_order_by_id/1, - place_order/1]). +-export([delete_order/1, delete_order/2, + get_inventory/0, get_inventory/1, + get_order_by_id/1, get_order_by_id/2, + place_order/1, place_order/2]). -define(BASE_URL, <<"http://petstore.swagger.io/v2">>). @@ -11,6 +11,10 @@ %% For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors -spec delete_order(binary()) -> ok | {error, integer()}. delete_order(OrderId) -> + delete_order(OrderId, , #{}). + +-spec delete_order(binary(), maps:map()) -> ok | {error, integer()}. +delete_order(OrderId, _Optional) -> Method = delete, Path = ["/store/order/", OrderId, ""], QS = [], @@ -30,6 +34,10 @@ delete_order(OrderId) -> %% Returns a map of status codes to quantities -spec get_inventory() -> {ok, list(), maps:map()} | {error, string()}. get_inventory() -> + get_inventory(, #{}). + +-spec get_inventory(maps:map()) -> {ok, list(), maps:map()} | {error, string()}. +get_inventory(_Optional) -> Method = get, Path = ["/store/inventory"], QS = [], @@ -40,14 +48,18 @@ get_inventory() -> case hackney:request(Method, Url, Headers, Body1, Opts) of {ok, 200, RespHeaders, ClientRef} -> - {ok, Body} = hackney:body(ClientRef), - {ok, RespHeaders, jsx:decode(Body, [returns_maps, {labels, attempt_atom}])} + {ok, ResponseBody} = hackney:body(ClientRef), + {ok, RespHeaders, jsx:decode(ResponseBody, [return_maps])} end. %% @doc Find purchase order by ID %% For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions -spec get_order_by_id(integer()) -> {ok, list(), swagger_order:swagger_order()} | {error, string()}. get_order_by_id(OrderId) -> + get_order_by_id(OrderId, , #{}). + +-spec get_order_by_id(integer(), maps:map()) -> {ok, list(), swagger_order:swagger_order()} | {error, string()}. +get_order_by_id(OrderId, _Optional) -> Method = get, Path = ["/store/order/", OrderId, ""], QS = [], @@ -58,8 +70,8 @@ get_order_by_id(OrderId) -> case hackney:request(Method, Url, Headers, Body1, Opts) of {ok, 200, RespHeaders, ClientRef} -> - {ok, Body} = hackney:body(ClientRef), - {ok, RespHeaders, jsx:decode(Body, [returns_maps, {labels, attempt_atom}])}; + {ok, ResponseBody} = hackney:body(ClientRef), + {ok, RespHeaders, jsx:decode(ResponseBody, [return_maps])}; {ok, 400, _RespHeaders, _ClientRef} -> {error, "Invalid ID supplied"}; {ok, 404, _RespHeaders, _ClientRef} -> @@ -67,8 +79,12 @@ get_order_by_id(OrderId) -> end. %% @doc Place an order for a pet --spec place_order(swagger_order:swagger_order()) -> {ok, list(), swagger_order:swagger_order()} | {error, string()}. +-spec place_order(swagger_order:swagger_order(), term()) -> {ok, list(), swagger_order:swagger_order()} | {error, string()}. place_order(Body) -> + place_order(Body, Body, #{}). + +-spec place_order(swagger_order:swagger_order(), term(), maps:map()) -> {ok, list(), swagger_order:swagger_order()} | {error, string()}. +place_order(Body, Body, _Optional) -> Method = post, Path = ["/store/order"], QS = [], @@ -79,8 +95,8 @@ place_order(Body) -> case hackney:request(Method, Url, Headers, Body1, Opts) of {ok, 200, RespHeaders, ClientRef} -> - {ok, Body} = hackney:body(ClientRef), - {ok, RespHeaders, jsx:decode(Body, [returns_maps, {labels, attempt_atom}])}; + {ok, ResponseBody} = hackney:body(ClientRef), + {ok, RespHeaders, jsx:decode(ResponseBody, [return_maps])}; {ok, 400, _RespHeaders, _ClientRef} -> {error, "Invalid Order"} end. diff --git a/samples/client/petstore/erlang-client/src/swagger_tag.erl b/samples/client/petstore/erlang-client/src/swagger_tag.erl index 5abdf9b959f..7f8ab49d9c0 100644 --- a/samples/client/petstore/erlang-client/src/swagger_tag.erl +++ b/samples/client/petstore/erlang-client/src/swagger_tag.erl @@ -1,8 +1,8 @@ -module(swagger_tag). --export_type([swagger_tag/0, - encode/1, - decode/1]). +-export([encode/1]). + +-export_type([swagger_tag/0]). -type swagger_tag() :: #{ 'id' => integer(), @@ -14,4 +14,4 @@ encode(#{ 'id' := Id, }) -> #{ 'id' => Id, 'name' => Name - } + }. diff --git a/samples/client/petstore/erlang-client/src/swagger_user.erl b/samples/client/petstore/erlang-client/src/swagger_user.erl index 8c82c40488e..e00cb98b1e4 100644 --- a/samples/client/petstore/erlang-client/src/swagger_user.erl +++ b/samples/client/petstore/erlang-client/src/swagger_user.erl @@ -1,8 +1,8 @@ -module(swagger_user). --export_type([swagger_user/0, - encode/1, - decode/1]). +-export([encode/1]). + +-export_type([swagger_user/0]). -type swagger_user() :: #{ 'id' => integer(), @@ -32,4 +32,4 @@ encode(#{ 'id' := Id, 'password' => Password, 'phone' => Phone, 'userStatus' => UserStatus - } + }. diff --git a/samples/client/petstore/erlang-client/src/swagger_user_api.erl b/samples/client/petstore/erlang-client/src/swagger_user_api.erl index fe2a84d78a8..837546f27d3 100644 --- a/samples/client/petstore/erlang-client/src/swagger_user_api.erl +++ b/samples/client/petstore/erlang-client/src/swagger_user_api.erl @@ -1,20 +1,24 @@ -module(swagger_user_api). --export([create_user/1, - create_users_with_array_input/1, - create_users_with_list_input/1, - delete_user/1, - get_user_by_name/1, - login_user/2, - logout_user/0, - update_user/2]). +-export([create_user/1, create_user/2, + create_users_with_array_input/1, create_users_with_array_input/2, + create_users_with_list_input/1, create_users_with_list_input/2, + delete_user/1, delete_user/2, + get_user_by_name/1, get_user_by_name/2, + login_user/2, login_user/3, + logout_user/0, logout_user/1, + update_user/2, update_user/3]). -define(BASE_URL, <<"http://petstore.swagger.io/v2">>). %% @doc Create user %% This can only be done by the logged in user. --spec create_user(swagger_user:swagger_user()) -> ok | {error, integer()}. +-spec create_user(swagger_user:swagger_user(), term()) -> ok | {error, integer()}. create_user(Body) -> + create_user(Body, Body, #{}). + +-spec create_user(swagger_user:swagger_user(), term(), maps:map()) -> ok | {error, integer()}. +create_user(Body, Body, _Optional) -> Method = post, Path = ["/user"], QS = [], @@ -31,8 +35,12 @@ create_user(Body) -> end. %% @doc Creates list of users with given input array --spec create_users_with_array_input(list()) -> ok | {error, integer()}. +-spec create_users_with_array_input(list(), term()) -> ok | {error, integer()}. create_users_with_array_input(Body) -> + create_users_with_array_input(Body, Body, #{}). + +-spec create_users_with_array_input(list(), term(), maps:map()) -> ok | {error, integer()}. +create_users_with_array_input(Body, Body, _Optional) -> Method = post, Path = ["/user/createWithArray"], QS = [], @@ -49,8 +57,12 @@ create_users_with_array_input(Body) -> end. %% @doc Creates list of users with given input array --spec create_users_with_list_input(list()) -> ok | {error, integer()}. +-spec create_users_with_list_input(list(), term()) -> ok | {error, integer()}. create_users_with_list_input(Body) -> + create_users_with_list_input(Body, Body, #{}). + +-spec create_users_with_list_input(list(), term(), maps:map()) -> ok | {error, integer()}. +create_users_with_list_input(Body, Body, _Optional) -> Method = post, Path = ["/user/createWithList"], QS = [], @@ -70,6 +82,10 @@ create_users_with_list_input(Body) -> %% This can only be done by the logged in user. -spec delete_user(binary()) -> ok | {error, integer()}. delete_user(Username) -> + delete_user(Username, , #{}). + +-spec delete_user(binary(), maps:map()) -> ok | {error, integer()}. +delete_user(Username, _Optional) -> Method = delete, Path = ["/user/", Username, ""], QS = [], @@ -88,6 +104,10 @@ delete_user(Username) -> %% @doc Get user by user name -spec get_user_by_name(binary()) -> {ok, list(), swagger_user:swagger_user()} | {error, string()}. get_user_by_name(Username) -> + get_user_by_name(Username, , #{}). + +-spec get_user_by_name(binary(), maps:map()) -> {ok, list(), swagger_user:swagger_user()} | {error, string()}. +get_user_by_name(Username, _Optional) -> Method = get, Path = ["/user/", Username, ""], QS = [], @@ -98,8 +118,8 @@ get_user_by_name(Username) -> case hackney:request(Method, Url, Headers, Body1, Opts) of {ok, 200, RespHeaders, ClientRef} -> - {ok, Body} = hackney:body(ClientRef), - {ok, RespHeaders, jsx:decode(Body, [returns_maps, {labels, attempt_atom}])}; + {ok, ResponseBody} = hackney:body(ClientRef), + {ok, RespHeaders, jsx:decode(ResponseBody, [return_maps])}; {ok, 400, _RespHeaders, _ClientRef} -> {error, "Invalid username supplied"}; {ok, 404, _RespHeaders, _ClientRef} -> @@ -109,9 +129,13 @@ get_user_by_name(Username) -> %% @doc Logs user into the system -spec login_user(binary(), binary()) -> {ok, list(), binary()} | {error, string()}. login_user(Username, Password) -> + login_user(Username, Password, , #{}). + +-spec login_user(binary(), binary(), maps:map()) -> {ok, list(), binary()} | {error, string()}. +login_user(Username, Password, _Optional) -> Method = get, Path = ["/user/login"], - QS = lists:flatten([{<<"username">>, Username}, {<<"password">>, Password}]), + QS = lists:flatten([{<<"username">>, Username}, {<<"password">>, Password}])++[{X, maps:get(X, _Optional)} || X <- [], maps:is_key(X, _Optional)], Headers = [], Body1 = [], Opts = [], @@ -119,8 +143,8 @@ login_user(Username, Password) -> case hackney:request(Method, Url, Headers, Body1, Opts) of {ok, 200, RespHeaders, ClientRef} -> - {ok, Body} = hackney:body(ClientRef), - {ok, RespHeaders, jsx:decode(Body, [returns_maps, {labels, attempt_atom}])}; + {ok, ResponseBody} = hackney:body(ClientRef), + {ok, RespHeaders, jsx:decode(ResponseBody, [return_maps])}; {ok, 400, _RespHeaders, _ClientRef} -> {error, "Invalid username/password supplied"} end. @@ -128,6 +152,10 @@ login_user(Username, Password) -> %% @doc Logs out current logged in user session -spec logout_user() -> ok | {error, integer()}. logout_user() -> + logout_user(, #{}). + +-spec logout_user(maps:map()) -> ok | {error, integer()}. +logout_user(_Optional) -> Method = get, Path = ["/user/logout"], QS = [], @@ -145,8 +173,12 @@ logout_user() -> %% @doc Updated user %% This can only be done by the logged in user. --spec update_user(binary(), swagger_user:swagger_user()) -> ok | {error, integer()}. +-spec update_user(binary(), swagger_user:swagger_user(), term()) -> ok | {error, integer()}. update_user(Username, Body) -> + update_user(Username, Body, Body, #{}). + +-spec update_user(binary(), swagger_user:swagger_user(), term(), maps:map()) -> ok | {error, integer()}. +update_user(Username, Body, Body, _Optional) -> Method = put, Path = ["/user/", Username, ""], QS = [],