Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[erlang-client] fix URL paths #14988

Merged
merged 1 commit into from Mar 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -21,14 +21,14 @@
Cfg = maps:get(cfg, Optional, application:get_env({{packageName}}_api, config, #{})),

Method = {{httpMethod}},
Path = ["{{{replacedPathName}}}"],
Path = [?BASE_URL, "{{{replacedPathName}}}"],
QS = {{#queryParams.isEmpty}}[]{{/queryParams.isEmpty}}{{^queryParams.isEmpty}}lists:flatten([{{#joinWithComma}}{{#queryParams}}{{#required}}{{#qsEncode}}{{this}}{{/qsEncode}} {{/required}}{{/queryParams}}{{/joinWithComma}}])++{{packageName}}_utils:optional_params([{{#joinWithComma}}{{#queryParams}}{{^required}} '{{baseName}}'{{/required}}{{/queryParams}}{{/joinWithComma}}], _OptionalParams){{/queryParams.isEmpty}},
Headers = {{#headerParams.isEmpty}}[]{{/headerParams.isEmpty}}{{^headerParams.isEmpty}}[{{#headerParams}}{{#required}} {<<"{{baseName}}">>, {{paramName}}}{{/required}}{{/headerParams}}]++{{packageName}}_utils:optional_params([{{#joinWithComma}}{{#headerParams}}{{^required}} '{{baseName}}'{{/required}}{{/headerParams}}{{/joinWithComma}}], _OptionalParams){{/headerParams.isEmpty}},
Body1 = {{^formParams.isEmpty}}{form, [{{#joinWithComma}}{{#formParams}}{{#required}} {<<"{{baseName}}">>, {{paramName}}}{{/required}}{{/formParams}}{{/joinWithComma}}]++{{packageName}}_utils:optional_params([{{#joinWithComma}}{{#formParams}}{{^required}} '{{baseName}}'{{/required}}{{/formParams}}{{/joinWithComma}}], _OptionalParams)}{{/formParams.isEmpty}}{{#formParams.isEmpty}}{{#bodyParams.isEmpty}}[]{{/bodyParams.isEmpty}}{{^bodyParams.isEmpty}}{{#bodyParams}}{{paramName}}{{/bodyParams}}{{/bodyParams.isEmpty}}{{/formParams.isEmpty}},
ContentTypeHeader = {{packageName}}_utils:select_header_content_type([{{#consumes}}{{^-first}}, {{/-first}}<<"{{mediaType}}">>{{/consumes}}]),
Opts = maps:get(hackney_opts, Optional, []),

{{packageName}}_utils:request(Ctx, Method, [?BASE_URL, Path], QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).
{{packageName}}_utils:request(Ctx, Method, Path, QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).

{{/operation}}

Expand Down
Expand Up @@ -11,7 +11,8 @@
request(_Ctx, Method, Path, QS, Headers, Body, Opts, Cfg) ->
{Headers1, QS1} = update_params_with_auth(Cfg, Headers, QS),
Host = maps:get(host, Cfg, "localhost:8001"),
Url = hackney_url:make_url(Host, Path, QS1),
Path1 = prepare_path(Path),
Url = hackney_url:make_url(Host, Path1, QS1),

ConfigHackneyOpts = maps:get(hackney_opts, Cfg, []),
Body1 = case lists:keyfind(<<"Content-Type">>, 1, Headers1) of
Expand All @@ -38,6 +39,14 @@ request(_Ctx, Method, Path, QS, Headers, Body, Opts, Cfg) ->
headers => RespHeaders}}
end.

prepare_path(Path) ->
lists:map(fun convert/1, Path).

convert(PathPart) when is_integer(PathPart) ->
integer_to_binary(PathPart);
convert(PathPart) when is_list(PathPart) or is_binary(PathPart) ->
PathPart.

decode_response(Headers, Body) ->
case lists:keyfind(<<"Content-Type">>, 1, Headers) of
{_, <<"application/json", _/binary>>} ->
Expand Down
@@ -1 +1 @@
6.5.0-SNAPSHOT
5.3.0-SNAPSHOT
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like your fix is not based on the latest master. i'll update the samples after merging this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 hrm I thought I had branched off of the latest master. is there something I should normally do when switching to the master branch to make sure the correct version is used normally?

37 changes: 21 additions & 16 deletions samples/client/petstore/erlang-client/src/petstore_pet_api.erl
Expand Up @@ -12,6 +12,7 @@
-define(BASE_URL, <<"/v2">>).

%% @doc Add a new pet to the store
%%
-spec add_pet(ctx:ctx(), petstore_pet:petstore_pet()) -> {ok, petstore_pet:petstore_pet(), petstore_utils:response_info()} | {ok, hackney:client_ref()} | {error, term(), petstore_utils:response_info()}.
add_pet(Ctx, PetstorePet) ->
add_pet(Ctx, PetstorePet, #{}).
Expand All @@ -22,16 +23,17 @@ add_pet(Ctx, PetstorePet, Optional) ->
Cfg = maps:get(cfg, Optional, application:get_env(petstore_api, config, #{})),

Method = post,
Path = ["/pet"],
Path = [?BASE_URL, "/pet"],
QS = [],
Headers = [],
Body1 = PetstorePet,
ContentTypeHeader = petstore_utils:select_header_content_type([<<"application/json">>, <<"application/xml">>]),
Opts = maps:get(hackney_opts, Optional, []),

petstore_utils:request(Ctx, Method, [?BASE_URL, Path], QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).
petstore_utils:request(Ctx, Method, Path, QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).

%% @doc Deletes a pet
%%
-spec delete_pet(ctx:ctx(), integer()) -> {ok, [], petstore_utils:response_info()} | {ok, hackney:client_ref()} | {error, term(), petstore_utils:response_info()}.
delete_pet(Ctx, PetId) ->
delete_pet(Ctx, PetId, #{}).
Expand All @@ -42,14 +44,14 @@ delete_pet(Ctx, PetId, Optional) ->
Cfg = maps:get(cfg, Optional, application:get_env(petstore_api, config, #{})),

Method = delete,
Path = ["/pet/", PetId, ""],
Path = [?BASE_URL, "/pet/", PetId, ""],
QS = [],
Headers = []++petstore_utils:optional_params(['api_key'], _OptionalParams),
Body1 = [],
ContentTypeHeader = petstore_utils:select_header_content_type([]),
Opts = maps:get(hackney_opts, Optional, []),

petstore_utils:request(Ctx, Method, [?BASE_URL, Path], QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).
petstore_utils:request(Ctx, Method, Path, QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).

%% @doc Finds Pets by status
%% Multiple status values can be provided with comma separated strings
Expand All @@ -63,14 +65,14 @@ find_pets_by_status(Ctx, Status, Optional) ->
Cfg = maps:get(cfg, Optional, application:get_env(petstore_api, config, #{})),

Method = get,
Path = ["/pet/findByStatus"],
Path = [?BASE_URL, "/pet/findByStatus"],
QS = lists:flatten([[{<<"status">>, X} || X <- Status]])++petstore_utils:optional_params([], _OptionalParams),
Headers = [],
Body1 = [],
ContentTypeHeader = petstore_utils:select_header_content_type([]),
Opts = maps:get(hackney_opts, Optional, []),

petstore_utils:request(Ctx, Method, [?BASE_URL, Path], QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).
petstore_utils:request(Ctx, Method, Path, QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).

%% @doc Finds Pets by tags
%% Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
Expand All @@ -84,14 +86,14 @@ find_pets_by_tags(Ctx, Tags, Optional) ->
Cfg = maps:get(cfg, Optional, application:get_env(petstore_api, config, #{})),

Method = get,
Path = ["/pet/findByTags"],
Path = [?BASE_URL, "/pet/findByTags"],
QS = lists:flatten([[{<<"tags">>, X} || X <- Tags]])++petstore_utils:optional_params([], _OptionalParams),
Headers = [],
Body1 = [],
ContentTypeHeader = petstore_utils:select_header_content_type([]),
Opts = maps:get(hackney_opts, Optional, []),

petstore_utils:request(Ctx, Method, [?BASE_URL, Path], QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).
petstore_utils:request(Ctx, Method, Path, QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).

%% @doc Find pet by ID
%% Returns a single pet
Expand All @@ -105,16 +107,17 @@ get_pet_by_id(Ctx, PetId, Optional) ->
Cfg = maps:get(cfg, Optional, application:get_env(petstore_api, config, #{})),

Method = get,
Path = ["/pet/", PetId, ""],
Path = [?BASE_URL, "/pet/", PetId, ""],
QS = [],
Headers = [],
Body1 = [],
ContentTypeHeader = petstore_utils:select_header_content_type([]),
Opts = maps:get(hackney_opts, Optional, []),

petstore_utils:request(Ctx, Method, [?BASE_URL, Path], QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).
petstore_utils:request(Ctx, Method, Path, QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).

%% @doc Update an existing pet
%%
-spec update_pet(ctx:ctx(), petstore_pet:petstore_pet()) -> {ok, petstore_pet:petstore_pet(), petstore_utils:response_info()} | {ok, hackney:client_ref()} | {error, term(), petstore_utils:response_info()}.
update_pet(Ctx, PetstorePet) ->
update_pet(Ctx, PetstorePet, #{}).
Expand All @@ -125,16 +128,17 @@ update_pet(Ctx, PetstorePet, Optional) ->
Cfg = maps:get(cfg, Optional, application:get_env(petstore_api, config, #{})),

Method = put,
Path = ["/pet"],
Path = [?BASE_URL, "/pet"],
QS = [],
Headers = [],
Body1 = PetstorePet,
ContentTypeHeader = petstore_utils:select_header_content_type([<<"application/json">>, <<"application/xml">>]),
Opts = maps:get(hackney_opts, Optional, []),

petstore_utils:request(Ctx, Method, [?BASE_URL, Path], QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).
petstore_utils:request(Ctx, Method, Path, QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).

%% @doc Updates a pet in the store with form data
%%
-spec update_pet_with_form(ctx:ctx(), integer()) -> {ok, [], petstore_utils:response_info()} | {ok, hackney:client_ref()} | {error, term(), petstore_utils:response_info()}.
update_pet_with_form(Ctx, PetId) ->
update_pet_with_form(Ctx, PetId, #{}).
Expand All @@ -145,16 +149,17 @@ update_pet_with_form(Ctx, PetId, Optional) ->
Cfg = maps:get(cfg, Optional, application:get_env(petstore_api, config, #{})),

Method = post,
Path = ["/pet/", PetId, ""],
Path = [?BASE_URL, "/pet/", PetId, ""],
QS = [],
Headers = [],
Body1 = {form, []++petstore_utils:optional_params(['name', 'status'], _OptionalParams)},
ContentTypeHeader = petstore_utils:select_header_content_type([<<"application/x-www-form-urlencoded">>]),
Opts = maps:get(hackney_opts, Optional, []),

petstore_utils:request(Ctx, Method, [?BASE_URL, Path], QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).
petstore_utils:request(Ctx, Method, Path, QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).

%% @doc uploads an image
%%
-spec upload_file(ctx:ctx(), integer()) -> {ok, petstore_api_response:petstore_api_response(), petstore_utils:response_info()} | {ok, hackney:client_ref()} | {error, term(), petstore_utils:response_info()}.
upload_file(Ctx, PetId) ->
upload_file(Ctx, PetId, #{}).
Expand All @@ -165,13 +170,13 @@ upload_file(Ctx, PetId, Optional) ->
Cfg = maps:get(cfg, Optional, application:get_env(petstore_api, config, #{})),

Method = post,
Path = ["/pet/", PetId, "/uploadImage"],
Path = [?BASE_URL, "/pet/", PetId, "/uploadImage"],
QS = [],
Headers = [],
Body1 = {form, []++petstore_utils:optional_params(['additionalMetadata', 'file'], _OptionalParams)},
ContentTypeHeader = petstore_utils:select_header_content_type([<<"multipart/form-data">>]),
Opts = maps:get(hackney_opts, Optional, []),

petstore_utils:request(Ctx, Method, [?BASE_URL, Path], QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).
petstore_utils:request(Ctx, Method, Path, QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).


17 changes: 9 additions & 8 deletions samples/client/petstore/erlang-client/src/petstore_store_api.erl
Expand Up @@ -19,14 +19,14 @@ delete_order(Ctx, OrderId, Optional) ->
Cfg = maps:get(cfg, Optional, application:get_env(petstore_api, config, #{})),

Method = delete,
Path = ["/store/order/", OrderId, ""],
Path = [?BASE_URL, "/store/order/", OrderId, ""],
QS = [],
Headers = [],
Body1 = [],
ContentTypeHeader = petstore_utils:select_header_content_type([]),
Opts = maps:get(hackney_opts, Optional, []),

petstore_utils:request(Ctx, Method, [?BASE_URL, Path], QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).
petstore_utils:request(Ctx, Method, Path, QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).

%% @doc Returns pet inventories by status
%% Returns a map of status codes to quantities
Expand All @@ -40,14 +40,14 @@ get_inventory(Ctx, Optional) ->
Cfg = maps:get(cfg, Optional, application:get_env(petstore_api, config, #{})),

Method = get,
Path = ["/store/inventory"],
Path = [?BASE_URL, "/store/inventory"],
QS = [],
Headers = [],
Body1 = [],
ContentTypeHeader = petstore_utils:select_header_content_type([]),
Opts = maps:get(hackney_opts, Optional, []),

petstore_utils:request(Ctx, Method, [?BASE_URL, Path], QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).
petstore_utils:request(Ctx, Method, Path, QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).

%% @doc Find purchase order by ID
%% For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions
Expand All @@ -61,16 +61,17 @@ get_order_by_id(Ctx, OrderId, Optional) ->
Cfg = maps:get(cfg, Optional, application:get_env(petstore_api, config, #{})),

Method = get,
Path = ["/store/order/", OrderId, ""],
Path = [?BASE_URL, "/store/order/", OrderId, ""],
QS = [],
Headers = [],
Body1 = [],
ContentTypeHeader = petstore_utils:select_header_content_type([]),
Opts = maps:get(hackney_opts, Optional, []),

petstore_utils:request(Ctx, Method, [?BASE_URL, Path], QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).
petstore_utils:request(Ctx, Method, Path, QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).

%% @doc Place an order for a pet
%%
-spec place_order(ctx:ctx(), petstore_order:petstore_order()) -> {ok, petstore_order:petstore_order(), petstore_utils:response_info()} | {ok, hackney:client_ref()} | {error, term(), petstore_utils:response_info()}.
place_order(Ctx, PetstoreOrder) ->
place_order(Ctx, PetstoreOrder, #{}).
Expand All @@ -81,13 +82,13 @@ place_order(Ctx, PetstoreOrder, Optional) ->
Cfg = maps:get(cfg, Optional, application:get_env(petstore_api, config, #{})),

Method = post,
Path = ["/store/order"],
Path = [?BASE_URL, "/store/order"],
QS = [],
Headers = [],
Body1 = PetstoreOrder,
ContentTypeHeader = petstore_utils:select_header_content_type([<<"application/json">>]),
Opts = maps:get(hackney_opts, Optional, []),

petstore_utils:request(Ctx, Method, [?BASE_URL, Path], QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).
petstore_utils:request(Ctx, Method, Path, QS, ContentTypeHeader++Headers, Body1, Opts, Cfg).