librelist archives

« back to archive

Consulta implementación

Consulta implementación

From:
Carlos Pantelides
Date:
2012-01-18 @ 15:45
Hola:

En el extracto de código [1], tengo implementado pegarle a una api y 
extraer la respuesta. Se usa asi:


%% version 1

...

Token                   = request_login({{user, User},{password,Password}}),
GroupUsers          = request_group({{token,Token},{group, "users"}}),
GroupDevelopers = request_group({{token,Token},{group, "developers"}}),
...


Como notarán viendo generate_connector() mas abajo, debo hardcodear la Url
en una función de un módulo. La única solución que se me ocurre es algo 
asi como

%% version 2

Url = "https://XXXXX", % u obtenerla de algún modo

...

Conn = generate_connector(Url), 

Token                   = request_login({{user, User},{password,Password}}, Conn),
GroupUsers          = request_group({{token,Token},{group, "users"}}, Conn),
GroupDevelopers = request_group({{token,Token},{group, "developers"}}, Conn),
...


cambiando la implementación apropiadamente.

Pros y contras? A alguien se le ocurre algo mejor?



Muchas gracias anticipadas


[1]

% Devuelve el cuerpo de una respuesta

generate_connector() ->
  fun (Json) -> 
    Url = "https://XXXXXX",
    {ok, {{_HttpVer, _Code, _Msg}, _Headers, Body}} = http:request(post, {
Url, [], "application/json", Json },  [], []),
    Body
  end.


% Genera un match para un formato de respuesta json
generate_match_1() ->
  fun (Body) ->
    {[{<<"id">>,_Id},{<<"result">>,Result},{<<"jsonrpc">>,_JsonRpc}]} = 
json_eep:json_to_term(Body),
    Result
  end.


% Genera otro match para un formato de respuesta json
generate_match_2() ->
  fun (Body) ->
    {[{<<"id">>, 
_Id}|[{<<"result">>,{[{<<"name">>,_Name}|[{<<"users">>,Users}]]}}|[{<<"jsonrpc">>,_JsonRpc}]]]}=json_eep:json_to_term(Body),
    Users
  end.

% 
request_login({{user,User},{password,Password}})->
  Conn = generate_connector(),
  Match = generate_match_1(),
  
binary_to_list(Match(Conn(make_json({{method,"login"},{params,[{user,User},{password,Password}]}})))).


% 

request_group({{token,Token},{group,Group}}) ->
  Conn = generate_connector(),
  Match = generate_match_2(),
  
Match(Conn(make_json({{method,"getGroup"},{params,[{token,Token},{group,Group}]}}))).

 


Carlos Pantelides


-----------------


http://seguridad-agile.blogspot.com/

Re: [erlar] Consulta implementación

