You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
One of the popular OpenAPI generators creates per codegen a file called RequestBuilder, for example:
# NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).# https://openapi-generator.tech# Do not edit the class manually.defmoduleOpenAPIPetstore.RequestBuilderdo@moduledoc""" Helper functions for building Tesla requests """@doc""" Specify the request method when building a request ## Parameters - request (Map) - Collected request options - m (atom) - Request method ## Returns Map """@specmethod(map(),atom)::map()defmethod(request,m)doMap.put_new(request,:method,m)end@doc""" Specify the request method when building a request ## Parameters - request (Map) - Collected request options - u (String) - Request URL ## Returns Map """@specurl(map(),String.t)::map()defurl(request,u)doMap.put_new(request,:url,u)end@doc""" Add optional parameters to the request ## Parameters - request (Map) - Collected request options - definitions (Map) - Map of parameter name to parameter location. - options (KeywordList) - The provided optional parameters ## Returns Map """@specadd_optional_params(map(),%{optional(atom)=>atom},keyword())::map()defadd_optional_params(request,_,[]),do: requestdefadd_optional_params(request,definitions,[{key,value}|tail])docasedefinitionsdo%{^key=>location}->request|>add_param(location,key,value)|>add_optional_params(definitions,tail)_->add_optional_params(request,definitions,tail)endend@doc""" Add optional parameters to the request ## Parameters - request (Map) - Collected request options - location (atom) - Where to put the parameter - key (atom) - The name of the parameter - value (any) - The value of the parameter ## Returns Map """@specadd_param(map(),atom,atom,any())::map()defadd_param(request,:body,:body,value),do: Map.put(request,:body,value)defadd_param(request,:body,key,value)dorequest|>Map.put_new_lazy(:body,&Tesla.Multipart.new/0)|>Map.update!(:body,&(Tesla.Multipart.add_field(&1,key,Poison.encode!(value),headers: [{:"Content-Type","application/json"}])))enddefadd_param(request,:headers,key,value)dorequest|>Tesla.put_header(key,value)enddefadd_param(request,:file,name,path)dorequest|>Map.put_new_lazy(:body,&Tesla.Multipart.new/0)|>Map.update!(:body,&(Tesla.Multipart.add_file(&1,path,name: name)))enddefadd_param(request,:form,name,value)dorequest|>Map.update(:body,%{name=>value},&(Map.put(&1,name,value)))enddefadd_param(request,location,key,value)doMap.update(request,location,[{key,value}],&(&1++[{key,value}]))end@doc""" Due to a bug in httpc, POST, PATCH and PUT requests will fail, if the body is empty This function will ensure, that the body param is always set ## Parameters - request (Map) - Collected request options ## Returns Map """@specensure_body(map())::map()defensure_body(%{body: nil}=request)do%{request|body: ""}enddefensure_body(request)doMap.put_new(request,:body,"")end@doc""" Handle the response for a Tesla request ## Parameters - arg1 (Tesla.Env.t | term) - The response object - arg2 (:false | struct | [struct]) - The shape of the struct to deserialize into ## Returns {:ok, struct} on success {:error, term} on failure """@specdecode(Tesla.Env.t()|term(),false|struct()|[struct()])::{:ok,struct()}|{:ok,Tesla.Env.t()}|{:error,any}defdecode(%Tesla.Env{}=env,false),do: {:ok,env}defdecode(%Tesla.Env{body: body},struct),do: Poison.decode(body,as: struct)defevaluate_response({:ok,%Tesla.Env{}=env},mapping)doresolve_mapping(env,mapping)enddefevaluate_response({:error,_}=error,_),do: errordefresolve_mapping(env,mapping,default\\nil)defresolve_mapping(%Tesla.Env{status: status}=env,[{mapping_status,struct}|_],_)whenstatus==mapping_statusdodecode(env,struct)enddefresolve_mapping(env,[{:default,struct}|tail],_),do: resolve_mapping(env,tail,struct)defresolve_mapping(env,[_|tail],struct),do: resolve_mapping(env,tail,struct)defresolve_mapping(env,[],nil),do: {:error,env}defresolve_mapping(env,[],struct),do: decode(env,struct)end
I also keep copying the same exact code whenever I can relate to it,
# NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).# https://openapi-generator.tech# Do not edit the class manually.defmoduleOpenAPIPetstore.Api.Storedo@moduledoc""" API calls for all endpoints tagged `Store`. """aliasOpenAPIPetstore.ConnectionimportOpenAPIPetstore.RequestBuilder@doc""" Delete purchase order by ID For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors ## Parameters - connection (OpenAPIPetstore.Connection): Connection to server - order_id (String.t): ID of the order that needs to be deleted - opts (KeywordList): [optional] Optional parameters ## Returns {:ok, nil} on success {:error, Tesla.Env.t} on failure """@specdelete_order(Tesla.Env.client,String.t,keyword())::{:ok,nil}|{:error,Tesla.Env.t}defdelete_order(connection,order_id,_opts\\[])do%{}|>method(:delete)|>url("/store/order/#{order_id}")|>Enum.into([])|>(&Connection.request(connection,&1)).()|>evaluate_response([{400,false},{404,false}])end@doc""" Returns pet inventories by status Returns a map of status codes to quantities ## Parameters - connection (OpenAPIPetstore.Connection): Connection to server - opts (KeywordList): [optional] Optional parameters ## Returns {:ok, %{}} on success {:error, Tesla.Env.t} on failure """@specget_inventory(Tesla.Env.client,keyword())::{:ok,map()}|{:error,Tesla.Env.t}defget_inventory(connection,_opts\\[])do%{}|>method(:get)|>url("/store/inventory")|>Enum.into([])|>(&Connection.request(connection,&1)).()|>evaluate_response([{200,%{}}])end@doc""" Find purchase order by ID For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions ## Parameters - connection (OpenAPIPetstore.Connection): Connection to server - order_id (integer()): ID of pet that needs to be fetched - opts (KeywordList): [optional] Optional parameters ## Returns {:ok, OpenAPIPetstore.Model.Order.t} on success {:error, Tesla.Env.t} on failure """@specget_order_by_id(Tesla.Env.client,integer(),keyword())::{:ok,nil}|{:ok,OpenAPIPetstore.Model.Order.t}|{:error,Tesla.Env.t}defget_order_by_id(connection,order_id,_opts\\[])do%{}|>method(:get)|>url("/store/order/#{order_id}")|>Enum.into([])|>(&Connection.request(connection,&1)).()|>evaluate_response([{200,%OpenAPIPetstore.Model.Order{}},{400,false},{404,false}])end@doc""" Place an order for a pet ## Parameters - connection (OpenAPIPetstore.Connection): Connection to server - order (Order): order placed for purchasing the pet - opts (KeywordList): [optional] Optional parameters ## Returns {:ok, OpenAPIPetstore.Model.Order.t} on success {:error, Tesla.Env.t} on failure """@specplace_order(Tesla.Env.client,OpenAPIPetstore.Model.Order.t,keyword())::{:ok,nil}|{:ok,OpenAPIPetstore.Model.Order.t}|{:error,Tesla.Env.t}defplace_order(connection,order,_opts\\[])do%{}|>method(:post)|>url("/store/order")|>add_param(:body,:body,order)|>Enum.into([])|>(&Connection.request(connection,&1)).()|>evaluate_response([{200,%OpenAPIPetstore.Model.Order{}},{400,false}])endend
It would be prudent to try to add something similar to Tesla. The intention is to have some pipelining of composing a request without caring too much about the underline data type of the request.
This discussion was converted from issue #531 on April 08, 2023 23:05.
Heading
Bold
Italic
Quote
Code
Link
Numbered list
Unordered list
Task list
Attach files
Mention
Reference
Menu
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Context
One of the popular OpenAPI generators creates per codegen a file called
RequestBuilder
, for example:I also keep copying the same exact code whenever I can relate to it,
My version is much simpler based on my needs, but it morph based on the use case.
The intention behind these modules is to give a declarative pipelining to put together some request.
Example:
Or from the codegen
Proposal
It would be prudent to try to add something similar to Tesla. The intention is to have some pipelining of composing a request without caring too much about the underline data type of the request.
Beta Was this translation helpful? Give feedback.
All reactions