Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/spiral/grpc-client
PHP client for gRPC
https://github.com/spiral/grpc-client
grpc grpc-client php
Last synced: about 1 month ago
JSON representation
PHP client for gRPC
- Host: GitHub
- URL: https://github.com/spiral/grpc-client
- Owner: spiral
- License: mit
- Created: 2024-07-25T10:56:20.000Z (4 months ago)
- Default Branch: master
- Last Pushed: 2024-08-02T20:45:16.000Z (3 months ago)
- Last Synced: 2024-09-27T14:02:33.072Z (about 2 months ago)
- Topics: grpc, grpc-client, php
- Language: PHP
- Homepage:
- Size: 243 KB
- Stars: 8
- Watchers: 2
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.md
Awesome Lists containing this project
README
# gRPC Client
The package provides powerful and convenient functionality for making client gRPC requests through
a simple and extensible interface.## Installation
```bash
composer require spiral/grpc-client -W
```[![PHP](https://img.shields.io/packagist/php-v/spiral/grpc-client.svg?style=flat-square&logo=php)](https://packagist.org/packages/spiral/grpc-client)
[![Latest Version on Packagist](https://img.shields.io/packagist/v/spiral/grpc-client.svg?style=flat-square&logo=packagist)](https://packagist.org/packages/spiral/grpc-client)
[![License](https://img.shields.io/packagist/l/spiral/grpc-client.svg?style=flat-square)](LICENSE.md)
[![Total downloads](https://img.shields.io/packagist/dt/spiral/grpc-client.svg?style=flat-square)](https://packagist.org/packages/spiral/grpc-client/stats)Note that the package requires [gRPC extension](https://pecl.php.net/package/gRPC) to be installed.
## Documentation
### Public API
The package provides the following parts of the API:
- Integration classes for use with frameworks.
- Classes for convenient package configuration through DTOs.
- A set of basic [interceptors](https://spiral.dev/docs/framework-interceptors/).
- Several types of exceptions for error handling.### Integration
#### Spiral
> [!NOTE]
> The [`spiral/roadrunner-bridge`](https://github.com/spiral/roadrunner-bridge) package includes
> the `spiral/grpc-client` package by default since version `4.0.0` and provides its integration
> and configuration flow.Add the `\Spiral\Grpc\Client\Bridge\GrpcClientBootloader` bootloader to the list of bootloaders
in the application configuration (usually it is `Kernel.php`).#### Other Frameworks
If you are using this package outside the [Spiral](https://spiral.dev/) framework,
you need to figure out how to use the `\Spiral\Grpc\Client\ServiceClientProvider` provider
to get ready-to-use gRPC clients.### Configuration DTOs
Now let's consider a configuration example:
```php
use Spiral\Grpc\Client\Config\GrpcClientConfig;
use Spiral\Grpc\Client\Config\ServiceConfig;
use Spiral\Grpc\Client\Config\ConnectionConfig;
use Spiral\Grpc\Client\Interceptor\SetTimoutInterceptor;
use Spiral\Grpc\Client\Interceptor\RetryInterceptor;
use Spiral\Grpc\Client\Interceptor\ExecuteServiceInterceptors;new GrpcClientConfig(
interceptors: [
SetTimoutInterceptor::createConfig(10_000), // 10 seconds
RetryInterceptor::createConfig(
maximumAttempts: 3,
initialInterval: 100, // 0.1 seconds
backoffCoefficient: 1.5,
),
ExecuteServiceInterceptors::class,
],
services: [
new ServiceConfig(
connections: ConnectionConfig::createInsecure('my-service:9001'),
interfaces: [
\GRPC\MyService\MailSenderInterface::class,
\GRPC\MyService\BlackListInterface::class,
\GRPC\MyService\SubscriberInterface::class,
],
),
],
)
```#### GrpcClientConfig
This class represents the configuration of the gRPC client in general.
It includes a list of service configurations and a general list of interceptors that will be applied to all services.Interceptors can be declared as class names, `Spiral\Core\Container\Autowire` objects
(if custom constructor arguments need to be passed), or objects.
Note that some interceptors provide convenient methods for creating configurations.#### ServiceConfig
This class represents the configuration of a specific service or a group of similar services
but with different connection options.The `interfaces` parameter is a list of gRPC service interfaces that were generated by the `protoc` utility
and that are implemented by the service.> [!NOTE]
> Currently, we support only service interfaces that are [generated](https://spiral.dev/docs/grpc-client)
> using the `protoc` utility with the `protoc-gen-php-grpc` plugin.The configuration example above doesn't include the `interceptors` parameter.
It's the same as in the general configuration, but it's applied only to the specified service.
This branch of interceptors is run via the `ExecuteServiceInterceptors` interceptor.
So, it's important to include it if you want to use service-specific interceptors.The `connections` parameter is a list of connection configurations. You can specify multiple connections
to distribute the load between them or to provide fail-over.
Multi-connection orchestration strategy can be configured by interceptors,
for example, `ConnectionsRotationInterceptor`.#### ConnectionConfig
This class represents the configuration of a single connection to the gRPC service.
It includes credentials and the service address.
Use static methods to create connection configurations with different types of credentials.### Usage
After the integration and configuration are ready, you can get the client for the desired service interface
from the container and call the service methods.```php
final class Sender
{
public function __construct(
private \GRPC\MyService\MailSenderInterface $mailSender,
) {}public function sendMail(string $email, $subject, string $message): bool
{
$request = (new \GRPC\MyService\SendMailRequest())
->setEmail($email)
->setSubject($subject)
->setMessage($message);$response = $this->mailSender->sendMail(new \Spiral\RoadRunner\GRPC\Context([]), $request);
return $response->getSuccess();
}
}
```### Interceptors
Important points when using interceptors in the [long-running](https://spiral.dev/docs/start-server) mode:
- **Stateful**: interceptors are recreated anew for each request, so you can safely store the state of each call.
- **Scoped**: interceptors are created in the same Container Scope in which the client is called.
Accordingly, you can request contextual dependencies in the interceptor's constructor.When writing your own interceptors, you will likely want to work with gRPC-specific fields
(options, metadata, input message, etc.).
Use the `\Spiral\Grpc\Client\Interceptor\Helper` class to get or set the values of these context fields.```php
final class AuthContextInterceptor implements InterceptorInterface
{
public function __construct(
private readonly AuthContextInterface $authContext,
) {}public function intercept(CallContextInterface $context, HandlerInterface $handler): mixed
{
$token = $this->authContext->getToken();if ($token === null) {
return $handler->handle($context);
}$metadata = \Spiral\Grpc\Client\Interceptor\Helper::withMetadata($context);
$metadata['auth-token'] = [$token];return $handler->handle(\Spiral\Grpc\Client\Interceptor\Helper::withMetadata($context, $metadata));
}
}
```#### Order of Interceptors
Interceptors are executed in the order in which they are declared in the configuration.
The order of the interceptors is important.For example, if we have the following configuration:
1. `SetTimeout(10 seconds)`
2. `Retry(maxAttempts: 3, interval: 2 seconds)`
3. `SetTimeout(3 seconds)`then we will have a 3-second timeout for each retry attempt.
We also have a 10-second timeout for all attempts in total, after which **no new request** attempts will be made.
This happens because the `RetryInterceptor` takes into account previously configured timeouts.Also, the placement of the `ExecuteServiceInterceptors` interceptor,
which embeds the interceptors of the currently running service,
will affect the final sequence of interceptors.