| |
| |
| |
| |
| |
| |
| |
| -module(hk_api_util). |
|
|
| -include("hyperkitty.hrl"). |
|
|
| -export([request_id/1, read_json_body/1, reply_json/3, reply_error/3, |
| run_operation/4]). |
|
|
| |
| |
| |
| -spec request_id(cowboy_req:req()) -> binary(). |
| request_id(Req) -> |
| case cowboy_req:header(<<"x-request-id">>, Req) of |
| undefined -> hk_id:new(<<"req">>); |
| Id -> Id |
| end. |
|
|
| -spec read_json_body(cowboy_req:req()) -> {ok, map(), cowboy_req:req()} | {error, term()}. |
| read_json_body(Req) -> |
| case cowboy_req:has_body(Req) of |
| false -> |
| {ok, #{}, Req}; |
| true -> |
| {ok, Body, Req2} = cowboy_req:read_body(Req), |
| try {ok, jsx:decode(Body, [return_maps]), Req2} |
| catch _:_ -> {error, invalid_json} |
| end |
| end. |
|
|
| -spec reply_json(non_neg_integer(), term(), cowboy_req:req()) -> cowboy_req:req(). |
| reply_json(Status, Data, Req) -> |
| cowboy_req:reply(Status, #{<<"content-type">> => <<"application/json">>}, |
| jsx:encode(Data), Req). |
|
|
| -spec reply_error(non_neg_integer(), term(), cowboy_req:req()) -> cowboy_req:req(). |
| reply_error(Status, Reason, Req) -> |
| reply_json(Status, #{error => term_bin(Reason)}, Req). |
|
|
| |
| |
| |
| |
| |
| -spec run_operation(binary(), atom(), fun(() -> {ok, term(), map()} | {error, term()}), |
| cowboy_req:req()) -> cowboy_req:req(). |
| run_operation(Kind, RequestId, Fun, Req) -> |
| hk_operation_store:ensure_table(), |
| Op = hk_operation_store:create(RequestId, Kind, undefined), |
| case Fun() of |
| {ok, Subject, ResultMap} -> |
| hk_operation_store:complete(Op#operation.operation_id, Subject), |
| reply_json(200, #{operation_id => Op#operation.operation_id, |
| request_id => RequestId, |
| status => succeeded, |
| result => ResultMap}, Req); |
| {error, Reason} -> |
| hk_operation_store:fail(Op#operation.operation_id, #{reason => term_bin(Reason)}), |
| reply_json(422, #{operation_id => Op#operation.operation_id, |
| request_id => RequestId, |
| status => failed, |
| error => term_bin(Reason)}, Req) |
| end. |
| |
| term_bin(Term) when is_binary(Term) -> Term; |
| term_bin(Term) -> iolist_to_binary(io_lib:format("~p", [Term])). |
| |