forked from zircote/swagger-php
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add example schema-query-parameter-attributes processor (zircote#1569)
- Loading branch information
Showing
8 changed files
with
307 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 84 additions & 0 deletions
84
Examples/processors/schema-query-parameter-attributes/SchemaQueryParameter.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace SchemaQueryParameterProcessor; | ||
|
||
use OpenApi\Analysis; | ||
use OpenApi\Annotations\Operation; | ||
use OpenApi\Generator; | ||
use OpenApi\Attributes\Parameter; | ||
use OpenApi\Attributes\Schema; | ||
|
||
/** | ||
* Custom processor to translate the vendor tag `query-args-$ref` into query parameter annotations. | ||
* | ||
* Details for the parameters are taken from the referenced schema. | ||
*/ | ||
class SchemaQueryParameter | ||
{ | ||
public const REF = 'query-args-$ref'; | ||
|
||
public function __invoke(Analysis $analysis): void | ||
{ | ||
/** @var Operation[] $operations */ | ||
$operations = $analysis->getAnnotationsOfType(Operation::class); | ||
|
||
foreach ($operations as $operation) { | ||
if ($operation->x !== Generator::UNDEFINED && array_key_exists(self::REF, $operation->x)) { | ||
if (!is_string($operation->x[self::REF])) { | ||
throw new \InvalidArgumentException('Value of `x.' . self::REF . '` must be a string'); | ||
} | ||
|
||
$schema = $analysis->getSchemaForSource($operation->x[self::REF]); | ||
if (!$schema instanceof Schema) { | ||
throw new \InvalidArgumentException('Value of `x.' . self::REF . "` contains reference to unknown schema: `{$operation->x[self::REF]}`"); | ||
} | ||
|
||
$this->expandQueryArgs($operation, $schema); | ||
$this->cleanUp($operation); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Expand the given operation by injecting parameters for all properties of the given schema. | ||
*/ | ||
private function expandQueryArgs(Operation $operation, Schema $schema): void | ||
{ | ||
if ($schema->properties === Generator::UNDEFINED || !$schema->properties) { | ||
return; | ||
} | ||
|
||
$operation->parameters = $operation->parameters === Generator::UNDEFINED ? [] : $operation->parameters; | ||
|
||
foreach ($schema->properties as $property) { | ||
$isNullable = $property->nullable !== Generator::UNDEFINED ? $property->nullable : false; | ||
$schema = new Schema( | ||
type: $property->format !== Generator::UNDEFINED ? $property->format : $property->type, | ||
nullable: $isNullable | ||
); | ||
$schema->_context = $operation->_context; // inherit context from operation, required to pretend to be a parameter | ||
|
||
$parameter = new Parameter( | ||
name: $property->property, | ||
description: $property->description !== Generator::UNDEFINED ? $property->description : null, | ||
in: 'query', | ||
required: !$isNullable, | ||
schema: $schema, | ||
example: $property->example, | ||
); | ||
$parameter->_context = $operation->_context; // inherit context from operation, required to pretend to be a parameter | ||
|
||
$operation->parameters[] = $parameter; | ||
} | ||
} | ||
|
||
private function cleanUp(Operation $operation): void | ||
{ | ||
unset($operation->x[self::REF]); | ||
if (!$operation->x) { | ||
$operation->x = Generator::UNDEFINED; | ||
} | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
Examples/processors/schema-query-parameter-attributes/app/OpenApi.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?php | ||
|
||
namespace App; | ||
|
||
use OpenApi\Attributes as OA; | ||
|
||
/** | ||
* Uses a custom processor `QueryArgsFromSchema` processor to convert a vendor extension into query parameters. | ||
* | ||
* The parameters are extracted from the schema referenced by the custom extension. | ||
*/ | ||
#[OA\OpenApi( | ||
info: new OA\Info(version: '1.0.0', title: 'Example of using a custom processor in swagger-php'), | ||
)] | ||
class OpenApi | ||
{ | ||
} |
26 changes: 26 additions & 0 deletions
26
Examples/processors/schema-query-parameter-attributes/app/Product.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
|
||
namespace App; | ||
|
||
use OpenApi\Attributes as OA; | ||
|
||
#[OA\Schema( | ||
title: 'Product', | ||
description: 'A simple product model', | ||
)] | ||
class Product | ||
{ | ||
public function __construct( | ||
#[OA\Property( | ||
title: 'The unique identifier of a product in our catalog.', | ||
example: 43, | ||
)] | ||
public int $id, | ||
#[OA\Property( | ||
title: 'The name of the product.', | ||
example: 'Lorem ipsum', | ||
)] | ||
public string|null $name, | ||
) { | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
Examples/processors/schema-query-parameter-attributes/app/ProductController.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App; | ||
|
||
use OpenApi\Attributes as OA; | ||
use OpenApi\Attributes\Response; | ||
use SchemaQueryParameterProcessor\SchemaQueryParameter; | ||
|
||
class ProductController | ||
{ | ||
#[OA\Get( | ||
path: '/products/{id}', | ||
tags: ['Products'], | ||
parameters: [ | ||
new OA\PathParameter( | ||
name: 'id', | ||
required: true, | ||
), | ||
], | ||
responses: [ | ||
new Response( | ||
response: 200, | ||
description: 'A single product', | ||
content: new OA\JsonContent( | ||
ref: Product::class | ||
) | ||
), | ||
], | ||
)] | ||
public function getProduct($id) | ||
{ | ||
} | ||
|
||
#[OA\Get( | ||
path: '/products/search', | ||
tags: ['Products'], | ||
responses: [ | ||
new Response( | ||
response: 200, | ||
description: 'A single product', | ||
content: new OA\JsonContent( | ||
type: 'array', | ||
items: new OA\Items(ref: Product::class) | ||
) | ||
), | ||
], | ||
x: [SchemaQueryParameter::REF => Product::class], | ||
)] | ||
public function findProducts($id) | ||
{ | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
Examples/processors/schema-query-parameter-attributes/scan.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php | ||
|
||
use OpenApi\Generator; | ||
use OpenApi\Processors\BuildPaths; | ||
use SchemaQueryParameterProcessor\SchemaQueryParameter; | ||
|
||
$classLoader = require __DIR__ . '/../../../vendor/autoload.php'; | ||
|
||
// register our app namespace... | ||
$classLoader->addPsr4('App\\', __DIR__ . '/app'); | ||
// and our custom processor | ||
$classLoader->addPsr4('SchemaQueryParameterProcessor\\', __DIR__); | ||
|
||
$openapiGenerator = new Generator(); | ||
$processors = []; | ||
foreach ($openapiGenerator->getProcessors() as $processor) { | ||
$processors[] = $processor; | ||
if ($processor instanceof BuildPaths) { | ||
$processors[] = new SchemaQueryParameter(); | ||
} | ||
} | ||
|
||
$openapi = $openapiGenerator | ||
->setProcessors($processors) | ||
->generate([__DIR__ . '/app']); | ||
|
||
file_put_contents(__DIR__ . '/schema-query-parameter.yaml', $openapi->toYaml()); | ||
|
||
echo $openapi->toYaml(); |
69 changes: 69 additions & 0 deletions
69
Examples/processors/schema-query-parameter-attributes/schema-query-parameter.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
openapi: 3.0.0 | ||
info: | ||
title: 'Example of using a custom processor in swagger-php' | ||
version: 1.0.0 | ||
paths: | ||
'/products/{id}': | ||
get: | ||
tags: | ||
- Products | ||
operationId: 399b71a7672f0a46be1b5f4c120c355d | ||
parameters: | ||
- | ||
name: id | ||
in: path | ||
required: true | ||
responses: | ||
'200': | ||
description: 'A single product' | ||
content: | ||
application/json: | ||
schema: | ||
$ref: '#/components/schemas/Product' | ||
/products/search: | ||
get: | ||
tags: | ||
- Products | ||
operationId: 178f74de3417eec20dee95709821e6ca | ||
parameters: | ||
- | ||
name: id | ||
in: query | ||
required: true | ||
schema: | ||
type: integer | ||
nullable: false | ||
example: 43 | ||
- | ||
name: name | ||
in: query | ||
required: false | ||
schema: | ||
type: string | ||
nullable: true | ||
example: 'Lorem ipsum' | ||
responses: | ||
'200': | ||
description: 'A single product' | ||
content: | ||
application/json: | ||
schema: | ||
type: array | ||
items: | ||
$ref: '#/components/schemas/Product' | ||
components: | ||
schemas: | ||
Product: | ||
title: Product | ||
description: 'A simple product model' | ||
properties: | ||
id: | ||
title: 'The unique identifier of a product in our catalog.' | ||
type: integer | ||
example: 43 | ||
name: | ||
title: 'The name of the product.' | ||
type: string | ||
example: 'Lorem ipsum' | ||
nullable: true | ||
type: object |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters