Use request base url

This commit is contained in:
Guilhem Niot 2017-07-05 15:41:53 +02:00
parent 7690f6cfb5
commit 0b05a23625
5 changed files with 52 additions and 22 deletions

View File

@ -13,6 +13,7 @@ namespace Nelmio\ApiDocBundle\Controller;
use Nelmio\ApiDocBundle\ApiDocGenerator; use Nelmio\ApiDocBundle\ApiDocGenerator;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
final class DocumentationController final class DocumentationController
{ {
@ -23,8 +24,13 @@ final class DocumentationController
$this->apiDocGenerator = $apiDocGenerator; $this->apiDocGenerator = $apiDocGenerator;
} }
public function __invoke() public function __invoke(Request $request)
{ {
return new JsonResponse($this->apiDocGenerator->generate()->toArray()); $spec = $this->apiDocGenerator->generate()->toArray();
if ('' !== $request->getBaseUrl()) {
$spec['basePath'] = $request->getBaseUrl();
}
return new JsonResponse($spec);
} }
} }

View File

@ -12,6 +12,7 @@
namespace Nelmio\ApiDocBundle\Controller; namespace Nelmio\ApiDocBundle\Controller;
use Nelmio\ApiDocBundle\ApiDocGenerator; use Nelmio\ApiDocBundle\ApiDocGenerator;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
final class SwaggerUiController final class SwaggerUiController
@ -25,10 +26,15 @@ final class SwaggerUiController
$this->twig = $twig; $this->twig = $twig;
} }
public function __invoke() public function __invoke(Request $request)
{ {
$spec = $this->apiDocGenerator->generate()->toArray();
if ('' !== $request->getBaseUrl()) {
$spec['basePath'] = $request->getBaseUrl();
}
return new Response( return new Response(
$this->twig->render('@NelmioApiDoc/SwaggerUi/index.html.twig', ['swagger_data' => ['spec' => $this->apiDocGenerator->generate()->toArray()]]), $this->twig->render('@NelmioApiDoc/SwaggerUi/index.html.twig', ['swagger_data' => ['spec' => $spec]]),
Response::HTTP_OK, Response::HTTP_OK,
['Content-Type' => 'text/html'] ['Content-Type' => 'text/html']
); );

View File

@ -13,25 +13,32 @@ namespace Nelmio\ApiDocBundle\Describer;
use ApiPlatform\Core\Documentation\Documentation; use ApiPlatform\Core\Documentation\Documentation;
use ApiPlatform\Core\Swagger\Serializer\DocumentationNormalizer; use ApiPlatform\Core\Swagger\Serializer\DocumentationNormalizer;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RequestContext;
final class ApiPlatformDescriber extends ExternalDocDescriber final class ApiPlatformDescriber extends ExternalDocDescriber
{ {
public function __construct(Documentation $documentation, DocumentationNormalizer $normalizer, bool $overwrite = false) public function __construct(Documentation $documentation, DocumentationNormalizer $normalizer, UrlGeneratorInterface $urlGenerator)
{ {
parent::__construct(function () use ($documentation, $normalizer) { parent::__construct(function () use ($documentation, $normalizer, $urlGenerator) {
$documentation = (array) $normalizer->normalize($documentation); $baseContext = $urlGenerator->getContext();
// Remove base path $urlGenerator->setContext(new RequestContext());
if (isset($documentation['basePath'])) { try {
$paths = []; $basePath = $urlGenerator->generate('api_entrypoint');
foreach ($documentation['paths'] as $path => $value) { } finally {
$paths['/'.ltrim($documentation['basePath'].'/'.ltrim($path, '/'), '/')] = $value; $urlGenerator->setContext($baseContext);
} }
$documentation = (array) $normalizer->normalize($documentation);
unset($documentation['basePath']); unset($documentation['basePath']);
$documentation['paths'] = $paths;
foreach ($documentation['paths'] as $path => $value) {
$paths['/'.ltrim($basePath.'/'.ltrim($path, '/'), '/')] = $value;
} }
$documentation['paths'] = $paths;
return $documentation; return $documentation;
}, $overwrite); });
} }
} }

View File

@ -7,6 +7,7 @@
<service id="nelmio_api_doc.describers.api_platform" class="Nelmio\ApiDocBundle\Describer\ApiPlatformDescriber" public="false"> <service id="nelmio_api_doc.describers.api_platform" class="Nelmio\ApiDocBundle\Describer\ApiPlatformDescriber" public="false">
<argument type="service" id="nelmio_api_doc.describers.api_platform.documentation" /> <argument type="service" id="nelmio_api_doc.describers.api_platform.documentation" />
<argument type="service" id="api_platform.swagger.normalizer.documentation" /> <argument type="service" id="api_platform.swagger.normalizer.documentation" />
<argument type="service" id="router" />
<tag name="nelmio_api_doc.describer" priority="-100" /> <tag name="nelmio_api_doc.describer" priority="-100" />
</service> </service>

View File

@ -13,28 +13,38 @@ namespace Nelmio\ApiDocBundle\Tests\Functional;
class SwaggerUiTest extends WebTestCase class SwaggerUiTest extends WebTestCase
{ {
protected static function createClient(array $options = [], array $server = [])
{
return parent::createClient([], ['PHP_SELF' => '/app_dev.php/docs', 'SCRIPT_FILENAME' => '/var/www/app/web/app_dev.php']);
}
public function testSwaggerUi() public function testSwaggerUi()
{ {
$client = self::createClient(); $client = self::createClient();
$crawler = $client->request('GET', '/docs/'); $crawler = $client->request('GET', '/app_dev.php/docs/');
$response = $client->getResponse(); $response = $client->getResponse();
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$this->assertEquals('text/html; charset=UTF-8', $response->headers->get('Content-Type')); $this->assertEquals('text/html; charset=UTF-8', $response->headers->get('Content-Type'));
$swaggerUiSpec = json_decode($crawler->filterXPath('//script[@id="swagger-data"]')->text(), true); $expected = $this->getSwaggerDefinition()->toArray();
$this->assertEquals($this->getSwaggerDefinition()->toArray(), $swaggerUiSpec['spec']); $expected['basePath'] = '/app_dev.php';
$this->assertEquals($expected, json_decode($crawler->filterXPath('//script[@id="swagger-data"]')->text(), true)['spec']);
} }
public function testJsonDocs() public function testJsonDocs()
{ {
$client = self::createClient(); $client = self::createClient();
$crawler = $client->request('GET', '/docs.json'); $crawler = $client->request('GET', '/app_dev.php/docs.json');
$response = $client->getResponse(); $response = $client->getResponse();
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$this->assertEquals('application/json', $response->headers->get('Content-Type')); $this->assertEquals('application/json', $response->headers->get('Content-Type'));
$this->assertEquals($this->getSwaggerDefinition()->toArray(), json_decode($response->getContent(), true)); $expected = $this->getSwaggerDefinition()->toArray();
$expected['basePath'] = '/app_dev.php';
$this->assertEquals($expected, json_decode($response->getContent(), true));
} }
} }