aboutsummaryrefslogtreecommitdiff
path: root/src/guff/api-handler.cr
diff options
context:
space:
mode:
Diffstat (limited to 'src/guff/api-handler.cr')
-rw-r--r--src/guff/api-handler.cr154
1 files changed, 11 insertions, 143 deletions
diff --git a/src/guff/api-handler.cr b/src/guff/api-handler.cr
index 3192447..dce351f 100644
--- a/src/guff/api-handler.cr
+++ b/src/guff/api-handler.cr
@@ -1,5 +1,6 @@
require "json"
require "./handler"
+require "./api-methods"
private macro define_method_calls(hash)
case namespace
@@ -25,64 +26,8 @@ end
module Guff
class APIHandler < Handler
- API = {
- "post": {
- "get_posts": {
- text: "Get posts matching query.",
-
- args: {
- "q": {
- text: "Search string.",
- type: :text,
- required: false,
- default: "",
- },
-
- "page": {
- text: "Page number",
- type: :int,
- required: false,
- default: "1",
- },
-
- "tags": {
- text: "Comma-separated list of tags (union)",
- type: :tags,
- required: false,
- default: "1",
- },
-
- "sort": {
- text: "Sort order of results",
- type: :sort,
- required: false,
- default: "date,desc",
- },
- },
- },
- },
-
- "test": {
- "version": {
- text: "Get version",
- },
-
- "get_posts": {
- text: "Test get posts",
- },
-
- "error": {
- text: "Test error response",
- },
- }
- }
-
- TYPE_CHECKS = {
- text: /.*/,
- int: /^\d+$/,
- tags: /^[a-z0-9_,-]+$/,
- sort: /^[a-z0-9_]+,(?:asc|desc)$/,
- }
+ include APIMethods
+ include APIContentType
PATH_RE = %r{
^/api
@@ -109,54 +54,6 @@ module Guff
$
}mx
- CONTENT_TYPES = {
- "development": "text/html; charset=utf-8",
- "production": "application/json; charset=utf8",
- }
-
- private def get_content_type
- CONTENT_TYPES[@model.config["environment"]]
- end
-
- private def get_method_args(
- params : HTTP::Params,
- namespace : String,
- method : String
- )
- return {} of String => String unless (
- API[namespace]? &&
- API[namespace][method] &&
- API[namespace][method][:args]?
- )
-
- # get method args
- args = API[namespace][method][:args] as \
- Hash(String, Hash(Symbol, String | Symbol | Bool))
-
- args.keys.reduce({} of String => String) do |r, arg_name|
- arg_data = args[arg_name] as Hash(Symbol, String|Symbol|Bool)
-
- # check for required parameter
- if arg_data[:required] && !params.has_key?(arg_name)
- raise "missing required parameter: %s" % [arg_name]
- end
-
- # get value
- val = params.fetch(arg_name, arg_data[:default] as String)
-
- # check value
- if !TYPE_CHECKS[arg_data[:type]].match(val)
- raise "invalid parameter format: %s" % [arg_name]
- end
-
- # add value to result
- r[arg_name] = val
-
- # return result
- r
- end
- end
-
def call(context : HTTP::Server::Context)
if md = (context.request.path || "").match(PATH_RE)
if md["namespace"]?
@@ -176,11 +73,18 @@ module Guff
namespace : String,
method : String
)
+ # set response type
context.response.content_type = get_content_type
# method call
json = begin
- # equivalent to send("do_#{namespace}_#{method}".intern, context)
+ #
+ # 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,
@@ -209,41 +113,5 @@ module Guff
context.response.content_type = page.content_type
context.response.puts page
end
-
- ################
- # post methods #
- ################
-
- private def do_post_get_posts(
- context : HTTP::Server::Context,
- args : Hash(String, String)
- )
- [{foo: "bar"}, {foo: "asdf"}].to_json
- end
-
- ################
- # test methods #
- ################
-
- private def do_test_version(
- context : HTTP::Server::Context,
- args : Hash(String, String)
- )
- {version: Guff::VERSION}.to_json
- end
-
- private def do_test_get_posts(
- context : HTTP::Server::Context,
- args : Hash(String, String)
- )
- [{foo: "bar"}, {foo: "asdf"}].to_json
- end
-
- private def do_test_error(
- context : HTTP::Server::Context,
- args : Hash(String, String)
- )
- raise "some random error"
- end
end
end