在JSON API中使用Erlang的最佳做法是什么? 我的意思是你如何处理JSON - 逻辑 - 数据库 - 逻辑 - JSON生命周期。您在Erlang应用程序中使用了哪些数据结构,工具和技术?
答案 0 :(得分:7)
我倾向于在Erlang中使用JSON的两个工具:jsx
和jiffy
。检查两者,因为它们具有稍微不同的特性,具有灵活性和速度。
主要问题是Erlang没有内置字典类型。因此,JSON对象通常表示为属性列表,即
{ a : 10,
b : 20 }
表示为元组列表:
[{a, 10}, {b, 20}]
这是要注意的主要事项。这也意味着应该尽可能避免使用JSON作为内部表示格式,因为从长远来看它很难处理。
答案 1 :(得分:5)
对于使用JSON,我使用mochijson2和Erlson。
mochijson2
是mochiweb项目的一部分。它是一个稳定的,经过实战考验的纯Erlang实现,具有灵活的JSON解析和生成API。
Erlson为Erlang提供了一个很好的字典语法,在使用JSON时尤其方便。例如:
#[
foo = 1,
bar = "some string",
nested = #[i = 1, b = true]
]
此外,Erlson附带erlson:to_json
和erlson:from_json
函数,可使用mochiweb2
在Erlson和JSON之间进行转换。
(免责声明:我是Erlson的作者)
答案 2 :(得分:1)
您的问题比目前为止收到的答案要大。但是,对于Manipulating JSON,他们都告诉了您mochijson.erl
,mochijson2.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在关键值存储,CouchDB
或RESTFUL
中写入数据。我在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
正在运行。