From:
Juan Jose Comellas
Date:
2012-01-18 @ 21:49
Lo que yo hago en estos casos es que ese valor sea parte de la
configuración de la aplicación Erlang (ver
http://erldocs.com/R15B/kernel/application.html). Normalmente esta
configuración se graba en un archivo de nombre sys.config o
app.config.

Por ejemplo, si yo tengo una aplicación de nombre 'mlapi', podría
grabar la configuración en un archivo de nombre app.config con el
siguiente formato:

[
 {mlapi, [
          {protocol, "https"},
          {host, "api.mercadolibre.com"},
          {default_format, proplist},
          {cache_ttl, 3600}
        ]}
].

Después tendrías que instanciar la máquina virtual de Erlang en la que
va a correr la aplicación de la siguiente manera (asumiendo que los
.beam están en el subdirectorio 'ebin'):

    # erl -sname mynode -pa ebin -config app

Dentro de la consola de la VM y después de haber iniciado la
aplicación con application:start(mlapi) podría hacer lo siguiente:

    > application:get_env(mlapi, host).

Y obtendría el siguiente resultado:

    {ok,"api.mercadolibre.com"}

Yo normalmente en el módulo principal de mi aplicación creo una
función como ésta para hacer más fácil la obtención de parámetros de
configuración:

-define(APP, mlapi).

-spec get_env(Key :: atom(), Default :: term()) -> term().
get_env(Key, Default) ->
    case application:get_env(?APP, Key) of
        {ok, Value} ->
            Value;
        _ ->
            Default
    end.

Podés ver un ejemplo de todo ésto en este proyecto (que está en
progreso): https://github.com/jcomellas/mlapi

Juanjo


2012/1/18 Carlos Pantelides <carlos_pantelides@yahoo.com>:
> Hola:
>
> En el extracto de código [1], tengo implementado pegarle a una api y extraer
> la respuesta. Se usa asi:
>
> %% version 1
> ...
> Token                   = request_login({{user, User},{password,Password}}),
> GroupUsers          = request_group({{token,Token},{group, "users"}}),
> GroupDevelopers = request_group({{token,Token},{group, "developers"}}),
> ...
>
> Como notarán viendo generate_connector() mas abajo, debo hardcodear la Url
> en una función de un módulo. La única solución que se me ocurre es algo asi
> como
>
> %% version 2
>
> Url = "https://XXXXX", % u obtenerla de algún modo
> ...
> Conn = generate_connector(Url),
>
> Token                   = request_login({{user, User},{password,Password}},
> Conn),
> GroupUsers          = request_group({{token,Token},{group, "users"}}, Conn),
> GroupDevelopers = request_group({{token,Token},{group, "developers"}},
> Conn),
> ...
>
> cambiando la implementación apropiadamente.
>
> Pros y contras? A alguien se le ocurre algo mejor?
>
>
> Muchas gracias anticipadas
>
>
> [1]
> % Devuelve el cuerpo de una respuesta
> generate_connector() ->
>   fun (Json) ->
>     Url = "https://XXXXXX",
>     {ok, {{_HttpVer, _Code, _Msg}, _Headers, Body}} = http:request(post, {
> Url, [], "application/json", Json },  [], []),
>     Body
>   end.
>
> % Genera un match para un formato de respuesta json
> generate_match_1() ->
>   fun (Body) ->
>     {[{<<"id">>,_Id},{<<"result">>,Result},{<<"jsonrpc">>,_JsonRpc}]} =
> json_eep:json_to_term(Body),
>     Result
>   end.
>
> % Genera otro match para un formato de respuesta json
> generate_match_2() ->
>   fun (Body) ->
>     {[{<<"id">>,
> 
_Id}|[{<<"result">>,{[{<<"name">>,_Name}|[{<<"users">>,Users}]]}}|[{<<"jsonrpc">>,_JsonRpc}]]]}=json_eep:json_to_term(Body),
>     Users
>   end.
>
> %
> request_login({{user,User},{password,Password}})->
>   Conn = generate_connector(),
>   Match = generate_match_1(),
>
> 
binary_to_list(Match(Conn(make_json({{method,"login"},{params,[{user,User},{password,Password}]}})))).
>
> %
> request_group({{token,Token},{group,Group}}) ->
>   Conn = generate_connector(),
>   Match = generate_match_2(),
>
> 
Match(Conn(make_json({{method,"getGroup"},{params,[{token,Token},{group,Group}]}}))).
>
>
>
> Carlos Pantelides
>
> -----------------
>
>
> http://seguridad-agile.blogspot.com/

Re: [erlar] Consulta implementación

From:
Mariano Guerra
Date:
2012-01-19 @ 08:11
2012/1/18 Carlos Pantelides <carlos_pantelides@yahoo.com>

> Hola:
>
> En el extracto de código [1], tengo implementado pegarle a una api y
> extraer la respuesta. Se usa asi:
>
> %% version 1
> ...
> Token                   = request_login({{user,
> User},{password,Password}}),
> GroupUsers          = request_group({{token,Token},{group, "users"}}),
> GroupDevelopers = request_group({{token,Token},{group, "developers"}}),
> ...
>
> Como notarán viendo generate_connector() mas abajo, debo hardcodear la
> Url en una función de un módulo. La única solución que se me ocurre es algo
> asi como
>
> %% version 2
>
> Url = "https://XXXXX", % u obtenerla de algún modo
> ...
> Conn = generate_connector(Url),
>
> Token                   = request_login({{user,
> User},{password,Password}}, Conn),
> GroupUsers          = request_group({{token,Token},{group, "users"}}, Conn
> ),
> GroupDevelopers = request_group({{token,Token},{group, "developers"}},
> Conn),
> ...
>
> cambiando la implementación apropiadamente.
>
> Pros y contras? A alguien se le ocurre algo mejor?
>
>
buenas, te tiro algunas ideas que podes llegar a explorar, no te digo que
sean mejores o peores sino que son alternativas.

* usar modulos parametrizados y mantener el estado en el parametro
  + http://myotherpants.com/2009/04/parameterized-modules-in-erlang/
  + http://www.trapexit.org/Parameterized_Modules

* pasar un argumento al principio llamado Ctx o similar que contiene la
configuracion particular que te interesa
  + esto es muy similar a como simular OO en lenguajes como C

* usar una combinacion de -on_load (experimental) y diccionario del proceso
(no bien visto)
  + http://www.erlang.org/doc/reference_manual/code_loading.html seccion
13.4
  + http://www.erlang.org/doc/reference_manual/processes.html seccion 11.9

* levantar un named process al que le das la configuracion y los otros se
la preguntan
  + http://www.erlang.org/doc/reference_manual/processes.html 11.3

esas son las que se me ocurren :P

una pregunta, porque envolves todos los parametros en una tupla con el
nombre? estas intentando simular static typing en un lenguaje dinamico?
el orden de los argumentos deberia darte una idea de que son, si queres
algo mas flexible o nombrado podes usar proplists
http://www.erlang.org/doc/man/proplists.html

saludos y espero que sirva de algo!