Skip to content

Commit 79c91c4

Browse files
committed
[#34] ApiDocumentationBundle implementation
0 parents  commit 79c91c4

29 files changed

+1668
-0
lines changed

Diff for: .gitignore

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/vendor
2+
/reports
3+
.phpunit.result.cache
4+
/var
5+
composer.lock
6+
/coverage
7+
.php-cs-fixer.cache

Diff for: .php-cs-fixer.dist.php

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
$finder = PhpCsFixer\Finder::create()
4+
->in(__DIR__);
5+
6+
return (new PhpCsFixer\Config())
7+
->setRules([
8+
'@Symfony' => true,
9+
'array_syntax' => ['syntax' => 'short'],
10+
])
11+
->setFinder($finder);

Diff for: LICENSE

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Copyright (c) Fusonic GmbH (https://www.fusonic.net)
2+
3+
Permission is hereby granted, free of charge, to any person obtaining
4+
a copy of this software and associated documentation files (the
5+
"Software"), to deal in the Software without restriction, including
6+
without limitation the rights to use, copy, modify, merge, publish,
7+
distribute, sublicense, and/or sell copies of the Software, and to
8+
permit persons to whom the Software is furnished to do so, subject to
9+
the following conditions:
10+
11+
The above copyright notice and this permission notice shall be
12+
included in all copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Diff for: README.md

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# fusonic-api-documentation-bundle
2+
3+
[![License](https://img.shields.io/packagist/l/fusonic/fusonic-api-documentation-bundle?color=blue)](https://github.com/fusonic/fusonic-api-documentation-bundle/blob/master/LICENSE)
4+
[![Latest Version](https://img.shields.io/github/tag/fusonic/fusonic-api-documentation-bundle.svg?color=blue)](https://github.com/fusonic/fusonic-api-documentation-bundle/releases)
5+
[![Total Downloads](https://img.shields.io/packagist/dt/fusonic/fusonic-api-documentation-bundle.svg?color=blue)](https://packagist.org/packages/fusonic/fusonic-api-documentation-bundle)
6+
![php 8.0+](https://img.shields.io/badge/php-min%208.0-blue.svg)
7+
8+
* [About](#about)
9+
* [Install](#install)
10+
* [Usage](#usage)
11+
* [Contributing](#contributing)
12+
13+
## About
14+
15+
This bundle makes generating documentation of your (json) API routes easier. It provides a custom route annotation that
16+
can parse the input and output model of a route to generate documentation definitions for
17+
[NelmioApiDocBundle](https://symfony.com/bundles/NelmioApiDocBundle/current/index.html). If you are using
18+
type hints for the input and output it can be detected automatically, see [Usage](#Usage) on how to do this.
19+
20+
With just [NelmioApiDocBundle](https://symfony.com/bundles/NelmioApiDocBundle/current/index.html) you will often find yourself
21+
writing many annotations with a repetitive pattern. With this bundle common annotation combinations are bundled into one
22+
single route attribute.
23+
24+
This bundle can work well together with
25+
the [http-kernel-extensions](https://github.com/fusonic/php-http-kernel-extensions).
26+
27+
## Install
28+
29+
Use composer to install the bundle from packagist.
30+
31+
```bash
32+
composer require fusonic/fusonic-api-documentation-bundle
33+
```
34+
35+
Requirements:
36+
37+
- PHP 8.1+
38+
- Symfony 5.4+
39+
40+
In case Symfony did not add the bundle to the bundle configuration, add the following (by default located
41+
in `config/bundles.php`):
42+
43+
```
44+
<?php
45+
46+
return [
47+
// ...
48+
Fusonic\ApiDocumentationBundle\FusonicApiDocumentationBundle::class => ['all' => true],
49+
];
50+
```
51+
52+
Next you need to configure [NelmioApiDocBundle](https://symfony.com/bundles/NelmioApiDocBundle/current/index.html).
53+
54+
There is one optional configuration for this bundle:
55+
56+
```yaml
57+
fusonic_api_documentation:
58+
# An attribute, class, or interface that is used to detect which object to parse the "input" model from.
59+
# If you do not configure this, automatic input detection will not work.
60+
request_object_class: Fusonic\ApiDocumentationBundle\Tests\App\FromRequest
61+
```
62+
63+
## Usage
64+
65+
Different examples can be found in the [tests](./tests/App/Controller/TestController.php).
66+
67+
#### Example route with automatic type detection
68+
69+
If you have some kind of response listener that allows you to return objects directly from your controller then you
70+
can use the automatic output detection based on the return type or return annotation.
71+
72+
```php
73+
#[DocumentedRoute(path: '/test-return-type/{id}', methods: ['GET'])]
74+
public function testReturnType(#[FromRequest] TestRequest $query): TestResponse
75+
{
76+
return new TestResponse($query->id);
77+
}
78+
```
79+
80+
If you return an array or a generic type, you can set the return type (e.g.: `SomeType[]` or `SomeGeneric<SomeType>).
81+
The only requirement here is that you can only have one return type. Multiple return types are not supported.
82+
83+
#### Example route with manual input/output
84+
85+
If you do not support argument resolving and returning objects directly you can define the `input` and `output`
86+
classes manually.
87+
88+
```php
89+
#[DocumentedRoute(path: '/test-return-type/{id}', methods: ['GET'], input: TestRequest::class, output: TestResponse::class)]
90+
public function testReturnType(int $id): JsonResponse
91+
{
92+
return new JsonResponse(['id' => $query->id], 200);
93+
}
94+
```
95+
96+
You can also specify builtin types for the output, for example `string`:
97+
98+
```php
99+
#[DocumentedRoute(path: '/test-return-type/{id}', methods: ['GET'], input: TestRequest::class, output: 'string')]
100+
```
101+
102+
If your manually defined output is a collection, you can set `outputIsCollection: true` in addition to the `output`:
103+
104+
```php
105+
#[DocumentedRoute(
106+
path: '/test-return-type/{id}',
107+
methods: ['GET'],
108+
input: TestRequest::class,
109+
output: 'string',
110+
outputIsCollection: true
111+
)]
112+
```
113+
114+
## Contributing
115+
116+
This is a subtree split of [fusonic/php-extensions](https://github.com/fusonic/php-extensions) repository. Please create
117+
your pull requests there.

Diff for: composer.json

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"name": "fusonic/api-documentation-bundle",
3+
"license": "MIT",
4+
"version": "0.0.1",
5+
"description": "Symfony bundle for automated documentation with NelmioApiDocBundle.",
6+
"type": "symfony-bundle",
7+
"authors": [
8+
{
9+
"name": "Fusonic GmbH",
10+
"email": "[email protected]"
11+
}
12+
],
13+
"autoload": {
14+
"psr-4": {
15+
"Fusonic\\ApiDocumentationBundle\\": "src/"
16+
}
17+
},
18+
"autoload-dev": {
19+
"psr-4": {
20+
"Fusonic\\ApiDocumentationBundle\\Tests\\": "tests/"
21+
},
22+
"classmap": [
23+
"tests/App/TestKernel.php"
24+
]
25+
},
26+
"require-dev": {
27+
"phpstan/phpstan": "^1.5",
28+
"friendsofphp/php-cs-fixer": "^3.8",
29+
"symfony/framework-bundle": "^5.4.9|^6.0",
30+
"phpstan/phpstan-strict-rules": "^1.1",
31+
"phpstan/phpstan-phpunit": "^1.1",
32+
"phpstan/phpstan-symfony": "^1.1",
33+
"symfony/test-pack": "^1.0",
34+
"symfony/yaml": "^5.4.9|^6.0"
35+
},
36+
"require": {
37+
"php": ">=8.1",
38+
"symfony/config": "^5.4.9|^6.0",
39+
"symfony/dependency-injection": "^5.4.9|^6.0",
40+
"symfony/routing": "^5.4.9|^6.0",
41+
"nelmio/api-doc-bundle": "^4.9",
42+
"symfony/property-info": "^5.4.9|^6.0",
43+
"phpunit/phpunit": "^9.5",
44+
"zircote/swagger-php": "^4.4",
45+
"symfony/dom-crawler": "^5.4.9"
46+
},
47+
"scripts": {
48+
"phpstan": "php -d memory_limit=2048M vendor/bin/phpstan analyse",
49+
"phpcs-check": "vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --dry-run --diff --using-cache=yes",
50+
"phpcs-fix": "vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=yes",
51+
"test": "vendor/bin/phpunit --testdox",
52+
"test-coverage" : "vendor/bin/phpunit --coverage-text --coverage-cobertura=coverage/cobertura.xml --coverage-html=coverage/html"
53+
}
54+
}

Diff for: phpstan.neon

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
parameters:
2+
level: 8
3+
paths:
4+
- src
5+
- tests
6+
checkMissingIterableValueType: false
7+
8+
includes:
9+
- vendor/phpstan/phpstan-phpunit/extension.neon
10+
- vendor/phpstan/phpstan-strict-rules/rules.neon
11+
- vendor/phpstan/phpstan-symfony/extension.neon

Diff for: phpunit.xml

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" backupGlobals="false" colors="true"
4+
bootstrap="vendor/autoload.php" failOnRisky="true" failOnWarning="true">
5+
6+
<coverage processUncoveredFiles="true">
7+
<include>
8+
<directory suffix=".php">./src/</directory>
9+
</include>
10+
</coverage>
11+
12+
<php>
13+
<ini name="error_reporting" value="-1"/>
14+
<server name="KERNEL_CLASS" value="TestKernel"/>
15+
</php>
16+
17+
<testsuites>
18+
<testsuite name="Fusonic ApiDocumentationBundle Test Suite">
19+
<directory>./tests/</directory>
20+
</testsuite>
21+
</testsuites>
22+
</phpunit>

0 commit comments

Comments
 (0)