2012-11-12 43 views
3

在JSON API中使用Erlang的最佳實踐是什麼? 我的意思是你如何處理JSON - 邏輯 - 數據庫 - 邏輯 - JSON生命週期。您在Erlang應用程序中使用了哪些數據結構,工具和技術?Erlang JSON API數據生命週期

回答

7

有兩個工具我傾向於在二郎用於JSON:jsxjiffy。檢查它們,因爲它們具有稍微不同的性質,靈活性和速度。

主要的問題是Erlang沒有內置的字典類型。因此,JSON對象通常表示爲屬性列表,即

{ a : 10, 
    b : 20 } 

表示爲元組的列表:

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

,這是看出來了重大的事情。這也意味着應該儘可能地避免使用JSON作爲內部表示格式,因爲從長遠來看,處理起來很不方便。

+2

另一種選擇是'mochisjon2',它附帶[Mochiweb](https://github.com/mochi/mochiweb)。 [Webmachine](https://github.com/basho/webmachine)基於Mochiweb。 – Tilman

+0

現在呢! Erlang 17 –

+0

@ArthurColléErlang 18,不,它沒有,是的,它有地圖,但它沒有地圖:to_json/1。 – Aus

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功能Erlson和JSON使用mochiweb2之間的轉換。

(免責聲明:我Erlson的作者)

1

你的問題比收到的答案爲止更大。但是,對於操縱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).
現在的數據庫,我不知道你真正想要的,但是,通常情況下,我們可以寫數據在Key Value商店中, MnesiaCouchDB經由 RESTFUL訪問API。我在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正在運行。