Doc generation for the specific API version

This commit is contained in:
Ilyas Salikhov 2014-10-22 14:38:40 +04:00
parent 4beb08e587
commit 84a4b0200f
11 changed files with 115 additions and 9 deletions

View File

@ -34,6 +34,7 @@ class DumpCommand extends ContainerAwareCommand
$this->availableFormats[0]
)
->addOption('no-sandbox', '', InputOption::VALUE_NONE)
->addOption('api-version', null, InputOption::VALUE_REQUIRED, 'The API version')
->setName('api:doc:dump')
;
}
@ -62,7 +63,11 @@ class DumpCommand extends ContainerAwareCommand
$this->getContainer()->set('request', new Request(), 'request');
}
$extractedDoc = $this->getContainer()->get('nelmio_api_doc.extractor.api_doc_extractor')->all();
$extractor = $this->getContainer()->get('nelmio_api_doc.extractor.api_doc_extractor')
$extractedDoc = $input->hasOption('api-version') ?
$extractor->allForVersion($input->getOption('api-version')) :
$extractor->all();
$formattedDoc = $formatter->format($extractedDoc);
if ('json' === $format) {

View File

@ -19,9 +19,12 @@ use Symfony\Component\HttpFoundation\Response;
class ApiDocController extends Controller
{
public function indexAction()
public function indexAction(Request $request)
{
$extractedDoc = $this->get('nelmio_api_doc.extractor.api_doc_extractor')->all();
$extractor = $this->get('nelmio_api_doc.extractor.api_doc_extractor');
$apiVersion = $request->query->get('_version', null);
$extractedDoc = $apiVersion ? $extractor->allForVersion($apiVersion) : $extractor->all();
$htmlContent = $this->get('nelmio_api_doc.formatter.html_formatter')->format($extractedDoc);
return new Response($htmlContent, 200, array('Content-Type' => 'text/html'));

View File

@ -88,6 +88,30 @@ class ApiDocExtractor
return $this->extractAnnotations($this->getRoutes());
}
/**
* Extracts annotations from routes for specific version
*
* @param string $apiVersion API version
*
* @return array
*/
public function allForVersion($apiVersion)
{
$data = $this->all();
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:
* - annotation

View File

@ -65,11 +65,11 @@ class CachingApiDocExtractor extends ApiDocExtractor
$data = parent::all();
$this->cache->write(serialize($data), $resources);
return $data;
}
return unserialize(file_get_contents($this->cacheFile));
}
}
}

View File

@ -384,6 +384,28 @@ It is a good idea to enable the internal caching mechanism on production:
cache:
enabled: true
### Route versions
You can define version for the API routes:
```yml
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:
php app/console api:doc:dump --format=html --api-version=3.0 > api.html
Or by adding `?_version={version}` to API documentation page URL.
Configuration In-Depth
----------------------

View File

@ -27,7 +27,6 @@ class ApiDocControllerTest extends WebTestCase
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals('application/json', $response->headers->get('Content-type'));
}
public function dataTestApiDeclarations()

View File

@ -17,7 +17,7 @@ use Nelmio\ApiDocBundle\Tests\WebTestCase;
class ApiDocExtractorTest extends WebTestCase
{
const ROUTES_QUANTITY = 33;
const ROUTES_QUANTITY = 34;
public function testAll()
{
@ -78,7 +78,21 @@ class ApiDocExtractorTest extends WebTestCase
$a3 = $data[20]['annotation'];
$this->assertTrue($a3->getHttps());
}
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, $data);
$data = $extractor->allForVersion('1.4');
$this->assertTrue(is_array($data));
$this->assertCount(self::ROUTES_QUANTITY - 1, $data);
}
public function testGet()

View File

@ -78,6 +78,13 @@ class TestController
{
}
/**
* @ApiDoc()
*/
public function routeVersionAction()
{
}
/**
* @ApiDoc(description="Action without HTTP verb")
*/

View File

@ -226,11 +226,16 @@ test_required_parameters:
requirements:
_method: POST
_format: json|xml|html
test_put_disables_required_parameters:
pattern: /api/other-resources/{id}.{_format}
defaults: { _controller: NelmioApiDocTestBundle:Resource:requiredParametersAction, _format: json }
requirements:
_method: PUT
_format: json|xml|html
_format: json|xml|html
test_route_version_checking:
pattern: /zz-tests-route-version.{_format}
defaults: { _controller: NelmioApiDocTestBundle:Test:routeVersion, _format: json, _version: "1.5" }
requirements:
_method: GET

View File

@ -948,6 +948,15 @@ related[b]:
### `POST` /zsecured ###
### `GET` /zz-tests-route-version.{_format} ###
#### Requirements ####
**_format**
MARKDOWN;
$this->assertEquals($expected, $result);

View File

@ -1256,6 +1256,24 @@ With multiple lines.',
'https' => false,
'authenticationRoles' => array(),
'deprecated' => false
),
21 =>
array(
'authentication' => false,
'method' => 'GET',
'uri' => '/zz-tests-route-version.{_format}',
'https' => false,
'authenticationRoles' => array(),
'deprecated' => false,
'requirements' =>
array(
'_format' =>
array(
'requirement' => '',
'dataType' => '',
'description' => '',
),
),
)
),
'/tests2' =>