mirror of
https://github.com/retailcrm/NelmioApiDocBundle.git
synced 2025-02-02 15:51:48 +03:00
Doc generation for the specific API version
This commit is contained in:
parent
f0a606b636
commit
1c4f003e76
@ -34,6 +34,7 @@ class DumpCommand extends ContainerAwareCommand
|
|||||||
'Output format like: ' . implode(', ', $this->availableFormats),
|
'Output format like: ' . implode(', ', $this->availableFormats),
|
||||||
$this->availableFormats[0]
|
$this->availableFormats[0]
|
||||||
)
|
)
|
||||||
|
->addOption('api-version', null, InputOption::VALUE_REQUIRED, 'The API version')
|
||||||
->addOption('view', '', InputOption::VALUE_OPTIONAL, '', ApiDoc::DEFAULT_VIEW)
|
->addOption('view', '', InputOption::VALUE_OPTIONAL, '', ApiDoc::DEFAULT_VIEW)
|
||||||
->addOption('no-sandbox', '', InputOption::VALUE_NONE)
|
->addOption('no-sandbox', '', InputOption::VALUE_NONE)
|
||||||
->setName('api:doc:dump')
|
->setName('api:doc:dump')
|
||||||
@ -66,7 +67,11 @@ class DumpCommand extends ContainerAwareCommand
|
|||||||
$this->getContainer()->set('request', new Request(), 'request');
|
$this->getContainer()->set('request', new Request(), 'request');
|
||||||
}
|
}
|
||||||
|
|
||||||
$extractedDoc = $this->getContainer()->get('nelmio_api_doc.extractor.api_doc_extractor')->all($view);
|
$extractor = $this->getContainer()->get('nelmio_api_doc.extractor.api_doc_extractor');
|
||||||
|
$extractedDoc = $input->hasOption('api-version') ?
|
||||||
|
$extractor->allForVersion($input->getOption('api-version'), $view) :
|
||||||
|
$extractor->all($view);
|
||||||
|
|
||||||
$formattedDoc = $formatter->format($extractedDoc);
|
$formattedDoc = $formatter->format($extractedDoc);
|
||||||
|
|
||||||
if ('json' === $format) {
|
if ('json' === $format) {
|
||||||
|
@ -20,9 +20,11 @@ use Symfony\Component\HttpFoundation\Response;
|
|||||||
|
|
||||||
class ApiDocController extends Controller
|
class ApiDocController extends Controller
|
||||||
{
|
{
|
||||||
public function indexAction($view = ApiDoc::DEFAULT_VIEW)
|
public function indexAction(Request $request, $view = ApiDoc::DEFAULT_VIEW)
|
||||||
{
|
{
|
||||||
$extractedDoc = $this->get('nelmio_api_doc.extractor.api_doc_extractor')->all($view);
|
$extractor = $this->get('nelmio_api_doc.extractor.api_doc_extractor');
|
||||||
|
$apiVersion = $request->query->get('_version', null);
|
||||||
|
$extractedDoc = $apiVersion ? $extractor->allForVersion($apiVersion, $view) : $extractor->all($view);
|
||||||
$htmlContent = $this->get('nelmio_api_doc.formatter.html_formatter')->format($extractedDoc);
|
$htmlContent = $this->get('nelmio_api_doc.formatter.html_formatter')->format($extractedDoc);
|
||||||
|
|
||||||
return new Response($htmlContent, 200, array('Content-Type' => 'text/html'));
|
return new Response($htmlContent, 200, array('Content-Type' => 'text/html'));
|
||||||
|
@ -101,6 +101,29 @@ class ApiDocExtractor
|
|||||||
return $this->extractAnnotations($this->getRoutes(), $view);
|
return $this->extractAnnotations($this->getRoutes(), $view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts annotations from routes for specific version
|
||||||
|
*
|
||||||
|
* @param string $apiVersion API version
|
||||||
|
* @param string $view
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function allForVersion($apiVersion, $view = ApiDoc::DEFAULT_VIEW)
|
||||||
|
{
|
||||||
|
$data = $this->all($view);
|
||||||
|
foreach ($data as $k => $a) {
|
||||||
|
// ignore other api version's routes
|
||||||
|
if (
|
||||||
|
$a['annotation']->getRoute()->getDefault('_version') &&
|
||||||
|
!version_compare($apiVersion, $a['annotation']->getRoute()->getDefault('_version'), '=')
|
||||||
|
) {
|
||||||
|
unset($data[$k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of data where each data is an array with the following keys:
|
* Returns an array of data where each data is an array with the following keys:
|
||||||
* - annotation
|
* - annotation
|
||||||
|
@ -119,3 +119,26 @@ By calling an URL with the parameter ``?_doc=1``, you will get the corresponding
|
|||||||
documentation if available.
|
documentation if available.
|
||||||
|
|
||||||
.. _`installation chapter`: https://getcomposer.org/doc/00-intro.md
|
.. _`installation chapter`: https://getcomposer.org/doc/00-intro.md
|
||||||
|
|
||||||
|
Route versions
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
You can define version for the API routes:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
api_v3_products_list:
|
||||||
|
pattern: /api/v3/products.{_format}
|
||||||
|
defaults: { _controller: NelmioApiDocTestBundle:Test:routeVersion, _format: json, _version: "3.0" }
|
||||||
|
requirements:
|
||||||
|
_method: GET
|
||||||
|
api_v1_orders:
|
||||||
|
resource: "@AcmeOrderBundle/Resources/config/routing/orders_v1.yml"
|
||||||
|
defaults: { _version: "1.0" }
|
||||||
|
prefix: /api/v1/orders
|
||||||
|
|
||||||
|
And generate documentation for specific version by the command:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
php app/console api:doc:dump --format=html --api-version=3.0 > api.html
|
||||||
|
|
||||||
|
Or by adding `?_version={version}` to API documentation page URL.
|
||||||
|
@ -19,7 +19,7 @@ class ApiDocExtractorTest extends WebTestCase
|
|||||||
{
|
{
|
||||||
const NB_ROUTES_ADDED_BY_DUNGLAS_API_BUNDLE = 5;
|
const NB_ROUTES_ADDED_BY_DUNGLAS_API_BUNDLE = 5;
|
||||||
|
|
||||||
private static $ROUTES_QUANTITY_DEFAULT = 34; // Routes in the default view
|
private static $ROUTES_QUANTITY_DEFAULT = 35; // Routes in the default view
|
||||||
private static $ROUTES_QUANTITY_PREMIUM = 6; // Routes in the premium view
|
private static $ROUTES_QUANTITY_PREMIUM = 6; // Routes in the premium view
|
||||||
private static $ROUTES_QUANTITY_TEST = 2; // Routes in the test view
|
private static $ROUTES_QUANTITY_TEST = 2; // Routes in the test view
|
||||||
|
|
||||||
@ -96,6 +96,18 @@ class ApiDocExtractorTest extends WebTestCase
|
|||||||
$this->assertEquals('test.dev|test.com', $a5requirements['domain']['requirement']);
|
$this->assertEquals('test.dev|test.com', $a5requirements['domain']['requirement']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testRouteVersionChecking()
|
||||||
|
{
|
||||||
|
$container = $this->getContainer();
|
||||||
|
$extractor = $container->get('nelmio_api_doc.extractor.api_doc_extractor');
|
||||||
|
$data = $extractor->allForVersion('1.5');
|
||||||
|
$this->assertTrue(is_array($data));
|
||||||
|
$this->assertCount(self::$ROUTES_QUANTITY_DEFAULT, $data);
|
||||||
|
$data = $extractor->allForVersion('1.4');
|
||||||
|
$this->assertTrue(is_array($data));
|
||||||
|
$this->assertCount(self::$ROUTES_QUANTITY_DEFAULT - 1, $data);
|
||||||
|
}
|
||||||
|
|
||||||
public function testGet()
|
public function testGet()
|
||||||
{
|
{
|
||||||
$container = $this->getContainer();
|
$container = $this->getContainer();
|
||||||
|
@ -84,6 +84,13 @@ class TestController
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ApiDoc()
|
||||||
|
*/
|
||||||
|
public function routeVersionAction()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ApiDoc(description="Action without HTTP verb")
|
* @ApiDoc(description="Action without HTTP verb")
|
||||||
*/
|
*/
|
||||||
|
@ -253,3 +253,9 @@ test_route_31:
|
|||||||
path: /z-query-requirement-param-not-set
|
path: /z-query-requirement-param-not-set
|
||||||
methods: [GET]
|
methods: [GET]
|
||||||
defaults: { _controller: NelmioApiDocTestBundle:Test:zActionWithRequirementParamNotSet }
|
defaults: { _controller: NelmioApiDocTestBundle:Test:zActionWithRequirementParamNotSet }
|
||||||
|
|
||||||
|
test_route_version_checking:
|
||||||
|
path: /zz-tests-route-version.{_format}
|
||||||
|
methods: [GET]
|
||||||
|
defaults: { _controller: NelmioApiDocTestBundle:Test:routeVersion, _format: json, _version: "1.5" }
|
||||||
|
|
||||||
|
@ -933,3 +933,12 @@ related[b]:
|
|||||||
|
|
||||||
|
|
||||||
### `POST` /zsecured ###
|
### `POST` /zsecured ###
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `GET` /zz-tests-route-version.{_format} ###
|
||||||
|
|
||||||
|
|
||||||
|
#### Requirements ####
|
||||||
|
|
||||||
|
**_format**
|
||||||
|
@ -2316,5 +2316,20 @@ With multiple lines.',
|
|||||||
),
|
),
|
||||||
'deprecated' => false,
|
'deprecated' => false,
|
||||||
),
|
),
|
||||||
|
22 => array(
|
||||||
|
'method' => 'GET',
|
||||||
|
'uri' => '/zz-tests-route-version.{_format}',
|
||||||
|
'requirements' => array(
|
||||||
|
'_format' => array(
|
||||||
|
'requirement' => '',
|
||||||
|
'dataType' => '',
|
||||||
|
'description' => '',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'https' => false,
|
||||||
|
'authentication' => false,
|
||||||
|
'authenticationRoles' => array(),
|
||||||
|
'deprecated' => false,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -1017,3 +1017,12 @@ related[b]:
|
|||||||
|
|
||||||
|
|
||||||
### `POST` /zsecured ###
|
### `POST` /zsecured ###
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `GET` /zz-tests-route-version.{_format} ###
|
||||||
|
|
||||||
|
|
||||||
|
#### Requirements ####
|
||||||
|
|
||||||
|
**_format**
|
||||||
|
@ -2470,5 +2470,23 @@ With multiple lines.',
|
|||||||
),
|
),
|
||||||
'deprecated' => false,
|
'deprecated' => false,
|
||||||
),
|
),
|
||||||
|
27 =>
|
||||||
|
array(
|
||||||
|
'authentication' => false,
|
||||||
|
'method' => 'GET',
|
||||||
|
'uri' => '/zz-tests-route-version.{_format}',
|
||||||
|
'https' => false,
|
||||||
|
'authenticationRoles' => array(),
|
||||||
|
'deprecated' => false,
|
||||||
|
'requirements' =>
|
||||||
|
array(
|
||||||
|
'_format' =>
|
||||||
|
array(
|
||||||
|
'requirement' => '',
|
||||||
|
'dataType' => '',
|
||||||
|
'description' => '',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -25,7 +25,7 @@ class JmsMetadataParserTest extends \PHPUnit_Framework_TestCase
|
|||||||
*/
|
*/
|
||||||
public function testParserWithNestedType($type)
|
public function testParserWithNestedType($type)
|
||||||
{
|
{
|
||||||
$metadataFactory = $this->getMock('Metadata\MetadataFactoryInterface');
|
$metadataFactory = $this->createMock('Metadata\MetadataFactoryInterface');
|
||||||
$docCommentExtractor = $this->getMockBuilder('Nelmio\ApiDocBundle\Util\DocCommentExtractor')
|
$docCommentExtractor = $this->getMockBuilder('Nelmio\ApiDocBundle\Util\DocCommentExtractor')
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
->getMock();
|
->getMock();
|
||||||
@ -56,7 +56,7 @@ class JmsMetadataParserTest extends \PHPUnit_Framework_TestCase
|
|||||||
$metadata->addPropertyMetadata($propertyMetadataBar);
|
$metadata->addPropertyMetadata($propertyMetadataBar);
|
||||||
$metadata->addPropertyMetadata($propertyMetadataBaz);
|
$metadata->addPropertyMetadata($propertyMetadataBaz);
|
||||||
|
|
||||||
$propertyNamingStrategy = $this->getMock('JMS\Serializer\Naming\PropertyNamingStrategyInterface');
|
$propertyNamingStrategy = $this->createMock('JMS\Serializer\Naming\PropertyNamingStrategyInterface');
|
||||||
|
|
||||||
$propertyNamingStrategy
|
$propertyNamingStrategy
|
||||||
->expects($this->at(0))
|
->expects($this->at(0))
|
||||||
@ -131,7 +131,7 @@ class JmsMetadataParserTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
public function testParserWithGroups()
|
public function testParserWithGroups()
|
||||||
{
|
{
|
||||||
$metadataFactory = $this->getMock('Metadata\MetadataFactoryInterface');
|
$metadataFactory = $this->createMock('Metadata\MetadataFactoryInterface');
|
||||||
$docCommentExtractor = $this->getMockBuilder('Nelmio\ApiDocBundle\Util\DocCommentExtractor')
|
$docCommentExtractor = $this->getMockBuilder('Nelmio\ApiDocBundle\Util\DocCommentExtractor')
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
->getMock();
|
->getMock();
|
||||||
@ -332,7 +332,7 @@ class JmsMetadataParserTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
public function testNestedGroups()
|
public function testNestedGroups()
|
||||||
{
|
{
|
||||||
$metadataFactory = $this->getMock('Metadata\MetadataFactoryInterface');
|
$metadataFactory = $this->createMock('Metadata\MetadataFactoryInterface');
|
||||||
$docCommentExtractor = $this->getMockBuilder('Nelmio\ApiDocBundle\Util\DocCommentExtractor')
|
$docCommentExtractor = $this->getMockBuilder('Nelmio\ApiDocBundle\Util\DocCommentExtractor')
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
->getMock();
|
->getMock();
|
||||||
@ -419,7 +419,7 @@ class JmsMetadataParserTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
public function testParserWithVersion()
|
public function testParserWithVersion()
|
||||||
{
|
{
|
||||||
$metadataFactory = $this->getMock('Metadata\MetadataFactoryInterface');
|
$metadataFactory = $this->createMock('Metadata\MetadataFactoryInterface');
|
||||||
$docCommentExtractor = $this->getMockBuilder('Nelmio\ApiDocBundle\Util\DocCommentExtractor')
|
$docCommentExtractor = $this->getMockBuilder('Nelmio\ApiDocBundle\Util\DocCommentExtractor')
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
->getMock();
|
->getMock();
|
||||||
@ -501,7 +501,7 @@ class JmsMetadataParserTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
public function testParserWithInline()
|
public function testParserWithInline()
|
||||||
{
|
{
|
||||||
$metadataFactory = $this->getMock('Metadata\MetadataFactoryInterface');
|
$metadataFactory = $this->createMock('Metadata\MetadataFactoryInterface');
|
||||||
$docCommentExtractor = $this->getMockBuilder('Nelmio\ApiDocBundle\Util\DocCommentExtractor')
|
$docCommentExtractor = $this->getMockBuilder('Nelmio\ApiDocBundle\Util\DocCommentExtractor')
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
->getMock();
|
->getMock();
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Nelmio\ApiDocBundle\Tests;
|
namespace Nelmio\ApiDocBundle\Tests;
|
||||||
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase as BaseWebTestCase;
|
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase as BaseWebTestCase;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
use Symfony\Component\HttpKernel\Kernel;
|
use Symfony\Component\HttpKernel\Kernel;
|
||||||
|
|
||||||
abstract class WebTestCase extends BaseWebTestCase
|
abstract class WebTestCase extends BaseWebTestCase
|
||||||
@ -36,6 +37,10 @@ abstract class WebTestCase extends BaseWebTestCase
|
|||||||
return \PHPUnit_Util_ErrorHandler::handleError($errorNumber, $message, $file, $line);
|
return \PHPUnit_Util_ErrorHandler::handleError($errorNumber, $message, $file, $line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $options
|
||||||
|
* @return ContainerInterface
|
||||||
|
*/
|
||||||
protected function getContainer(array $options = array())
|
protected function getContainer(array $options = array())
|
||||||
{
|
{
|
||||||
if (!static::$kernel) {
|
if (!static::$kernel) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user