Skip to content

Commit

Permalink
Added integration between api, spa and ws
Browse files Browse the repository at this point in the history
1. Added integration with Github API
2. Fixed SPA grid
3. Added subscription on WS events
  • Loading branch information
butschster committed Apr 20, 2024
1 parent 6c72134 commit f8fa834
Show file tree
Hide file tree
Showing 55 changed files with 4,965 additions and 85 deletions.
10 changes: 3 additions & 7 deletions .docker/centrifugo/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,16 @@
],
"publish": true,
"proxy_publish": true,
"proxy_subscribe": true,
"proxy_connect": true,
"allow_subscribe_for_client": true,
"address": "0.0.0.0",
"port": 8089,
"grpc_api": true,
"grpc_api_address": "0.0.0.0",
"grpc_api_port": 10000,
"proxy_connect_endpoint": "grpc:https://api:10001",
"proxy_connect_endpoint": "grpc:https://buggregator-api:10001",
"proxy_connect_timeout": "10s",
"proxy_publish_endpoint": "grpc:https://api:10001",
"proxy_publish_endpoint": "grpc:https://buggregator-api:10001",
"proxy_publish_timeout": "10s",
"proxy_subscribe_endpoint": "grpc:https://api:10001",
"proxy_subscribe_timeout": "10s",
"proxy_rpc_endpoint": "grpc:https://api:10001",
"proxy_rpc_endpoint": "grpc:https://buggregator-api:10001",
"proxy_rpc_timeout": "10s"
}
15 changes: 9 additions & 6 deletions app/.rr-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ http:
address: '0.0.0.0:8000'
middleware:
- gzip
- static
static:
dir: public
forbid:
- .php
- .htaccess
- headers
headers:
cors:
allowed_origin: ${RR_CORS_ALLOWED_ORIGIN:-*}
allowed_headers: ${RR_CORS_ALLOWED_HEADERS:-*}
allowed_methods: ${RR_CORS_ALLOWED_METHODS:-GET,POST,PUT,DELETE}
allow_credentials: false
exposed_headers: ${RR_CORS_EXPOSED_HEADERS:-Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma,Content-Disposition,X-RateLimit-Remaining,X-RateLimit-Retry-After,X-RateLimit-Limit,X-Captcha}
max_age: 600
pool:
num_workers: 4
supervisor:
Expand Down
18 changes: 18 additions & 0 deletions app/app/config/broadcasting.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

use Spiral\Broadcasting\Driver\NullBroadcast;

