Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: async api schema v3 without operations #23

Merged
merged 15 commits into from
Feb 3, 2024
11 changes: 7 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ on:
jobs:
tests:
runs-on: ubuntu-latest
name: CI - PHP ${{ matrix.php }}, Dependencies ${{ matrix.dependencies }}
name: CI - PHP ${{ matrix.php }}, Dependencies ${{ matrix.dependencies }}, Schema ${{ matrix.schema }}
env:
ASYNCAPI_VERSION: ${{ matrix.schema }}
strategy:
matrix:
php: [8.2, 8.3]
schema: [3.0.0, 2.6.0]
dependencies: [lowest, highest]
include:
-
Expand Down Expand Up @@ -55,12 +58,12 @@ jobs:
- # Run AsyncAPI Validation
name: AsyncAPI Validation
run: |
docker run --rm -v $(pwd):/app asyncapi/cli:1.4.4 validate /app/var/asyncapi.yaml
docker run --rm -v $(pwd):/app asyncapi/cli:1.4.4 validate /app/var/asyncapi.json
docker run --rm -v $(pwd):/app asyncapi/cli:1.4.4 validate /app/var/${{ matrix.schema }}/asyncapi.yaml
docker run --rm -v $(pwd):/app asyncapi/cli:1.4.4 validate /app/var/${{ matrix.schema }}/asyncapi.json

- # Upload Coverage to Coveralls
name: Coveralls
if: ${{ matrix.coveralls }}
if: ${{ matrix.coveralls && github.event_name == 'pull_request' }}
uses: coverallsapp/[email protected]
with:
file: var/coverage/clover.xml
1 change: 1 addition & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

<php>
<env name="KERNEL_CLASS" value="Ferror\AsyncapiDocBundle\Tests\Integration\Service\Kernel" />
<env name="ASYNCAPI_VERSION" value="3.0.0" />
</php>

<source
Expand Down
4 changes: 2 additions & 2 deletions src/Generator/GeneratorFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

use Ferror\AsyncapiDocBundle\DataFormat;
use Ferror\AsyncapiDocBundle\GeneratorInterface;
use Ferror\AsyncapiDocBundle\Schema\V2\SchemaRenderer;
use Ferror\AsyncapiDocBundle\SchemaRendererInterface;

