Skip to content

Instantly share code, notes, and snippets.

@retgoat
Forked from dry/dispatcher.erl
Last active November 2, 2015 06:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save retgoat/93b4d69c19fbff6bacf4 to your computer and use it in GitHub Desktop.
Save retgoat/93b4d69c19fbff6bacf4 to your computer and use it in GitHub Desktop.
Moochiweb router example
-module (dispatcher).
-export ([dispatch/2, convert_method_to_action/1]).
dispatch(_,[]) -> none;
dispatch(Req, [{Regexp, Handler}|T]) ->
"/" ++ Path = Req:get(path),
Method = Req:get(method),
Match = re:run(Path, Regexp, [global, {capture, all_but_first, list}]),
case Match of
{match, [MatchList]}->
case length(MatchList) of
0 ->
Action = convert_method_to_action(Method),
Handler:Action(Req, []);
% posts_handler:get(Req)
Length when Length > 0 ->
Args = lists:flatten(MatchList),
Action = convert_method_to_action(Method),
Handler:Action(Req, Args)
% posts_handler:get(Req, Args)
end;
_ ->
dispatch(Req, T)
end.
convert_method_to_action(Method) ->
List = atom_to_list(Method),
Action = string:sub_string(List, 1, length(List)),
list_to_atom(string:to_lower(Action)).
-module (posts_handler).
-include_lib("erlang_couchdb.hrl").
-include_lib("headers.hrl").
-compile(export_all).
% Get one doc or all docs from DB
get(Req, Doc_id) ->
case Doc_id of
[] ->
{json, {struct, Data}} = erlang_couchdb:invoke_view(?DB_HOST, ?DB_POSTS_DATABASE, ?DB_POSTS_DOCUMENT_CLASS, ?DB_ALL_POSTS_VIEW, [{"include_docs", "false"}]);
_ ->
{json, {struct, Data}} = erlang_couchdb:retrieve_document(?DB_HOST, ?DB_POSTS_DATABASE, Doc_id)
end,
respond_with_json(Req, Data).
% JSON Responder
respond_with_json(Req, Data) ->
JSON = mochijson2:encode(Data),
Req:respond({200, [{"Content-Type", ?JSON_H}], JSON}).
-module (router).
-export ([urls/0]).
-compile(export_all).
urls() -> [
{"^posts/?$", posts_handler },
{"^posts/(.+?)/?$", posts_handler } % url: /posts/:post_id
].
%% Mochiweb loop
loop(Req, DocRoot) ->
"/" ++ Path = Req:get(path),
try
case dispatcher:dispatch(Req, router:urls()) of
none ->
% No request handler found
Req:not_found();
Response ->
Response
end
catch
Type:What ->
%% Error handling
...
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment