Web::API(3pm)

๐Ÿ“ฆ
version 2.8 ยท 4 versions
, in debian trixie, ubuntu resolute, ubuntu stonking

โœจ Web::API โ€” NAME โœจ

okay so bestie, this is the manual page for Web::API, a Perl module that is literally "A Simple base module to implement almost every RESTful API with just a few lines of configuration". no cap, it's giving API-wrapping magic and I'm obsessed. ๐Ÿซถ

๐ŸŒˆ VERSION ๐ŸŒˆ

version 2.8 โœจ

๐ŸŽ€ SYNOPSIS ๐ŸŽ€

NOTE: as of version 2.1 strict_ssl is enabled by default for obvious security reasons, this may break your current library implementation, sorry. ๐Ÿ˜ญ

Implement the RESTful API of your choice in 10 minutes, roughly. ๐Ÿ’…

package Net::CloudProvider;

use Mouse;

with 'Web::API';

our $VERSION = "0.1";

has 'commands' => (
    is      => 'rw',
    default => sub {
        {
            list_nodes => { method => 'GET' },
            node_info  => { method => 'GET', require_id => 1 },
            create_node => {
                method             => 'POST',
                default_attributes => {
                    allowed_hot_migrate            => 1,
                    required_virtual_machine_build => 1,
                    cpu_shares                     => 5,
                    required_ip_address_assignment => 1,
                    primary_network_id             => 1,
                    required_automatic_backup      => 0,
                    swap_disk_size                 => 1,
                },
                mandatory => [
                    'label',
                    'hostname',
                    'template_id',
                    'cpus',
                    'memory',
                    'primary_disk_size',
                    'required_virtual_machine_build',
                    'cpu_shares',
                    'primary_network_id',
                    'required_ip_address_assignment',
                    'required_automatic_backup',
                    'swap_disk_size',
                ]
            },
            update_node => { method => 'PUT',    require_id => 1 },
            delete_node => { method => 'DELETE', require_id => 1 },
            start_node  => {
                method       => 'POST',
                require_id   => 1,
                post_id_path => 'startup',
            },
            stop_node => {
                method       => 'POST',
                require_id   => 1,
                post_id_path => 'shutdown',
            },
            suspend_node => {
                method       => 'POST',
                require_id   => 1,
                post_id_path => 'suspend',
            },
        };
    },
);

sub commands {
    my ($self) = @_;
    return $self->commands;
}

sub BUILD {
    my ($self) = @_;

    $self->user_agent(__PACKAGE__ . ' ' . $VERSION);
    $self->live_url('https://ams01.cloudprovider.net/virtual_machines');
    $self->content_type('application/json');
    $self->extension('json');
    $self->wrapper('virtual_machine');
    $self->mapping({
            os        => 'template_id',
            debian    => 1,
            id        => 'label',
            disk_size => 'primary_disk_size',
    });

    return $self;
}

1;

later use as:

use Net::CloudProvider;

my $nc = Net::CloudProvider->new(user => 'foobar', api_key => 'secret');
my $response = $nc->create_node({
    id                             => 'funnybox',
    hostname                       => 'node.funnybox.com',
    os                             => 'debian',
    cpus                           => 2,
    memory                         => 256,
    disk_size                      => 5,
    allowed_hot_migrate            => 1,
    required_virtual_machine_build => 1,
    cpu_shares                     => 5,
    required_ip_address_assignment => 1,
});

๐Ÿ’… ATTRIBUTES ๐Ÿ’…

๐Ÿงš commands ๐Ÿงš

most important configuration part of the module which has to be provided by the module you are writing. like, this is the main character of the whole setup. ๐Ÿ‘‘

the following keys are valid/possible:

  • method
  • path
  • mandatory
  • default_attributes
  • headers
  • extension
  • content_type
  • incoming_content_type
  • outgoing_content_type
  • wrapper
  • query_keys
  • require_id (deprecated, use path)
  • pre_id_path (deprecated, use path)
  • post_id_path (deprecated, use path)

the request path for commands is being build as:

$base_url/$path.$extension

an example for path:

path => 'users/:user_id/labels'

this will add user_id to the list of mandatory keys for this command automatically. slay.

๐ŸŒธ live_url (required) ๐ŸŒธ

get/set base URL to API, can include paths.

๐Ÿฆ‹ test_url (optional) ๐Ÿฆ‹

get/set base URL for test system if applicable.

๐ŸŽ€ test (optional) ๐ŸŽ€

get/set boolean to run against base URL from test system or live system.

๐Ÿ”‘ api_key (required in most cases) ๐Ÿ”‘

get/set API key (also used as basic auth password).

๐Ÿ‘‘ user (optional) ๐Ÿ‘‘

get/set API username/account name.

๐Ÿท๏ธ api_key_field (optional) ๐Ÿท๏ธ

get/set name of the hash key that has to hold the api_key e.g. in POST content payloads.

๐Ÿ“ฆ api_version (optional) ๐Ÿ“ฆ

get/set API version to be used.

default: 1

๐Ÿ—บ๏ธ mapping (optional) ๐Ÿ—บ๏ธ

supply mapping table, hashref of format { "key" => "value", ... }

๐ŸŽ wrapper (optional) ๐ŸŽ

get/set name of the key that is used to wrap all options of a command in. unfortunately some APIs increase the depth of a hash by wrapping everything into a single key (who knows why...), which means this:

$wa->command(%options);

turns %options into:

{ wrapper => \%options }

before encoding and sending it off.

๐Ÿ“จ header (optional) ๐Ÿ“จ

get/set custom headers sent with every request.

๐Ÿ›ก๏ธ auth_type ๐Ÿ›ก๏ธ

get/set authentication type. currently supported are only 'basic', 'header', 'hash_key', 'get_params', 'oauth_header', 'oauth_params' or 'none'

default: none

๐Ÿ” auth_header (optional) ๐Ÿ”

get/set the name of the header used for Authorization credentials.

default: Authorization

๐Ÿช™ auth_header_token_format ๐Ÿช™

get/set format of the auth_header token.

default: 'Token token=%s'

๐Ÿ› ๏ธ default_method (optional) ๐Ÿ› ๏ธ

get/set default HTTP method.

default: GET

๐Ÿ“Ž extension (optional) ๐Ÿ“Ž

get/set file extension, e.g. 'json'

๐Ÿค– user_agent (optional) ๐Ÿค–

get/set User Agent String.

default: "Web::API $VERSION"

โณ timeout (optional) โณ

get/set LWP::UserAgent timeout.

๐Ÿ”’ strict_ssl (optional) ๐Ÿ”’

enable/disable strict SSL certificate hostname checking as a convenience alternatively you can supply your own LWP::Useragent compatible agent for the "agent" attribute.

default: true

๐Ÿ•ต๏ธ agent (optional) ๐Ÿ•ต๏ธ

get/set LWP::UserAgent object.

๐Ÿ” retry_http_codes (optional) ๐Ÿ”

get/set array of HTTP response codes that trigger a retry of the request.

๐Ÿ’ฅ retry_errors (optional) ๐Ÿ’ฅ

define an array reference of regexes that should trigger a retry of the request if matched against an error found via one of the "error_keys"

๐Ÿ”‚ retry_times (optional) ๐Ÿ”‚

get/set number of times a request will be retried at most.

default: 3

โฑ๏ธ retry_delay (optional) โฑ๏ธ

get/set delay to wait between retries. accepts float for millisecond support.

default: 1.0

๐Ÿ“„ content_type (optional) ๐Ÿ“„

global content type, which is used for in and out going request/response headers and to encode and decode the payload if no other more specific content types are set, e.g. "incoming_content_type", "outgoing_content_type" or content types set individually per command attribute.

default: 'text/plain'

๐Ÿ“ฅ incoming_content_type (optional) ๐Ÿ“ฅ

default: undef

๐Ÿ“ค outgoing_content_type (optional) ๐Ÿ“ค

default: undef

๐Ÿ› debug (optional) ๐Ÿ›

enable/disabled debug logging.

default: false

๐Ÿช cookies (optional) ๐Ÿช

this is used to store and retrieve cookies before and after requests were made to keep authenticated sessions alive for the time this object exists in memory you can add your own cookies to be send with every request. See HTTP::Cookies for more information.

default: HTTP::Cookies->new()

๐Ÿซ‚ consumer_secret (required for all oauth_* auth_types) ๐Ÿซ‚

default: undef

๐ŸŽŸ๏ธ access_token (required for all oauth_* auth_types) ๐ŸŽŸ๏ธ

default: undef

๐Ÿคซ access_secret (required for all oauth_* auth_types) ๐Ÿคซ

default: undef

