The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

WWW::BetterServers::API - Perl interface for the BetterServers REST API

SYNOPSIS

  use WWW::BetterServers::API;
  use v5.10;

  my $api_id    = '(your API id)';
  my $secret    = '(your API secret)';
  my $auth_type = '(your auth type)';

  my $api = new WWW::BetterServers::API(api_id     => $api_id,
                                        api_secret => $secret,
                                        auth_type  => $auth_type);

  my $resp = $api->request(method  => "POST",
                           uri     => "/v1/accounts/$api_id/instances",
                           payload => {display_name => "new server 4",
                                       plan_id => (plan UUID)});

  if( $resp->code == 201 ) {
      say "New instance created!\n";
  }

  $api->api_id($api_id);
  $api->api_secret($secret);

  $resp = $api->request(method => "GET",
                        uri    => "/v1/accounts/$api_id/instances");

  if( $resp->code == 200 ) {
      say "Your instances:";
      for my $inst ( @{ $resp->json('/instances') } ) {
          print <<_INSTANCE_;
ID: $inst->{id}
Name: $inst->{displayname}

_INSTANCE_ } }

DESCRIPTION

WWW::BetterServers::API is an easy-to-use wrapper for the BetterServers REST API. All you need is your BetterServers API id and API secret (available in the BetterServers portal after signup).

new

Creates a new BetterServers API object.

Parameters

api_id

Required. Your BetterServers API id. This is in the portal area after you've signed up for BetterServers.

api_secret

Required. Your BetterServers API secret. This is in the portal area after you've signed up for BetterServers.

auth_type

Required. Your BetterServers auth type. This uniquely identifies your organization.

api_host

Optional. If you're a white label reseller, specify your API hostname here. Defaults to api.betterservers.com.

Example

    $api = new WWW::BetterServers::API(api_id => "123456-1234-1234-12345678",
                                       api_secret => "wefoidfjl324asdf982asdflkj234",
                                       auth_type => "FOKA83TI");

ua

A handle to the Mojo::UserAgent object. Normally not needed unless you want to set special proxy or other parameters. See Mojo::UserAgent.

    $api->ua->https_proxy('http://localhost:8443');

request

Makes a request to the BetterServers API server (or api_host if you've specified it). Returns a Mojolicious response object. The response object has the following methods:

code

The HTTP response status code (e.g., 200, 404, etc.)

    if ($resp->code !~ /^[23]/) {
        warn "Error: " . $resp->json('/error') . "\n";
    }
message

The HTTP response message (e.g., "OK", "Not Found", etc.)

headers

A list of response headers.

json

A Mojo::JSON object. You may specify a JSON pointer to retrieve a particular value:

    my $resp = $api->request(method => "GET",
                             uri => "/v1/instances");

    print $resp->json('/instances/0/id');
body

The raw body of the response.

Parameters

All of these parameters reference the API directly; see the API documentation for details:

  https://www.betterservers.com/docs/api

For example, if you want to create a new VM instance, find "Create account instance" in the API documentation here:

  https://www.betterservers.com/docs/api#createaccountinstance

The Method/URI section will tell you what HTTP method and URI path to use. Parameters, if any, are also listed.

To create new API resources (e.g., instances, plans), you will often need to know the UUID of other offerings (e.g., disk offerings, hypervisors, service offerings, etc.). You will look up these UUIDs using the offerings available:

  https://www.betterservers.com/docs/api#resources

Once you've looked up the available offerings, you can use them to create your new resource.

method

One of GET, POST, PATCH, PUT, DELETE, or OPTIONS.

uri

The URI reference of the resource you're using.

payload

Optional. A way to send JSON data to the API resource. The value of this parameter should be a reference to a native Perl data type (e.g., array, hash) which will be JSON-encoded before it's sent. Mutually exclusive with body.

body

Optional. Some requests require a JSON document or url-encoded strings in the body; you may specify that here, or use the payload parameter to let this API helper encode it for you. If you already have JSON data, use this parameter. Mutually exclusive with payload.

callback

Optional. If you want to do non-blocking requests, specify a callback subroutine here. The callback will be invoked with a useragent object and the transaction object; no response will be given from the request, instead the results will be given to the callback. This allows you to make multiple, concurrent requests:

    my $delay = Mojo::IOLoop->delay;

    my $end1 = $delay->begin(0);
    $api->request(method   => "GET",
                  uri      => "/v1/instances",
                  callback => sub {
                      my ($ua, $tx) = @_;
                      say "Here are the VMs: " . $tx->res->body;
                      $end1->();
                  });

    my $end2 = $delay->begin(0);
    $api->request(method   => "GET",
                  uri      => "/v1/vpcs",
                  callback => sub {
                      my ($ua, $tx) = @_;
                      say "Here are the VPCs: " . $tx->res->body;
                      $end2->();
                  });

    $delay->wait;

Example

  ## make a new plan
  $resp = $api->request(method  => 'POST',
                        uri     => "/v1/plans/$plan_id",
                        payload => {name => "Plan C",
                                    service_offering_id => "12345",
                                    disk_offering_id => "23456"});

  ## same thing, but we encode it ourselves
  $resp = $api->request(method => 'POST',
                        uri    => "/v1/plans",
                        body   => JSON::encode_json({name => "Plan B",
                                                     service_offering_id => "12345",
                                                     disk_offering_id => "23456"}));

  unless( $resp->code == 201 ) {
      say STDERR $resp->message;
      die Dumper($resp->json);
  }

EXAMPLES

Some additional examples may be found in the test suite for this module. Also see the BetterServers API documentation.

TESTING

You may run the tests against your own API credentials (no resources will be altered--only read-only queries are made). The easiest way is to create a file called test-credentials in the root of this module when you retrieve it from CPAN:

    API_ID=4C662460-E5E0-11E2-F8DE-1F1F9B08DD17
    API_SECRET=GVSm2m+cvH1Laiphsu8hdOj3uOAVS+o6RoHh5dyoQ08
    AUTH_TYPE=BAFU33FA

Then run the tests from a Bourne-compatible shell:

    $ perl Makefile.PL
    $ make
    $ env `cat test-credentials` make test

SEE ALSO

Mojo::UserAgent, Mojo::JSON, Mojo::IOLoop

The API helpers:

  https://www.betterservers.com/docs/api-helpers

The API documentation:

  https://www.betterservers.com/docs/api

URI relative references:

  https://tools.ietf.org/html/rfc3986

AUTHOR

Scott Wiersdorf, <scott@betterservers.com>

COPYRIGHT AND LICENSE

Copyright (C) 2013 by BetterServers, Inc.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.10.1 or, at your option, any later version of Perl 5 you may have available.