wonsulting / opensearch-client
The official PHP OpenSearch client integrated with Laravel
Requires
- php: ^7.4 || ^8.0
- opensearch-project/opensearch-php: ^2.1
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.8
- orchestra/testbench: ^7.5
- phpstan/phpstan: ^1.6
- phpunit/phpunit: ^9.5
This package is auto-updated.
Last update: 2026-07-09 17:15:23 UTC
README
The official PHP OpenSearch client integrated with Laravel.
Contents
Compatibility
| Requirement | Supported versions |
|---|---|
| PHP | 8.2 – 8.4 |
| Laravel | 11 – 13 |
| OpenSearch (opensearch-php client) | 2.x |
Laravel 13 requires PHP 8.3 or newer.
Installation
The library can be installed via Composer:
composer require wonsulting/opensearch-client
Configuration
To change the client settings you need to publish the configuration file first:
php artisan vendor:publish --provider="OpenSearch\Laravel\Client\ServiceProvider"
In the newly created config/opensearch.client.php file you can define the default connection name and one options array per connection.
return [ 'default' => env('OPENSEARCH_CONNECTION', 'default'), 'connections' => [ 'default' => [ 'base_uri' => env('OPENSEARCH_BASE_URI', 'http://localhost:9200'), // Optional — any Guzzle request option passes through to the factory: // 'auth' => [env('OPENSEARCH_USERNAME'), env('OPENSEARCH_PASSWORD')], // 'verify' => env('OPENSEARCH_VERIFY_TLS', true), // 'retries' => (int) env('OPENSEARCH_RETRIES', 0), ], ], ];
Each connection is the options array for the SDK's PSR-18 OpenSearch\GuzzleClientFactory. base_uri is required
(a single URI with an explicit scheme); auth, verify, and any other Guzzle request option pass straight through.
retries is the one package-level key — it is applied as the factory's maxRetries, not sent to Guzzle.
Migrating from v2.x: the per-connection
hostsarray was replaced by a singlebase_uri, andOPENSEARCH_HOSTbecameOPENSEARCH_BASE_URI. A connection that still contains ahostskey throwsInvalidConfigurationExceptionrather than silently dropping hosts — the new API expresses exactly one host per connection.
To swap the HTTP client (e.g. Symfony), add AWS SigV4 signing, or attach a logger, bind your own
OpenSearch\ClientFactoryInterface in the container and ClientBuilder will use it instead of the default
GuzzleClientFactory:
$this->app->bind(OpenSearch\ClientFactoryInterface::class, fn () => new OpenSearch\SymfonyClientFactory());
If you need still more control over the client creation, you can create your own client builder:
// see OpenSearch\Laravel\Client\ClientBuilder for the reference class MyClientBuilder implements OpenSearch\Laravel\Client\ClientBuilderInterface { public function default(): Client { // should return a client instance for the default connection } public function connection(string $name): Client { // should return a client instance for the connection with the given name } }
Do not forget to register the builder in your application service provider:
class MyAppServiceProvider extends Illuminate\Support\ServiceProvider { public function register() { $this->app->singleton(ClientBuilderInterface::class, MyClientBuilder::class); } }
Usage
Use OpenSearch\Laravel\Client\ClientBuilderInterface to get access to the client instance:
namespace App\Console\Commands; use OpenSearch\Client; use OpenSearch\Laravel\Client\ClientBuilderInterface; use Illuminate\Console\Command; class CreateIndex extends Command { protected $signature = 'create:index {name}'; protected $description = 'Creates an index'; public function handle(ClientBuilderInterface $clientBuilder) { // get a client for the default connection $client = $clientBuilder->default(); // get a client for the connection with name "write" $client = $clientBuilder->connection('write'); $client->indices()->create([ 'index' => $this->argument('name') ]); } }
Documentation
Maintainer-facing docs live in docs/:
- Architecture — package internals, the three classes, DI flow, config schema, and caching semantics.
- Runbook — setup, tests, quality tooling, CI mapping, smoke test, and release process.