Skip to content

Commit

Permalink
Merge pull request biig-io#55 from Nek-/feat/change-the-way-to-config…
Browse files Browse the repository at this point in the history
…ure-the-documentation-controller
  • Loading branch information
Nek- authored Dec 11, 2021
2 parents 5f1b396 + b981856 commit 7bd99e8
Show file tree
Hide file tree
Showing 14 changed files with 88 additions and 19 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.8.0] 2020-11-26
## [0.9.0] 2021-12-10
### Added
- Compatibility with PHP 8.1

### Changed
- Fix #54 to be able to build a melodiia application on any PAAS service

## [0.8.0] 2021-11-26
### Added
- Add json-api header in responses

Expand Down
4 changes: 4 additions & 0 deletions UPGRADE-0.9.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Upgrade guide 0.8...0.9
=======================

Use the new configuration key `openapi_path` instead of `documentation_file_path` to configure your documentation routing.
1 change: 1 addition & 0 deletions docs/config-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ melodiia:
# Define as much APIs you want here.
main:
base_path: /api/v1
openapi_path: /path/to/your/openapi/doc.yaml
pagination:
# Using this query attribute you can change the max per page
max_per_page_attribute: max_per_page
Expand Down
18 changes: 15 additions & 3 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,23 @@ to configure the OpenAPI documentation in a good way was a serious pain and was
But it comes with some help to build your documentation:
1. Run `bin/console assets:insall`
2. Create a file `documentation.yml` (the `config` folder seems like a good location)
2. Add the following routing to your configuration
3. Add your documentation file in the global melodiia configuration and configure your documentation route

```yaml
# The documentation should be available only in dev environment
# routing_dev.yaml
# /config/packages/melodiia.yaml
melodiia:
apis:
main:
# Required all the time! Do not forget this!
base_path: /api/v1
# This is what we are looking for here:
openapi_path: /path/to/your/openapi/doc.yaml
```

