summaryrefslogtreecommitdiff
path: root/posts/2010-06-10-moosex-net-api-update.org
blob: f130447bbb03bde1cf92bb35a17168113d10af19 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
[[http://git.lumberjaph.net/p5-moosex-net-api.git/][MooseX::Net::API]]
is a module to help writing clients for RESTful (and even non-RESTful)
WebServices:

#+BEGIN_SRC perl
    package my::api;
    use MooseX::Net::API;

    net_api_declare myapi => (
        api_base_url => 'http://api....',
        api_format   => 'json',
    );

    net_api_method users => (
        method      => 'GET',
        path        => '/users/:country',
        description => 'fetch a list of users',
        params      => [qw/country/],
        expected    => [qw/200 404/],
    );
#+END_SRC

We've been using this module at work for the last few months on various
internal APIs, and I'm pretty pleased with the result so far.

Lately I've started to rework the core. I've tried to split most of the
functionalities into roles, and rework the code that generates the
various methods. I've also added methods to access miscellaneous
information :

#+BEGIN_SRC perl
    my $client = my::api->new;

    # to get a list of API methods
    $client->meta->get_all_net_api_methods();

    # find an API method
    my $method = $client->meta->find_net_api_method_by_name('users');

    # and now informations about the method
    say $method->documentation;

    name:        users
    description: fetch a list of useres
    method:      GET
    path:        /users/:country
    arguments:   country
    expected:    200, 404
#+END_SRC

It's not yet complete, but a new version will be available soon on CPAN.
Here is a list of some more features I plan to add quickly:

-  better internal API
-  better authorization support (OAuth!)
-  add more methods to provide better introspection
-  better unserialization
-  more tests and better documentation
-  generate POD via a PODWeaver plugin ?
-  plugins ?
-  renaming ? (not sure it really fits in the MooseX:: namespace)

** http-console

I've also started
[[http://git.lumberjaph.net/p5-net-http-console.git/][Net::HTTP::Console]].
It's inspired by
[[http://github.com/cloudhead/http-console][http-console]]. It relies on
MX::Net::API, and can use any libraries written with MX::Net::API, as
well as any *raw* RESTful API. As an example, let's use it on twitter.

#+BEGIN_EXAMPLE
    % http-console --url http://api.twitter.com --format json

    http://127.0.0.1:5984> GET /1/statuses/public_timeline
    [
        {
            "source" : "web",
            "favorited" : false,
            "geo" : null,
            "coordinates" : null,
            "place" : null,
            ...
        }
    ]

    http://127.0.0.1:5984> show headers
    cache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
    last-modified: Mon, 07 Jun 2010 15:27:12 GMT
    x-transaction: 1275924432-94882-31146
    x-ratelimit-reset: 1275925258
    ...
#+END_EXAMPLE

You can call any method from the twitter API (at the exception of the
ones that require authentication: it's not supported yet).

You can also use it with any library that uses MX::Net::API:

#+BEGIN_EXAMPLE
    % http-console --lib Net::Backtweet

    http://api.backtweet.com> help command
    available commands:
    - tweets\_by_url
    - stats\_by_url
    - good\_tweets_by_url

    http://api.backtype.com> help command tweets\_by_url
    name:        tweets_by_url
    description: Retrieve tweets that link to a given URL, whether the links are shortened or unshortened.
    method:      GET
    path:        /tweets/search/links

    http://api.backtype.com> stats\_by_url {"q":"http://lumberjaph.net","key":s3kr3t"}
    {
        "tweetcount" : 388
    }
#+END_EXAMPLE

Arguments to the methods are serialized in JSON format. Not sure if it's
the best idea I will see if it needs improvement while using it. You can
also perform POST and PUT with content.

#+BEGIN_EXAMPLE
        http://localhost:5984> POST /test_rtgi_fetcher {"foo":"bar"}
        {
           "ok" : true,
           "rev" : "1-fe67006eb0e02e5f0057b5b2a6672391",
           "id" : "fe3175615a34eb28153479307c000f26"
        }
#+END_EXAMPLE

It's far from being complete at the moment, but I will extend it
quickly. Right now, you can define global headers, and get help for all
methods in your MX::Net::API library. Authentication is on top of my
priority list, as is alias creation, so instead of doing (on a
non-moosex::net::api lib): =GET /users/= you will do:

#+BEGIN_QUOTE
  alias users/:country as users
#+END_QUOTE

then:

#+BEGIN_QUOTE
  users {"country":"france"}
#+END_QUOTE

(and yes, I've switched from wordpress to
[[http://github.com/perigrin/blawd][blawd]]).