require "json" require "../handler" require "../api/*" private macro define_method_calls(hash) case namespace {% for namespace, methods in hash %} when "{{ namespace.id }}" case method {% for method in methods %} when "{{ method }}" do_{{ namespace.id }}_{{ method }}(context, get_method_args( context.request.query_params, "{{ namespace.id }}", "{{ method.id }}" )).to_json {% end %} else raise "unknown method" end {% end %} else raise "unknown namespace" end end class Guff::Handlers::APIHandler < Guff::Handler include API::Methods include API::ContentType include API::Util include API::PostAPI include API::DirAPI include API::FileAPI include API::TagAPI include API::SiteAPI include API::TestAPI PATH_RE = %r{ ^/api (?: # method call (?: / (?[a-z0-9_-]+) / (?[a-z0-9_]+) ) | # index.html /(?:index(?:\.html|)|) | # implicit index (no trailing slash) ) $ }mx def call(context : HTTP::Server::Context) if md = (context.request.path || "").match(PATH_RE) if md["namespace"]? # method call do_call(context, md["namespace"], md["method"]) else # api index do_docs(context) end else call_next(context) end end private def do_call( context : HTTP::Server::Context, namespace : String, method : String ) # set response type context.response.content_type = get_content_type # method call json = begin # # macro expands to equivalent of the following for each # namespace and method: # # args = get_method_args(context, namespace, method) # send("do_#{namespace}_#{method}".intern, context, args) # define_method_calls({ post: [ get_posts, add_post, update_post, remove_posts, set_tags, ], dir: [ add, remove, ], file: [ add, remove, ], tag: [ get_tags, remove_tags, ], site: [ add_site, remove_sites, set_default, set_domains, ], test: [ version, get_posts, error, ], }) rescue e # log backtrace # FIXME puts e.inspect_with_backtrace # return error to user { "error": e.to_s }.to_json end # send body context.response.puts json end private def do_docs(context : HTTP::Server::Context) APIDocsHTMLView.run(context) end end