mirror of
https://github.com/retailcrm/NelmioApiDocBundle.git
synced 2025-03-12 10:36:09 +03:00
Add ApiPlatform support
This commit is contained in:
parent
abe82b19a9
commit
170249b369
2
.php_cs
2
.php_cs
@ -21,7 +21,7 @@ HeaderCommentFixer::setHeader($header);
|
|||||||
|
|
||||||
return Config::create()
|
return Config::create()
|
||||||
->level(FixerInterface::SYMFONY_LEVEL)
|
->level(FixerInterface::SYMFONY_LEVEL)
|
||||||
->fixers(array('align_double_arrow', 'header_comment'))
|
->fixers(array('header_comment'))
|
||||||
->finder($finder)
|
->finder($finder)
|
||||||
->setUsingCache(true)
|
->setUsingCache(true)
|
||||||
;
|
;
|
||||||
|
@ -23,6 +23,6 @@ class AddRouteDescribersPass implements CompilerPassInterface
|
|||||||
{
|
{
|
||||||
$routeDescribers = $this->findAndSortTaggedServices('exsyst_api_doc.route_describer', $container);
|
$routeDescribers = $this->findAndSortTaggedServices('exsyst_api_doc.route_describer', $container);
|
||||||
|
|
||||||
$container->getDefinition('exsyst_api_doc.describers.route')->replaceArgument(2, $routeDescribers);
|
$container->getDefinition('exsyst_api_doc.describers.route')->replaceArgument(3, $routeDescribers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,5 +49,11 @@ class EXSystApiDocExtension extends Extension
|
|||||||
if (!class_exists(Swagger::class)) {
|
if (!class_exists(Swagger::class)) {
|
||||||
$container->removeDefinition('exsyst_api_doc.describers.swagger_php');
|
$container->removeDefinition('exsyst_api_doc.describers.swagger_php');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$bundles = $container->getParameter('kernel.bundles');
|
||||||
|
// ApiPlatform support
|
||||||
|
if (isset($bundles['ApiPlatformBundle']) && class_exists('ApiPlatform\Core\Documentation\Documentation')) {
|
||||||
|
$loader->load('api_platform.xml');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
28
Describer/ApiPlatformDescriber.php
Normal file
28
Describer/ApiPlatformDescriber.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the ApiDocBundle package.
|
||||||
|
*
|
||||||
|
* (c) EXSyst
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace EXSyst\Bundle\ApiDocBundle\Describer;
|
||||||
|
|
||||||
|
use ApiPlatform\Core\Documentation\Documentation;
|
||||||
|
use ApiPlatform\Core\Swagger\DocumentationNormalizer;
|
||||||
|
|
||||||
|
class ApiPlatformDescriber extends ExternalDocDescriber
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param string $projectPath
|
||||||
|
*/
|
||||||
|
public function __construct(Documentation $documentation, DocumentationNormalizer $normalizer, bool $overwrite = false)
|
||||||
|
{
|
||||||
|
parent::__construct(function () use ($documentation, $normalizer) {
|
||||||
|
return $normalizer->normalize($documentation);
|
||||||
|
}, $overwrite);
|
||||||
|
}
|
||||||
|
}
|
@ -11,35 +11,30 @@
|
|||||||
|
|
||||||
namespace EXSyst\Bundle\ApiDocBundle\Describer;
|
namespace EXSyst\Bundle\ApiDocBundle\Describer;
|
||||||
|
|
||||||
use Doctrine\Common\Util\ClassUtils;
|
|
||||||
use EXSyst\Bundle\ApiDocBundle\RouteDescriber\RouteDescriberInterface;
|
|
||||||
use gossi\swagger\Swagger;
|
use gossi\swagger\Swagger;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser;
|
|
||||||
use Symfony\Component\Routing\Route;
|
|
||||||
use Symfony\Component\Routing\RouterInterface;
|
|
||||||
|
|
||||||
class ExternalDocDescriber implements DescriberInterface
|
class ExternalDocDescriber implements DescriberInterface
|
||||||
{
|
{
|
||||||
private $externalDoc;
|
private $externalDoc;
|
||||||
private $stategy;
|
private $overwrite;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array|callable $externalDoc
|
* @param array|callable $externalDoc
|
||||||
* @param int $strategy
|
* @param int $strategy
|
||||||
*/
|
*/
|
||||||
public function __construct($externalDoc, $strategy = Swagger::PREFER_ORIGINAL)
|
public function __construct($externalDoc, bool $overwrite = false)
|
||||||
{
|
{
|
||||||
$this->externalDoc = $externalDoc;
|
$this->externalDoc = $externalDoc;
|
||||||
$this->strategy = $strategy;
|
$this->overwrite = $overwrite;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function describe(Swagger $api)
|
public function describe(Swagger $api)
|
||||||
{
|
{
|
||||||
$externalDoc = $this->getExternalDoc();
|
$externalDoc = $this->getExternalDoc();
|
||||||
$api->merge($externalDoc, $this->strategy);
|
$api->merge($externalDoc, $this->overwrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getExternalDoc(): array
|
private function getExternalDoc()
|
||||||
{
|
{
|
||||||
if (is_callable($this->externalDoc)) {
|
if (is_callable($this->externalDoc)) {
|
||||||
return call_user_func($this->externalDoc);
|
return call_user_func($this->externalDoc);
|
||||||
|
@ -15,20 +15,26 @@ use Doctrine\Common\Util\ClassUtils;
|
|||||||
use EXSyst\Bundle\ApiDocBundle\RouteDescriber\RouteDescriberInterface;
|
use EXSyst\Bundle\ApiDocBundle\RouteDescriber\RouteDescriberInterface;
|
||||||
use gossi\swagger\Swagger;
|
use gossi\swagger\Swagger;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser;
|
use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
use Symfony\Component\Routing\Route;
|
use Symfony\Component\Routing\Route;
|
||||||
use Symfony\Component\Routing\RouterInterface;
|
use Symfony\Component\Routing\RouterInterface;
|
||||||
|
|
||||||
class RouteDescriber implements DescriberInterface
|
class RouteDescriber implements DescriberInterface
|
||||||
{
|
{
|
||||||
|
private $container;
|
||||||
|
private $router;
|
||||||
|
private $controllerNameParser;
|
||||||
private $routeDescribers;
|
private $routeDescribers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param ContainerInterface $container
|
||||||
* @param RouterInterface $router
|
* @param RouterInterface $router
|
||||||
* @param ControllerNameParser $controllerNameParser
|
* @param ControllerNameParser $controllerNameParser
|
||||||
* @param RouteDescriberInterface[] $routeDescribers
|
* @param RouteDescriberInterface[] $routeDescribers
|
||||||
*/
|
*/
|
||||||
public function __construct(RouterInterface $router, ControllerNameParser $controllerNameParser, array $routeDescribers)
|
public function __construct(ContainerInterface $container, RouterInterface $router, ControllerNameParser $controllerNameParser, array $routeDescribers)
|
||||||
{
|
{
|
||||||
|
$this->container = $container;
|
||||||
$this->router = $router;
|
$this->router = $router;
|
||||||
$this->controllerNameParser = $controllerNameParser;
|
$this->controllerNameParser = $controllerNameParser;
|
||||||
$this->routeDescribers = $routeDescribers;
|
$this->routeDescribers = $routeDescribers;
|
||||||
|
@ -11,31 +11,17 @@
|
|||||||
|
|
||||||
namespace EXSyst\Bundle\ApiDocBundle\Describer;
|
namespace EXSyst\Bundle\ApiDocBundle\Describer;
|
||||||
|
|
||||||
use gossi\swagger\Swagger;
|
class SwaggerPhpDescriber extends ExternalDocDescriber
|
||||||
|
|
||||||
class SwaggerPhpDescriber implements DescriberInterface
|
|
||||||
{
|
{
|
||||||
private $projectPath;
|
|
||||||
private $overwrite;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $projectPath
|
* @param string $projectPath
|
||||||
*/
|
*/
|
||||||
public function __construct(string $projectPath, bool $overwrite = false)
|
public function __construct(string $projectPath, bool $overwrite = false)
|
||||||
{
|
{
|
||||||
$this->projectPath = $projectPath;
|
parent::__construct(function () use ($projectPath) {
|
||||||
$this->overwrite = $overwrite;
|
$annotation = \Swagger\scan($projectPath);
|
||||||
}
|
|
||||||
|
|
||||||
public function describe(Swagger $api)
|
return json_decode(json_encode($annotation));
|
||||||
{
|
}, $overwrite);
|
||||||
$annotation = \Swagger\scan($this->projectPath);
|
|
||||||
|
|
||||||
$api->merge($this->normalize($annotation), $this->overwrite);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function normalize($annotation)
|
|
||||||
{
|
|
||||||
return json_decode(json_encode($annotation));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
26
Model/ModelDescriber.php
Normal file
26
Model/ModelDescriber.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace EXSyst\Bundle\ApiDocBundle\Model;
|
||||||
|
|
||||||
|
use gossi\swagger\Schema;
|
||||||
|
|
||||||
|
class ModelDescriber
|
||||||
|
{
|
||||||
|
private $namingStrategy;
|
||||||
|
private $models = [];
|
||||||
|
|
||||||
|
public function __construct(callable $namingStrategy = null)
|
||||||
|
{
|
||||||
|
if (null === namingStrategy) {
|
||||||
|
$namingStrategy = function ($class) {
|
||||||
|
return str_replace('\\', '_', $class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->namingStrategy = $namingStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function describe(string $class, array $options = []): Schema
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
19
Resources/config/api_platform.xml
Normal file
19
Resources/config/api_platform.xml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" ?>
|
||||||
|
<container xmlns="http://symfony.com/schema/dic/services"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||||
|
|
||||||
|
<services>
|
||||||
|
<service id="exsyst_api_doc.describers.api_platform" class="EXSyst\Bundle\ApiDocBundle\Describer\ApiPlatformDescriber" public="false">
|
||||||
|
<argument type="service" id="exsyst_api_doc.describers.api_platform.documentation" />
|
||||||
|
<argument type="service" id="api_platform.swagger.normalizer.documentation" />
|
||||||
|
|
||||||
|
<tag name="exsyst_api_doc.describer" priority="-150" />
|
||||||
|
</service>
|
||||||
|
|
||||||
|
<service id="exsyst_api_doc.describers.api_platform.documentation" class="ApiPlatform\Core\Documentation\Documentation" public="false">
|
||||||
|
<factory service="api_platform.action.documentation" method="__invoke" />
|
||||||
|
</service>
|
||||||
|
</services>
|
||||||
|
|
||||||
|
</container>
|
@ -16,6 +16,7 @@
|
|||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service id="exsyst_api_doc.describers.route" class="EXSyst\Bundle\ApiDocBundle\Describer\RouteDescriber" public="false">
|
<service id="exsyst_api_doc.describers.route" class="EXSyst\Bundle\ApiDocBundle\Describer\RouteDescriber" public="false">
|
||||||
|
<argument type="service" id="service_container" />
|
||||||
<argument type="service" id="router" />
|
<argument type="service" id="router" />
|
||||||
<argument type="service" id="controller_name_converter" />
|
<argument type="service" id="controller_name_converter" />
|
||||||
<argument type="collection" />
|
<argument type="collection" />
|
||||||
|
68
Tests/Functional/Entity/Dummy.php
Normal file
68
Tests/Functional/Entity/Dummy.php
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the ApiDocBundle package.
|
||||||
|
*
|
||||||
|
* (c) EXSyst
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace EXSyst\Bundle\ApiDocBundle\Tests\Functional\Entity;
|
||||||
|
|
||||||
|
use ApiPlatform\Core\Annotation\ApiProperty;
|
||||||
|
use ApiPlatform\Core\Annotation\ApiResource;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Guilhem N. <egetick@gmail.com>
|
||||||
|
*
|
||||||
|
* @ApiResource(
|
||||||
|
* collectionOperations={"get"={"method"="GET"}},
|
||||||
|
* itemOperations={"get"={"method"="GET"}})
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
class Dummy
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*
|
||||||
|
* @Assert\NotBlank
|
||||||
|
* @ApiProperty(iri="http://schema.org/name")
|
||||||
|
*/
|
||||||
|
private $name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $foo;
|
||||||
|
|
||||||
|
public function getId(): int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setName(string $name)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(): string
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasRole(string $role)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFoo(array $foo = null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
18
Tests/Functional/TestBundle.php
Normal file
18
Tests/Functional/TestBundle.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the ApiDocBundle package.
|
||||||
|
*
|
||||||
|
* (c) EXSyst
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace EXSyst\Bundle\ApiDocBundle\Tests\Functional;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||||
|
|
||||||
|
class TestBundle extends Bundle
|
||||||
|
{
|
||||||
|
}
|
@ -9,7 +9,9 @@
|
|||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use ApiPlatform\Core\Bridge\Symfony\Bundle\ApiPlatformBundle;
|
||||||
use EXSyst\Bundle\ApiDocBundle\EXSystApiDocBundle;
|
use EXSyst\Bundle\ApiDocBundle\EXSystApiDocBundle;
|
||||||
|
use EXSyst\Bundle\ApiDocBundle\Tests\Functional\TestBundle;
|
||||||
use Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle;
|
use Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle;
|
||||||
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
|
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
|
||||||
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
|
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
|
||||||
@ -30,7 +32,9 @@ class TestKernel extends Kernel
|
|||||||
return [
|
return [
|
||||||
new FrameworkBundle(),
|
new FrameworkBundle(),
|
||||||
new SensioFrameworkExtraBundle(),
|
new SensioFrameworkExtraBundle(),
|
||||||
|
new ApiPlatformBundle(),
|
||||||
new EXSystApiDocBundle(),
|
new EXSystApiDocBundle(),
|
||||||
|
new TestBundle(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,6 +44,7 @@ class TestKernel extends Kernel
|
|||||||
protected function configureRoutes(RouteCollectionBuilder $routes)
|
protected function configureRoutes(RouteCollectionBuilder $routes)
|
||||||
{
|
{
|
||||||
$routes->import(__DIR__.'/Controller/', '/', 'annotation');
|
$routes->import(__DIR__.'/Controller/', '/', 'annotation');
|
||||||
|
$routes->import('', '/api', 'api_platform');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,7 +54,8 @@ class TestKernel extends Kernel
|
|||||||
{
|
{
|
||||||
$c->loadFromExtension('framework', [
|
$c->loadFromExtension('framework', [
|
||||||
'secret' => 'MySecretKey',
|
'secret' => 'MySecretKey',
|
||||||
'test' => null,
|
'test' => null,
|
||||||
|
'validation' => null,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,21 +10,27 @@
|
|||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.0",
|
"php": "^7.0",
|
||||||
"symfony/framework-bundle": "^3.2@dev",
|
"symfony/framework-bundle": "^3.2",
|
||||||
"exsyst/swagger": "dev-master"
|
"exsyst/swagger": "dev-master"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/browser-kit": "^2.8|^3.0",
|
"symfony/validator": "^3.2",
|
||||||
"symfony/phpunit-bridge": "^3.2@dev",
|
"symfony/property-access": "^3.2",
|
||||||
|
"symfony/browser-kit": "^3.2",
|
||||||
|
"symfony/cache": "^3.2",
|
||||||
|
"symfony/phpunit-bridge": "^3.2",
|
||||||
"sensio/framework-extra-bundle": "^3.0",
|
"sensio/framework-extra-bundle": "^3.0",
|
||||||
"nelmio/api-doc-bundle": "^2.0",
|
"nelmio/api-doc-bundle": "^2.0",
|
||||||
"phpdocumentor/reflection-docblock": "^3.1",
|
"phpdocumentor/reflection-docblock": "^3.1",
|
||||||
"phpunit/phpunit": "^5.4",
|
"phpunit/phpunit": "^5.4",
|
||||||
"zircote/swagger-php": "^2.0"
|
"zircote/swagger-php": "^2.0",
|
||||||
|
"api-platform/core": "^2.0"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"nelmio/api-doc-bundle": "For using the ApiDoc annotation.",
|
"nelmio/api-doc-bundle": "For using the ApiDoc annotation.",
|
||||||
"phpdocumentor/reflection-docblock": "For parsing php docs."
|
"phpdocumentor/reflection-docblock": "For parsing php docs.",
|
||||||
|
"zircote/swagger-php": "For using swagger annotations.",
|
||||||
|
"api-platform/core": "For using an API oriented framework."
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user