```yaml
# The documentation should be available only in dev environment in some cases
# /config/routing_dev.yaml
documentation:
path: /documentation
controller: 'melodiia.documentation'
Expand Down
2 changes: 2 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace SwagIndustries\Melodiia\DependencyInjection;

use SwagIndustries\Melodiia\MelodiiaConfiguration;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

Expand All @@ -28,6 +29,7 @@ public function getConfigTreeBuilder()
->arrayPrototype()
->children()
->scalarNode('base_path')->defaultValue('/')->end()
->scalarNode(MelodiiaConfiguration::CONFIGURATION_OPENAPI_PATH)->defaultNull()->end()
->arrayNode('pagination')
->addDefaultsIfNotSet()
->children()
Expand Down
15 changes: 12 additions & 3 deletions src/DependencyInjection/MelodiiaExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

use Doctrine\Persistence\AbstractManagerRegistry;
use SwagIndustries\Melodiia\Crud\FilterInterface;
use SwagIndustries\Melodiia\Exception\DependencyMissingException;
use SwagIndustries\Melodiia\MelodiiaConfiguration;
use SwagIndustries\Melodiia\Serialization\Context\ContextBuilderInterface;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
Expand All @@ -28,6 +30,9 @@ public function load(array $configs, ContainerBuilder $container)
$xmlLoader = new XmlFileLoader($container, $configFileLocator);
$xmlLoader->load('error-management.xml');

$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);

if (class_exists(AbstractManagerRegistry::class)) {
$loader->load('doctrine.yaml');
}
Expand All @@ -41,11 +46,15 @@ public function load(array $configs, ContainerBuilder $container)

if (class_exists(Environment::class)) {
$loader->load('twig.yaml');
} elseif ('dev' === $container->getParameter('kernel.environment')) {
// This is just a helpful layer in case some dependency is missing, because twig is optional.
foreach ($config['api'] as $endpoint) {
if (!empty($endpoint[MelodiiaConfiguration::CONFIGURATION_OPENAPI_PATH])) {
throw new DependencyMissingException('You specified a documentation path but twig is not installed. Melodiia will not be able to render your documentation.');
}
}
}

$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);

$container->setParameter('melodiia.config', $config);

// Autoconf
Expand Down
20 changes: 18 additions & 2 deletions src/Documentation/Controller/SwaggerUiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

use SwagIndustries\Melodiia\Exception\MelodiiaLogicException;
use SwagIndustries\Melodiia\Exception\MelodiiaRuntimeException;
use SwagIndustries\Melodiia\MelodiiaConfiguration;
use SwagIndustries\Melodiia\MelodiiaConfigurationInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Yaml\Exception\ParseException;
Expand All @@ -14,21 +16,35 @@

class SwaggerUiController
{
/** @deprecated use melodiia configuration instead */
public const PATH_TO_OPEN_API_FILE_OPTION = 'documentation_file_path';

/**
* @var Environment
*/
private $templating;

public function __construct(Environment $templating)
/** @var MelodiiaConfigurationInterface */
private $configuration;

public function __construct(Environment $templating, MelodiiaConfigurationInterface $configuration)
{
$this->templating = $templating;
$this->configuration = $configuration;
}

public function __invoke(Request $request)
{
$response = new Response();
$path = $request->attributes->get(self::PATH_TO_OPEN_API_FILE_OPTION, null);

$path = $this->configuration->getApiConfigFor($request)[MelodiiaConfiguration::CONFIGURATION_OPENAPI_PATH] ?? null;

if (null === $path) {
$path = $request->attributes->get(self::PATH_TO_OPEN_API_FILE_OPTION, null);
if (null !== $path) {
@trigger_error('Using a route attribute to define the documentation path is deprecated since Melodiia 0.9.0 and will be removed in 1.0.0.', \E_USER_DEPRECATED);
}
}

if (null === $path) {
throw new MelodiiaLogicException(sprintf('The option %s is missing on the documentation route', self::PATH_TO_OPEN_API_FILE_OPTION));
Expand Down
9 changes: 9 additions & 0 deletions src/Exception/DependencyMissingException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace SwagIndustries\Melodiia\Exception;

class DependencyMissingException extends MelodiiaLogicException
{
}
1 change: 1 addition & 0 deletions src/MelodiiaConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
final class MelodiiaConfiguration implements MelodiiaConfigurationInterface
{
public const PREFIX_CONTROLLER = 'melodiia.crud.controller';
public const CONFIGURATION_OPENAPI_PATH = 'openapi_path';

/**
* @var array
Expand Down
2 changes: 1 addition & 1 deletion src/MelodiiaConfigurationInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use Symfony\Component\HttpFoundation\Request;

/**
* @internal inheritance
* @internal for testing purpose, you should implement this interface
*/
interface MelodiiaConfigurationInterface
{
Expand Down
1 change: 1 addition & 0 deletions src/Resources/config/twig.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ services:
tags: ['controller.service_arguments']
arguments:
$templating: '@twig'
$configuration: '@melodiia.configuration'
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy;
use SwagIndustries\Melodiia\Documentation\Controller\SwaggerUiController;
use SwagIndustries\Melodiia\MelodiiaConfiguration;
use SwagIndustries\Melodiia\MelodiiaConfigurationInterface;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
Expand All @@ -28,13 +30,19 @@ public function setUp(): void

public function testItGeneratesAResponseUsingTemplate()
{
$attributes = new ParameterBag();
$attributes->set(SwaggerUiController::PATH_TO_OPEN_API_FILE_OPTION, __DIR__ . '/../../../fixtures/doc.yaml');
$this->templating->render(Argument::type('string'), ['json' => '{"openapi":"3.0.1"}'])->shouldBeCalled();
$request = $this->prophesize(Request::class);
$request->attributes = $attributes;
$this->controller = new SwaggerUiController($this->templating->reveal());
$request->attributes = new ParameterBag();
$request = $request->reveal();
/** @var MelodiiaConfigurationInterface|ObjectProphecy $config */
$config = $this->prophesize(MelodiiaConfigurationInterface::class);
$config->getApiConfigFor($request)->willReturn([
MelodiiaConfiguration::CONFIGURATION_OPENAPI_PATH => __DIR__ . '/../../../fixtures/doc.yaml',
]);

$this->templating->render(Argument::type('string'), ['json' => '{"openapi":"3.0.1"}'])->shouldBeCalled();

$this->controller = new SwaggerUiController($this->templating->reveal(), $config->reveal());

$this->assertInstanceOf(Response::class, $this->controller->__invoke($request->reveal()));
$this->assertInstanceOf(Response::class, $this->controller->__invoke($request));
}
}
3 changes: 2 additions & 1 deletion tests/TestApplication/config/melodiia.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
melodiia:
apis:
main: ~
main:
openapi_path: '%kernel.project_dir%/config/documentation.yaml'
2 changes: 0 additions & 2 deletions tests/TestApplication/config/routing_dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,3 @@
documentation:
path: /documentation
controller: 'melodiia.documentation'
defaults:
documentation_file_path: '%kernel.project_dir%/config/documentation.yaml'

0 comments on commit 7bd99e8

Please sign in to comment.