summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2011-01-07 11:19:43 -0600
committerJesse Luehrs <doy@tozt.net>2011-01-07 11:19:43 -0600
commitfa2f5b79f94a71a7a1038f2c297ccbd4033257ac (patch)
tree73846e70ca868b0a6b652083d2276e0243aaea11
parent77b06b71f7803915004266172251673847f472cd (diff)
downloadplack-client-fa2f5b79f94a71a7a1038f2c297ccbd4033257ac.tar.gz
plack-client-fa2f5b79f94a71a7a1038f2c297ccbd4033257ac.zip
docs
-rw-r--r--lib/Plack/Client.pm114
1 files changed, 114 insertions, 0 deletions
diff --git a/lib/Plack/Client.pm b/lib/Plack/Client.pm
index fd02730..4b7f666 100644
--- a/lib/Plack/Client.pm
+++ b/lib/Plack/Client.pm
@@ -12,8 +12,62 @@ use Scalar::Util qw(blessed reftype);
=head1 SYNOPSIS
+ use Plack::Client;
+ my $client = Plack::Client->new({ myapp => sub { ... } });
+ my $res1 = $client->get('http://google.com/');
+ my $res2 = $client->post(
+ 'psgi-local://myapp/foo.html',
+ ['Content-Type' => 'text/plain'],
+ "foo"
+ );
+
=head1 DESCRIPTION
+A common task required in more complicated web applications is communicating
+with various web services for different tasks. These web services may be spread
+among a number of different servers, but some of them may be on the local
+server, and for those, there's no reason to require accessing them through the
+network; assuming the app is written using Plack, the app coderef for the
+service already exists in the current process, so a lot of time could be saved
+by just calling it directly.
+
+The key issue here then becomes providing an interface that allows accessing
+both local and remote services through a common api, so that services can be
+moved between servers with only a small change in configuration, rather than
+having to change the actual code involved in accessing it. This module solves
+this issue by providing an API similar to L<LWP::UserAgent>, but using an
+underlying implementation consisting entirely of Plack apps. Local apps are
+distinguished from remote apps by the URL scheme: remote URLs use C<http> or
+C<https>, while local URLs use C<psgi-local> or C<psgi-local-ssl>. For
+instance, accessing C</foo> on a remote application would look like this:
+C<< $client->get('http://some.other.server.com/foo') >>, and accessing the same
+thing on a local application would look like this:
+C<< $client->get('psgi-local://myapp/foo') >>, but they will both give the same
+result. This API allows a simple config file change to be all that's necessary
+to migrate your service to a different server.
+
+=cut
+
+=method new
+
+ my $client = Plack::Client->new(
+ apps => {
+ foo => sub { ... },
+ bar => MyApp->new->to_app,
+ }
+ )
+
+Constructor. Takes a hash of arguments, with these keys being valid:
+
+=over 4
+
+=item apps
+
+A mapping of local app names to PSGI app coderefs. These are the apps that will
+be available via the C<psgi-local> URL scheme.
+
+=back
+
=cut
sub new {
@@ -28,14 +82,52 @@ sub new {
}, $class;
}
+=method apps
+
+ my $apps = $client->apps;
+
+Returns the C<apps> hashref that was passed to the constructor.
+
+=cut
+
sub apps { shift->{apps} }
+=method app_for
+
+ my $app = $client->app_for('foo');
+
+Returns the app corresponding to the given app name (or undef, if no such app
+exists).
+
+=cut
+
sub app_for {
my $self = shift;
my ($for) = @_;
return $self->apps->{$for};
}
+=method request
+
+ $client->request(
+ 'POST',
+ 'http://example.com/',
+ ['Content-Type' => 'text/plain'],
+ "content",
+ );
+ $client->request(HTTP::Request->new(...));
+ $client->request($env);
+ $client->request(Plack::Request->new(...));
+
+This method performs most of the work for this module. It takes a request in
+any of several forms, makes the request, and returns the response as a
+L<Plack::Response> object. The request can be in the form of an
+L<HTTP::Request> or L<Plack::Request> object directly, or it can take arguments
+to pass to the constructor of either of those two modules (so see those two
+modules for a description of exactly what is valid).
+
+=cut
+
sub request {
my $self = shift;
@@ -186,6 +278,28 @@ sub _resolve_response {
return $psgi_res;
}
+=method get
+
+=method head
+
+=method post
+
+=method put
+
+=method delete
+
+ $client->get('http://example.com/foo');
+ $client->head('psgi-local://bar/admin');
+ $client->post('https://example.com/submit', [], "my submission");
+ $client->put('psgi-local-ssl://foo/new-item', [], "something new");
+ $client->delete('http://example.com/item/2');
+
+These methods are just shorthand for C<request>. They only allow the "URL,
+headers, body" API; for anything more complicated, C<request> should be used
+directly.
+
+=cut
+
sub get { shift->request('GET', @_) }
sub head { shift->request('HEAD', @_) }
sub post { shift->request('POST', @_) }