return [
'default' => env('BROADCAST_CONNECTION', 'centrifugo'),
'aliases' => [],
'connections' => [
'centrifugo' => [
'driver' => 'centrifugo',
],
'null' => [
'driver' => NullBroadcast::class,
],
],
];
4 changes: 3 additions & 1 deletion app/app/config/cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
return [
'default' => env('CACHE_STORAGE', 'rr'),

'aliases' => [],
'aliases' => [
'github' => 'rr',
],

'storages' => [
'rr' => [
Expand Down
17 changes: 17 additions & 0 deletions app/app/config/centrifugo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

use App\Endpoint\Centrifugo\ConnectService;
use App\Endpoint\Centrifugo\RPCService;
use RoadRunner\Centrifugo\Request\RequestType;

return [
'services' => [
RequestType::Connect->value => ConnectService::class,
RequestType::RPC->value => RPCService::class,
],
'interceptors' => [
'*' => [],
],
];
9 changes: 9 additions & 0 deletions app/app/config/events.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

return [
'interceptors' => [
\App\Application\Broadcasting\BroadcastEventInterceptor::class
]
];
34 changes: 34 additions & 0 deletions app/app/src/Application/Bootloader/GithubBootloader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace App\Application\Bootloader;

use App\Github\Client;
use App\Github\ClientInterface;
use App\Github\WebhookGate;
use Spiral\Boot\Bootloader\Bootloader;
use Spiral\Boot\EnvironmentInterface;
use Spiral\Cache\CacheStorageProviderInterface;

final class GithubBootloader extends Bootloader
{
public function defineSingletons(): array
{
return [
ClientInterface::class => static fn(CacheStorageProviderInterface $cache) => new Client(
client: new \GuzzleHttp\Client([
'base_uri' => 'https://api.github.com/',
'headers' => [
'Accept' => 'application/vnd.github.v3+json',
],
]),
cache: $cache,
),

WebhookGate::class => static fn(
EnvironmentInterface $env,
) => new WebhookGate(secret: $env->get('GITHUB_WEBHOOK_SECRET', 'secret')),
];
}
}
15 changes: 3 additions & 12 deletions app/app/src/Application/Bootloader/RoutesBootloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,15 @@

namespace App\Application\Bootloader;

use Nyholm\Psr7\Stream;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Spiral\Bootloader\Http\RoutesBootloader as BaseRoutesBootloader;
use Spiral\Cookies\Middleware\CookiesMiddleware;
use Spiral\Csrf\Middleware\CsrfMiddleware;
use Spiral\Debug\Middleware\DumperMiddleware;
use Spiral\Debug\StateCollector\HttpCollector;
use Spiral\Filter\ValidationHandlerMiddleware;
use Spiral\Http\Middleware\ErrorHandlerMiddleware;
use Spiral\Http\Middleware\JsonPayloadMiddleware;
use Spiral\Router\Bootloader\AnnotatedRoutesBootloader;
use Spiral\Router\Loader\Configurator\RoutingConfigurator;
use Spiral\Router\GroupRegistry;
use Spiral\Session\Middleware\SessionMiddleware;

/**
Expand Down Expand Up @@ -57,13 +53,8 @@ protected function middlewareGroups(): array
];
}

protected function defineRoutes(RoutingConfigurator $routes): void
protected function configureRouteGroups(GroupRegistry $groups): void
{
$routes->default('/<path:.*>')
->callable(function (ServerRequestInterface $r, ResponseInterface $response) {
return $response
->withStatus(404)
->withBody(Stream::create('Not found'));
});
$groups->getGroup('api')->setPrefix('/api');
}
}
35 changes: 35 additions & 0 deletions app/app/src/Application/Broadcasting/BroadcastEventInterceptor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace App\Application\Broadcasting;

use Spiral\Broadcasting\BroadcastInterface;
use Spiral\Core\CoreInterceptorInterface;
use Spiral\Core\CoreInterface;

final readonly class BroadcastEventInterceptor implements CoreInterceptorInterface
{
public function __construct(
private BroadcastInterface $broadcast,
) {
}

public function process(string $controller, string $action, array $parameters, CoreInterface $core): mixed
{
$event = $parameters['event'];
$result = $core->callAction($controller, $action, $parameters);

if ($event instanceof ShouldBroadcastInterface) {
$this->broadcast->publish(
$event->getBroadcastTopics(),
\json_encode([
'event' => $event->getEventName(),
'data' => $event->jsonSerialize(),
], JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE),
);
}

return $result;
}
}
17 changes: 17 additions & 0 deletions app/app/src/Application/Broadcasting/Channel/Channel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace App\Application\Broadcasting\Channel;

class Channel implements \Stringable
{
public function __construct(
public readonly string $name
) {}

public function __toString(): string
{
return $this->name;
}
}
13 changes: 13 additions & 0 deletions app/app/src/Application/Broadcasting/Channel/EventsChannel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);

namespace App\Application\Broadcasting\Channel;

final class EventsChannel extends Channel
{
public function __construct()
{
parent::__construct('events');
}
}
14 changes: 14 additions & 0 deletions app/app/src/Application/Broadcasting/ShouldBroadcastInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace App\Application\Broadcasting;

use Stringable;

interface ShouldBroadcastInterface extends \JsonSerializable
{
public function getEventName(): string;

public function getBroadcastTopics(): iterable|Stringable;
}
8 changes: 6 additions & 2 deletions app/app/src/Application/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

namespace App\Application;

use App\Application\Bootloader\GithubBootloader;
use Spiral\Boot\Bootloader\CoreBootloader;
use Spiral\DotEnv\Bootloader\DotenvBootloader;
use Spiral\League\Event\Bootloader\EventBootloader;
use Spiral\Prototype\Bootloader\PrototypeBootloader;
use Spiral\Tokenizer\Bootloader\TokenizerListenerBootloader;

Expand All @@ -25,15 +27,17 @@ public function defineBootloaders(): array
return [
Bootloader\Infrastructure\LogsBootloader::class,



Bootloader\Infrastructure\ConsoleBootloader::class,
Bootloader\Infrastructure\HttpBootloader::class,
Bootloader\Infrastructure\SecurityBootloader::class,
Bootloader\Infrastructure\CycleOrmBootloader::class,
Bootloader\Infrastructure\RoadRunnerBootloader::class,

EventBootloader::class,

PrototypeBootloader::class,

GithubBootloader::class,
];
}
}
30 changes: 30 additions & 0 deletions app/app/src/Endpoint/Centrifugo/ConnectService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace App\Endpoint\Centrifugo;

use RoadRunner\Centrifugo\Payload\ConnectResponse;
use RoadRunner\Centrifugo\Request;
use RoadRunner\Centrifugo\Request\RequestInterface;
use Spiral\RoadRunnerBridge\Centrifugo\ServiceInterface;

class ConnectService implements ServiceInterface
{
/**
* @param Request\Connect $request
*/
public function handle(RequestInterface $request): void
{
try {
$request->respond(
new ConnectResponse(
user: (string)$request->getAttribute('user_id'),
channels: ['events'],
),
);
} catch (\Throwable $e) {
$request->error($e->getCode(), $e->getMessage());
}
}
}

0 comments on commit f8fa834

Please sign in to comment.