Skip to content

Commit 37e16de

Browse files
committed
feat: add gRPC client support and configuration
1 parent b2ef789 commit 37e16de

File tree

3 files changed

+96
-1
lines changed

3 files changed

+96
-1
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@
4242
"spiral/roadrunner-http": "^3.0",
4343
"spiral/roadrunner-worker": "^3.0",
4444
"temporal/sdk": "^2.0",
45-
"internal/dload": "^1.1"
45+
"internal/dload": "^1.1",
46+
"spiral/grpc-client": "^1.0.0-rc1"
4647
},
4748
"require-dev": {
4849
"laravel/framework": "^12.0",

config/roadrunner.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,31 @@
1818
'services' => [
1919
// GreeterInterface::class => new Greeter::class,
2020
],
21+
'clients' => [
22+
'interceptors' => [
23+
// LoggingInterceptor::class,
24+
],
25+
'services' => [
26+
// [
27+
// 'connection' => 'my-grpc-server:9002',
28+
// 'interfaces' => [
29+
// GreeterInterface::class,
30+
// ],
31+
// ],
32+
// [
33+
// 'connection' => 'my-secure-grpc-server:9002',
34+
// 'interfaces' => [
35+
// GreeterInterface::class,
36+
// ],
37+
// 'tls' => [
38+
// 'rootCerts' => '/path/to/ca.pem',
39+
// 'privateKey' => '/path/to/client.key',
40+
// 'certChain' => '/path/to/client.crt',
41+
// 'serverName' => 'my.grpc.server',
42+
// ],
43+
// ],
44+
],
45+
],
2146
],
2247

2348
'temporal' => [

src/ServiceProvider.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66

77
use Spiral\Attributes\AttributeReader;
88
use Spiral\Attributes\ReaderInterface;
9+
use Spiral\Core\FactoryInterface;
10+
use Spiral\Grpc\Client\Config\ConnectionConfig;
11+
use Spiral\Grpc\Client\Config\GrpcClientConfig;
12+
use Spiral\Grpc\Client\Config\ServiceConfig;
13+
use Spiral\Grpc\Client\Config\TlsConfig;
14+
use Spiral\Grpc\Client\ServiceClientProvider;
915

1016
final class ServiceProvider extends \Illuminate\Support\ServiceProvider
1117
{
@@ -23,6 +29,7 @@ public function register(): void
2329
{
2430
$this->app->singleton(ReaderInterface::class, AttributeReader::class);
2531
$this->initializeConfigs();
32+
$this->initializeGrpcClientServices();
2633
}
2734

2835
protected function initializeConfigs(): void
@@ -33,4 +40,66 @@ protected function initializeConfigs(): void
3340
\realpath(self::getConfigPath()) => config_path(\basename(self::getConfigPath())),
3441
], 'config');
3542
}
43+
44+
protected function initializeGrpcClientServices(): void
45+
{
46+
$this->app->singleton(FactoryInterface::class, fn() => new class implements FactoryInterface {
47+
/**
48+
* @param class-string $class
49+
* @param array<int, mixed> $parameters
50+
*/
51+
public function make(string $class, array $parameters = []): object
52+
{
53+
return new $class(...array_values($parameters));
54+
}
55+
});
56+
$this->app->singleton(ServiceClientProvider::class, function () {
57+
$toNonEmptyStringOrNull = static fn($value): ?string => (is_string($value) && $value !== '') ? $value : null;
58+
/**
59+
* @var array<int, array{
60+
* connection: non-empty-string,
61+
* interfaces: list<class-string>,
62+
* tls?: array{
63+
* rootCerts?: non-empty-string|null,
64+
* privateKey?: non-empty-string|null,
65+
* certChain?: non-empty-string|null,
66+
* serverName?: non-empty-string|null
67+
* }
68+
* }>
69+
*/
70+
$rawServices = config('roadrunner.grpc.clients.services', []);
71+
$services = collect($rawServices);
72+
$serviceConfigs = [];
73+
foreach ($services as $service) {
74+
$tls = null;
75+
if (isset($service['tls'])) {
76+
$tlsConfig = $service['tls'];
77+
$tls = new TlsConfig(
78+
$toNonEmptyStringOrNull($tlsConfig['rootCerts'] ?? null),
79+
$toNonEmptyStringOrNull($tlsConfig['privateKey'] ?? null),
80+
$toNonEmptyStringOrNull($tlsConfig['certChain'] ?? null),
81+
$toNonEmptyStringOrNull($tlsConfig['serverName'] ?? null),
82+
);
83+
}
84+
/** @var non-empty-string $connection */
85+
$connection = $service['connection'];
86+
/** @var list<class-string> $interfaces */
87+
$interfaces = $service['interfaces'];
88+
$serviceConfigs[] = new ServiceConfig(
89+
connections: new ConnectionConfig($connection, $tls),
90+
interfaces: $interfaces,
91+
);
92+
}
93+
94+
/** @var array<class-string<\Spiral\Interceptors\InterceptorInterface>|\Spiral\Core\Container\Autowire<\Spiral\Interceptors\InterceptorInterface>|\Spiral\Interceptors\InterceptorInterface> $interceptors */
95+
$interceptors = config('roadrunner.grpc.clients.interceptors', []);
96+
$config = new GrpcClientConfig(
97+
interceptors: $interceptors,
98+
services: $serviceConfigs,
99+
);
100+
101+
return new ServiceClientProvider($config, $this->app->make(FactoryInterface::class));
102+
});
103+
104+
}
36105
}

0 commit comments

Comments
 (0)