โœ๏ธ signature_method (required for all oauth_* auth_types) โœ๏ธ

default: undef

๐Ÿงฌ encoder (custom options encoding subroutine) ๐Ÿงฌ

Receives \%options and "content-type" as the only 2 arguments and has to return a single scalar.

default: undef

๐Ÿงช decoder (custom response content decoding subroutine) ๐Ÿงช

Receives "content" and "content-type" as the only 2 scalar arguments and has to return a single hash reference.

default: undef

๐Ÿ“ฎ oauth_post_body (required for all oauth_* auth_types) ๐Ÿ“ฎ

enable/disable adding of command options as extra parameters to the OAuth request generation and therefor be included in the OAuth signature calculation.

default: true

๐Ÿšจ error_keys ๐Ÿšจ

get/set list of array keys that will be search for in the decoded response data structure. the same format as for mandatory keys is supported:

some.deeply.nested.error.message

will search for an error message at

$decoded_response->{some}->{deeply}->{nested}->{error}->{messsage}

and if the key exists and its value is defined it will be provided as "$response-"{error}> and matched against all regexes from the retry_errors array ref if provided to trigger a retry on particular errors.

โœจ INTERNAL SUBROUTINES/METHODS โœจ

okay bestie, these are the backstage passes โ€” the internal subroutines and methods that make Web::API do its thing. some have notes, some are just here for the vibe. let's go ๐Ÿ’…


nonce

generates a new OAuth nonce for every single request. iconic behavior, honestly ๐Ÿ”ฅ

log

no description given, she's mysterious ๐Ÿ’…

decode

no description, just vibes โœจ

encode

same energy, no notes ๐ŸŒธ

talk

she's here, no description, we move ๐Ÿฆ‹

map_options

no description, but she's doing her thing ๐Ÿ’–

check_mandatory

no description, but mandatory checks are mandatory, periodt ๐Ÿ’…

key_exists

no description, she checks if the key exists, iykyk ๐Ÿ”‘

wrap

no description, she wraps, she slays ๐ŸŽ€

request

retries the request with a delay if retry_http_codes is set, otherwise just tries once. no cap.

needs_retry

returns true if the HTTP code or error found matches either retry_http_codes or retry_errors (respectively). returns false otherwise.

if retry_errors are defined, she'll try to decode the response content and store the decoded structure internally so we don't have to decode again at the end.

needs the last response object and the 'Accept' content type header from the request for decoding. it's giving thorough ๐Ÿ’…

find_error

goes through error_keys and finds a potential error message in the decoded/parsed response, then returns it. periodt.

format_response

no description, just formatting and vibes โœจ

build_uri

no description, she builds URIs, we stan ๐Ÿซถ

build_content_type

configures in/out content types.

order of precedence:

  1. per command incoming_content_type / outgoing_content_type
  2. per command general content_type
  3. content type based on file path extension (only for incoming)
  4. global incoming_content_type / outgoing_content_type
  5. global general content_type

it's giving hierarchy, and we respect it ๐Ÿ‘‘

DESTROY

catches the DESTROY call and tears down / cleans up if necessary โ€” but at this point there is nothing to do though. the real reason she exists? to prevent AUTOLOAD from logging an unknown command error message. queen shit ๐Ÿ‘‘

AUTOLOAD magic

installs a method for each new command and calls it inside an eval {} to catch exceptions and set an error in a unified way. slay ๐Ÿ’…


๐Ÿ› BUGS ๐Ÿ›

bestie, please report any bugs or feature requests on GitHub's issue tracker <https://github.com/nupfel/Web-API/issues>. pull requests welcome! ๐Ÿซถ


๐ŸŒธ SUPPORT ๐ŸŒธ

you can find documentation for this module with the perldoc(1) command.

perldoc Web::API

you can also look for information at:


๐Ÿ‘€ SEE ALSO ๐Ÿ‘€

  • HTTP::Cookies
  • LWP::UserAgent
  • Net::OAuth

โœ๏ธ AUTHOR โœ๏ธ

Tobias Kirschstein <lev@cpan.org>


this software is Copyright (c) 2013 by Tobias Kirschstein.

this is free software, licensed under:

The (three-clause) BSD License

and that's the tea, bestie! this page was served fresh from perl v5.38.2 on 2024-04-13 as Web::API(3pm). bye ๐Ÿ’–

๐Ÿ“ฆ where this page comes from