Erlang JSON API数据生命周期

时间:2012-11-12 14:32:24

标签: json api erlang

在JSON API中使用Erlang的最佳做法是什么? 我的意思是你如何处理JSON - 逻辑 - 数据库 - 逻辑 - JSON生命周期。您在Erlang应用程序中使用了哪些数据结构,工具和技术?

3 个答案:

答案 0 :(得分:7)

我倾向于在Erlang中使用JSON的两个工具:jsxjiffy。检查两者,因为它们具有稍微不同的特性,具有灵活性和速度。

主要问题是Erlang没有内置字典类型。因此,JSON对象通常表示为属性列表,即

{ a : 10,
  b : 20 }

表示为元组列表:

[{a, 10}, {b, 20}]

这是要注意的主要事项。这也意味着应该尽可能避免使用JSON作为内部表示格式,因为从长远来看它很难处理。

答案 1 :(得分:5)

对于使用JSON,我使用mochijson2和Erlson

mochijson2mochiweb项目的一部分。它是一个稳定的,经过实战考验的纯Erlang实现,具有灵活的JSON解析和生成API。

Erlson为Erlang提供了一个很好的字典语法,在使用JSON时尤其方便。例如:

#[
    foo = 1,
    bar = "some string",
    nested = #[i = 1, b = true]
]

此外,Erlson附带erlson:to_jsonerlson:from_json函数,可使用mochiweb2在Erlson和JSON之间进行转换。

(免责声明:我是Erlson的作者)

答案 2 :(得分:1)

您的问题比目前为止收到的答案要大。但是,对于Manipulating JSON,他们都告诉了您mochijson.erlmochijson2.erl所有这些都带有mochiweb HTTP库。要使用它们,JSON对象表示为Struct对象,如下所示:

In JSON
{"FirstName": "Joshua", "Surname": "Muzaaya"}
In Erlang
{struct,[{<<"FirstName">>,<<"Joshua">>},{<<"Surname">>,<<"Muzaaya">>}]}

要解析和解冻:

JSON_DATA = {"students":[
{"student_number":45,
"details":[{"FirstName": "Joshua", "Surname": "Muzaaya"} ] } ]}
From JSON to Erlang
$> mochijson2:decode(JSON_DATA). {struct,[{<<"students">>, [{struct,[{<<"student_number">>,45}, {<<"details">>, [{struct,[{<<"FirstName">>,<<"Joshua">>}, {<<"Surname">>,<<"Muzaaya">>}]}]}]}]}]}
From Erlang to JSON
$> mochijson2:encode(StructObject).
现在数据库,我不知道你真正想要什么,但通常我们可以通过Mnesia访问API在关键值存储,CouchDBRESTFUL中写入数据。我在Erlang中编写了一个Couchbase Single Server客户端。以下是一些内部函数:
create_database(ServerDomain,DBName)->
    try ibrowse:send_req(ServerDomain ++ DBName,[{"Content-Type",
"application/json"}],put,[]) of
{ok,_,_,Result} -> case proplists:get_value(<<"ok">>,element(2,mochijson2:decode(Result
))) of undefined -> {error,failed}; _ -> ok end; Any -> {error,Any} catch EE:EE2 -> {error,{EE,EE2}} end.
delete_database(ServerDomain,DBName)-> try ibrowse:send_req(ServerDomain ++ DBName,[{"Content-Type","application/json"}],delete,[]) of {ok,_,_,Result} -> case proplists:get_value(<<"ok">>,element(2,mochijson2:decode(Result))) of undefined -> {error,failed}; _ -> ok end; Any -> {error,Any} catch EE:EE2 -> {error,{EE,EE2}} end.
%% read/3 ::= Struct
read(ServerDomain,DBName,DocId)-> try ibrowse:send_req(ServerDomain ++ DBName ++ "/" ++ DocId,[{"Content-Type","application/json"}],get,[]) of
{ok,_,_,Result} -> mochijson2:decode(Result);
Any -> {error,Any} catch EE:EE2 -> {error,{EE,EE2}} end.

%% write/3 ::= [{id,Id::string()},{rev,Rev::string()}]
write(ServerDomain,DBName,DocStruct)-> try ibrowse:send_req(ServerDomain ++ DBName,[{"Content-Type","application/json"}],post,lists:flatten(mochijson:encode(DocStruct))) of
{ok,_,_,Result} -> E = element(2,mochijson2:decode(Result)), case {proplists:get_value(<<"id">>,E),proplists:get_value(<<"rev">>,E)} of {undefined,_} -> {error,E}; {_,undefined} -> {error,E}; {Id,Rev} -> [{id,binary_to_list(Id)},{rev,binary_to_list(Rev)}]
end;
Any -> {error,Any} catch EE:EE2 -> {error,{EE,EE2}} end.

%% remember to specify the '_rev' of recent copy when updating %% update/4 ::= [{id,Id::string()},{rev,Rev::string()}] update(ServerDomain,DBName,DocId,DocStruct)-> try ibrowse:send_req(ServerDomain ++ DBName ++ "/" ++ DocId,[{"Content-Type","application/json"}],put,lists:flatten(mochijson:encode(DocStruct))) of
{ok,_,_,Result} -> E = element(2,mochijson2:decode(Result)), case {proplists:get_value(<<"id">>,E),proplists:get_value(<<"rev">>,E)} of {undefined,_} -> {error,E}; {_,undefined} -> {error,E}; {Id,Rev} -> [{id,binary_to_list(Id)},{rev,binary_to_list(Rev)}]
end;
Any -> {error,Any} catch EE:EE2 -> {error,{EE,EE2}} end.

%% you need to provide the '_rev' of current copy %% of doc to be deleted
delete(ServerDomain,DBName,DocId,Rev)-> try ibrowse:send_req(ServerDomain ++ DBName ++ "/" ++ DocId ++ "?rev=" ++ Rev,[{"Content-Type","application/json"}],delete,[]) of
{ok,_,_,Result} -> E = element(2,mochijson2:decode(Result)), case {proplists:get_value(<<"id">>,E),proplists:get_value(<<"ok">>,E)} of {undefined,_} -> {error,E}; {_,undefined} -> {error,E}; {_Id,_} -> ok
end;
Any -> {error,Any} catch EE:EE2 -> {error,{EE,EE2}} end.

random(ServerDomain,Count) when is_integer(Count)-> try ibrowse:send_req(ServerDomain ++ "_uuids?count=" ++ integer_to_list(Count),[{"Content-Type","application/json"}],get,[]) of {ok,_,_,Result} -> [binary_to_list(Z) || Z <- proplists:get_value(<<"uuids">>,element(2,mochijson2:decode(Result)))]; Any -> {error,Any} catch EE:EE2 -> {error,{EE,EE2}} end.

所以,也许试着打破你的问题。否则,你可以看到上面我正在玩很多JSON。要使用abpve方法,首先要使用户ibrowse正在运行。