Skip to main content

Perl Client

The Perl client wraps hlquery's HTTP API with Hlquery::Client, service objects, parsed Hlquery::Response values, authentication, URL encoding, and consistent request handling. Public Perl method names use CamelCase.

Installation

cd etc/api/perl
cpanm --installdeps .

For a repository checkout:

use lib '/path/to/hlquery/etc/api/perl/lib';
use Hlquery::Client;

Create a client

my $client = Hlquery::Client->new(
$ENV{HLQ_BASE_URL} // $ENV{HLQUERY_BASE_URL} // 'http://localhost:9200',
{
token => $ENV{HLQ_TOKEN},
auth_method => 'bearer', # or api-key
timeout => 30,
},
);

my $health = $client->Health();
die $health->GetError() unless $health->IsSuccess();

Authentication can be changed or cleared after construction:

$client->SetAuthToken('token', 'bearer');
$client->SetAuthToken('key', 'api-key');
$client->ClearAuth();

Collections and documents

my $collections = $client->Collections();
$collections->Create('products', {
fields => [
{ name => 'title', type => 'string' },
{ name => 'price', type => 'float' },
],
});

my $metadata = $collections->Get('products');
my $language = $collections->Language('products');
$collections->Update('products', { fields => [{ name => 'active', type => 'bool' }] });

# GetFields is a compatibility alias for Get. Fields are returned as part of
# collection metadata; the server does not expose /collections/{name}/fields.
my $metadata_again = $collections->GetFields('products');

my $documents = $client->Documents();
$documents->Add('products', { id => 'prod_1', title => 'Keyboard', price => 49.99 });
my $document = $documents->Get('products', 'prod_1');
my $context = $documents->Context('products', 'prod_1', { window => 3 });
my $page = $documents->List('products', { offset => 0, limit => 25 });

$documents->Import('products', [
{ id => 'prod_2', title => 'Mouse' },
{ id => 'prod_3', title => 'Monitor' },
]);
$documents->Facets('products', { facet_by => 'brand' });
$documents->Export('products', { filter_by => 'active:true' });
$documents->Maybe('products', { q => 'keybaord' });
$documents->UpdateByQuery('products', {
filter_by => 'active:false', set => { archived => 1 },
});
$documents->DeleteByQuery('products', { filter_by => 'expired:true' });

Search and SQL

my $search = $client->SearchAPI();
my $result = $search->GlobalSearch({
collection => 'products', q => 'keyboard', query_by => 'title',
});

my $searches = [
{ collection => 'products', q => 'keyboard', query_by => 'title' },
{ collection => 'articles', q => 'hardware', query_by => 'content' },
];
$search->MultiSearch($searches); # POST by default
$search->MultiSearch($searches, 'GET');
$search->VectorSearch('products', { vector => [0.1, 0.2, 0.3], limit => 10 });

my $sql = $client->SQL();
my $rows = $sql->Query('SHOW COLLECTIONS;');
my $write = $sql->Exec("INSERT INTO products (id, title) VALUES ('prod_4', 'Desk');");
my $selected = $sql->Search('products', 'SELECT * FROM products LIMIT 10;');

Resource and system services

The client exposes Synonyms, Stopwords, Overrides, Aliases, Users, Keys, Links, Modules, and Analytics service objects. Synonym, global-synonym, override, and alias Upsert methods default to PUT; pass POST or PUT as their final argument when the verb matters.

System wrappers include Status, Query, Health, Ready, Ping, Startup, BootStatus, Stats, Metrics, MetricsJson, MetricsHistory, Connections, RocksDB, RocksDBInternal, DocTotal, SearchConfig, Integrity, Consistency, SelfCheck, StorageStatus, DebugCounters, UpdateCounters, Repair, Etc, and Flush.

Raw relative routes are available through ExecuteRequest:

my $response = $client->ExecuteRequest(
'GET', '/modules/example/status', undef, { verbose => 1 },
);

Responses and errors

Responses provide GetStatusCode, GetBody, GetHeaders, IsSuccess, IsError, and GetError. Server error bodies can include a human-readable error and message, numeric code, and stable code_text.

Tests

cd etc/api/perl
prove -Ilib t/route_contract.t

See etc/api/perl/README.md and the repository examples for packaging and runnable programs.