final readonly class GeneratorFactory
{
public function __construct(private SchemaRenderer $generator)
public function __construct(private SchemaRendererInterface $generator)
{
}

Expand Down
4 changes: 2 additions & 2 deletions src/Generator/JsonGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
namespace Ferror\AsyncapiDocBundle\Generator;

use Ferror\AsyncapiDocBundle\GeneratorInterface;
use Ferror\AsyncapiDocBundle\Schema\V2\SchemaRenderer;
use Ferror\AsyncapiDocBundle\SchemaRendererInterface;
use JsonException;

final readonly class JsonGenerator implements GeneratorInterface
{
public function __construct(private SchemaRenderer $generator)
public function __construct(private SchemaRendererInterface $generator)
{
}

Expand Down
4 changes: 2 additions & 2 deletions src/Generator/YamlGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
namespace Ferror\AsyncapiDocBundle\Generator;

use Ferror\AsyncapiDocBundle\GeneratorInterface;
use Ferror\AsyncapiDocBundle\Schema\V2\SchemaRenderer;
use Ferror\AsyncapiDocBundle\SchemaRendererInterface;
use Symfony\Component\Yaml\Yaml;

final readonly class YamlGenerator implements GeneratorInterface
{
public function __construct(private SchemaRenderer $generator)
public function __construct(private SchemaRendererInterface $generator)
{
}

Expand Down
10 changes: 8 additions & 2 deletions src/Schema/SchemaGeneratorFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@

namespace Ferror\AsyncapiDocBundle\Schema;

use Ferror\AsyncapiDocBundle\Schema\V2\SchemaRenderer;
use Ferror\AsyncapiDocBundle\Schema\V2\SchemaRenderer as SchemaV2Renderer;
use Ferror\AsyncapiDocBundle\Schema\V3\SchemaRenderer as SchemaV3Renderer;
use Ferror\AsyncapiDocBundle\SchemaRendererInterface;
use InvalidArgumentException;

final readonly class SchemaGeneratorFactory
{
public function __construct(
private SchemaRenderer $schemaGeneratorV2,
private SchemaV2Renderer $schemaGeneratorV2,
private SchemaV3Renderer $schemaGeneratorV3,
) {
}

Expand All @@ -23,6 +25,10 @@ public function __invoke(string $version): SchemaRendererInterface
return $this->schemaGeneratorV2;
}

if ($major === '3') {
return $this->schemaGeneratorV3;
}

throw new InvalidArgumentException("Not supported Async API Schema $version");
}
}
25 changes: 25 additions & 0 deletions src/Schema/V3/ChannelRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Ferror\AsyncapiDocBundle\Schema\V3;

final readonly class ChannelRenderer
{
public function render(array $document): array
{
$channels = [];

foreach ($document['channels'] as $channel) {
$channels[$channel['name']] = [
'messages' => [
$document['name'] => [
'$ref' => '#/components/messages/' . $document['name'],
]
],
];
}

return $channels;
}
}
24 changes: 24 additions & 0 deletions src/Schema/V3/InfoRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Ferror\AsyncapiDocBundle\Schema\V3;

final readonly class InfoRenderer
{
public function __construct(
public string $title,
public string $description,
public string $version,
) {
}

public function render(): array
{
return [
'title' => $this->title,
'version' => $this->version,
'description' => $this->description,
];
}
}
46 changes: 46 additions & 0 deletions src/Schema/V3/MessageRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace Ferror\AsyncapiDocBundle\Schema\V3;

use Ferror\AsyncapiDocBundle\PropertyTypeTranslator;

final readonly class MessageRenderer
{
public function render(array $document): array
{
$properties = [];
$required = [];

foreach ($document['properties'] as $property) {
$properties[$property['name']]['type'] = PropertyTypeTranslator::translate($property['type']);

if (!empty($property['description'])) {
$properties[$property['name']]['description'] = $property['description'];
}

if (!empty($property['format'])) {
$properties[$property['name']]['format'] = $property['format'];
}

if (!empty($property['example'])) {
$properties[$property['name']]['example'] = $property['example'];
}

if (isset($property['required']) && $property['required']) {
$required[] = $property['name'];
}
}

$message[$document['name']] = [
'payload' => [
'type' => 'object',
'properties' => $properties,
'required' => $required,
],
];

return $message;
}
}
50 changes: 48 additions & 2 deletions src/Schema/V3/SchemaRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,59 @@

namespace Ferror\AsyncapiDocBundle\Schema\V3;

use Ferror\AsyncapiDocBundle\ClassFinder\ClassFinderInterface;
use Ferror\AsyncapiDocBundle\DocumentationEditor;
use Ferror\AsyncapiDocBundle\SchemaRendererInterface;
use RuntimeException;

final readonly class SchemaRenderer implements SchemaRendererInterface
{
public function __construct(
private ClassFinderInterface $classFinder,
private DocumentationEditor $documentationEditor,
private InfoRenderer $infoRenderer,
private MessageRenderer $messageRenderer,
private ChannelRenderer $channelRenderer,
private ServerRenderer $serverRenderer,
private string $schemaVersion,
) {
}

public function generate(): array
{
throw new RuntimeException("Async API V3 not yet supported");
$classes = $this->classFinder->find();

$channels = [];
$messages = [];

foreach ($classes as $class) {
$document = $this->documentationEditor->document($class);
$document = $document->toArray();

$channel = $this->channelRenderer->render($document);
$message = $this->messageRenderer->render($document);

$channelKey = key($channel);
$messageKey = key($message);

$channels[$channelKey] = $channel[$channelKey];
$messages[$messageKey] = $message[$messageKey];
}

$schema = [
'asyncapi' => $this->schemaVersion,
'info' => $this->infoRenderer->render(),
'channels' => $channels,
'components' => [
'messages' => $messages,
],
];

$servers = $this->serverRenderer->render();

if ($servers) {
$schema['servers'] = $servers;
}

return $schema;
}
}
27 changes: 27 additions & 0 deletions src/Schema/V3/ServerRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace Ferror\AsyncapiDocBundle\Schema\V3;

final readonly class ServerRenderer
{
public function __construct(private array $servers)
{
}

public function render(): array
{
$servers = [];

foreach ($this->servers as $name => $properties) {
$url = $properties['url'];
unset($properties['url']);
$properties['host'] = $url;

$servers[$name] = $properties;
}

return $servers;
}
}
1 change: 0 additions & 1 deletion src/Symfony/Console/DumpSpecificationConsole.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Ferror\AsyncapiDocBundle\Symfony\Console;


use Ferror\AsyncapiDocBundle\DataFormat;
use Ferror\AsyncapiDocBundle\DocumentationStrategy\DocumentationStrategyInterface;
use Ferror\AsyncapiDocBundle\Generator\GeneratorFactory;
Expand Down
Loading
Loading