From 945412cd8fad832f7bea42ac3191867287a9a3c0 Mon Sep 17 00:00:00 2001 From: franck cuny Date: Tue, 31 Aug 2010 15:40:13 +0200 Subject: initial import --- eg/api.pl | 10 ++++++++++ eg/github.json | 31 +++++++++++++++++++++++++++++++ eg/github.yaml | 19 +++++++++++++++++++ eg/twitter.json | 27 +++++++++++++++++++++++++++ eg/twitter.yaml | 19 +++++++++++++++++++ lib/Net/HTTP/API/Spec.pm | 46 ++++++++++++++++++++++++++++++++++++++++++++++ t/01_basic.t | 12 ++++++++++++ t/spec/test1.json | 38 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 202 insertions(+) create mode 100644 eg/api.pl create mode 100644 eg/github.json create mode 100644 eg/github.yaml create mode 100644 eg/twitter.json create mode 100644 eg/twitter.yaml create mode 100644 lib/Net/HTTP/API/Spec.pm create mode 100644 t/01_basic.t create mode 100644 t/spec/test1.json diff --git a/eg/api.pl b/eg/api.pl new file mode 100644 index 0000000..d5e8a61 --- /dev/null +++ b/eg/api.pl @@ -0,0 +1,10 @@ +use strict; +use warnings; +use 5.010; + +use Net::HTTP::API::Spec; + +my $api = Net::HTTP::API::Spec->load_from_spec(shift); +my $res = $api->user_information(format => 'json', username => 'franckcuny'); + +use YAML::Syck; warn Dump $res; diff --git a/eg/github.json b/eg/github.json new file mode 100644 index 0000000..52513d1 --- /dev/null +++ b/eg/github.json @@ -0,0 +1,31 @@ +{ + "declare" : { + "api_base_url" : "http://github.com/api/v2/", + "api_format_mode" : "content-type", + "api_format" : "json" + }, + "methods" : { + "user_information" : { + "params" : [ + "username", + "format" + ], + "required" : [ + "username", + "format" + ], + "path" : "/:format/user/show/:username", + "method" : "GET" + }, + "user_following" : { + "params" : [ + "user" + ], + "required" : [ + "user" + ], + "path" : "/user/show/:user/followers", + "method" : "GET" + } + } +} diff --git a/eg/github.yaml b/eg/github.yaml new file mode 100644 index 0000000..c28e370 --- /dev/null +++ b/eg/github.yaml @@ -0,0 +1,19 @@ +declare: + api_base_url: http://github.com/api/v2/ + api_format: JSON + api_format_mode: content-type +methods: + user_information: + method: GET + path: /user/show/:username + params: + - username + required: + - username + user_following: + method: GET + path: /user/show/:user/followers + params: + - user + required: + - user diff --git a/eg/twitter.json b/eg/twitter.json new file mode 100644 index 0000000..f07470e --- /dev/null +++ b/eg/twitter.json @@ -0,0 +1,27 @@ +{ + "declare" : { + "api_base_url" : "http://api.twitter.com/1", + "api_format_mode" : "append", + "api_format" : "json" + }, + "methods" : { + "public_timeline" : { + "params" : [ + "skip_user" + ], + "path" : "/statuses/public_timeline", + "method" : "GET" + }, + "home_timeline" : { + "params" : [ + "since_id", + "max_id", + "count", + "page", + "skip_user" + ], + "path" : "/statuses/home_timeline", + "method" : "GET" + } + } +} diff --git a/eg/twitter.yaml b/eg/twitter.yaml new file mode 100644 index 0000000..92054b7 --- /dev/null +++ b/eg/twitter.yaml @@ -0,0 +1,19 @@ +declare: + api_base_url: http://api.twitter.com/1 + api_format: json + api_format_mode: append +methods: + public_timeline: + method: GET + path: /statuses/public_timeline + params: + - skip_user + home_timeline: + method: GET + path: /statuses/home_timeline + params: + - since_id + - max_id + - count + - page + - skip_user diff --git a/lib/Net/HTTP/API/Spec.pm b/lib/Net/HTTP/API/Spec.pm new file mode 100644 index 0000000..37975c2 --- /dev/null +++ b/lib/Net/HTTP/API/Spec.pm @@ -0,0 +1,46 @@ +package Net::HTTP::API::Spec; + +use JSON; +use Moose; +use IO::All; + +use Net::HTTP::API::Core; + +sub load_from_spec { + my ($class, $spec_file) = @_; + + my $content < io($spec_file); + my $spec = JSON::decode_json($content); + + my $net_api_class = + Class::MOP::Class->create_anon_class( + superclasses => ['Net::HTTP::API::Core']); + + my $net_api_object = $net_api_class->new_object; + + $net_api_object = _declare_api($net_api_object, $spec->{declare}); + $net_api_object = _add_methods($net_api_object, $spec->{methods}); + + $net_api_object; +} + +sub _declare_api { + my ($api, $declaration_spec) = @_; + + foreach my $k (keys %$declaration_spec) { + $api->meta->set_api_option($k => $declaration_spec->{$k}); + } + $api; +} + +sub _add_methods { + my ($class, $methods_spec) = @_; + + foreach my $method_name (keys %$methods_spec) { + $class->meta->add_net_api_method($method_name, + %{$methods_spec->{$method_name}}); + } + $class; +} + +1; diff --git a/t/01_basic.t b/t/01_basic.t new file mode 100644 index 0000000..bf1d999 --- /dev/null +++ b/t/01_basic.t @@ -0,0 +1,12 @@ +use strict; +use warnings; +use Test::More; + +use Net::HTTP::API::Spec; + +ok my $client = Net::HTTP::API::Spec->load_from_spec('t/spec/test1.json'); + +my @methods = $client->meta->get_all_net_api_methods(); +is scalar @methods, 2; + +done_testing; diff --git a/t/spec/test1.json b/t/spec/test1.json new file mode 100644 index 0000000..85cb277 --- /dev/null +++ b/t/spec/test1.json @@ -0,0 +1,38 @@ +{ + "declare" : { + "api_format_mode" : "content-type", + "api_format" : "json" + }, + "methods" : { + "add_corpus" : { + "params" : [ + "name", + "tasks" + ], + "required" : [ + "name", + "tasks" + ], + "expected" : [ + "200", + "201" + ], + "path" : "/corpus/:name", + "method" : "POST" + }, + "corpus" : { + "params" : [ + "name" + ], + "required" : [ + "name" + ], + "expected" : [ + "200", + "204" + ], + "path" : "/corpus/:name", + "method" : "GET" + } + } +} -- cgit 1.4.1