Skip to content

Commit

Permalink
Merge pull request #29 from cnizzardini/branch/v1.1.0
Browse files Browse the repository at this point in the history
Branch/v1.1.0
  • Loading branch information
cnizzardini authored May 18, 2020
2 parents 0c7fdc8 + c1141ec commit f2ee3a1
Show file tree
Hide file tree
Showing 84 changed files with 3,182 additions and 1,719 deletions.
53 changes: 32 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,40 +23,50 @@ SwaggerBake requires CakePHP4 and a few dependencies that will be automatically
composer require cnizzardini/cakephp-swagger-bake
```

Add the plugin to `Application.php`:
Run `bin/cake plugin load SwaggerBake` or manually load the plugin:

```php
$this->addPlugin('SwaggerBake');
# src/Application.php
public function bootstrap(): void
{
// other logic...
$this->addPlugin('SwaggerBake');
}
```

## Basic Usage
## Setup

Get going in just four easy steps:
For standard applications that have not split their API into plugins, the automated setup should work. Otherwise
use the manual setup.

- Create a base swagger.yml file in `config\swagger.yml`. An example file is provided [here](assets/swagger.yml).
### Automated Setup

- Create a `config/swagger_bake.php` file. See the example file [here](assets/swagger_bake.php) for further
explanation.
Run `bin/cake swagger install`

- Create a route for the SwaggerUI page in `config/routes.php`. See Extensibility for other ways to diplay Swagger.
Create a route for the SwaggerUI page in `config/routes.php`, example:

```php
$builder->connect('/api', ['controller' => 'Swagger', 'action' => 'index', 'plugin' => 'SwaggerBake']);
$builder->connect('/your-api-path', ['controller' => 'Swagger', 'action' => 'index', 'plugin' => 'SwaggerBake']);
```

- Use the `swagger bake` command to generate your swagger documentation.
### Manual Setup

```sh
bin/cake swagger bake
```
- Create a base swagger.yml file in `config\swagger.yml`. An example file is provided [here](assets/swagger.yml).

Using the above example you should now see your swagger documentation after browsing to http://your-project/api
- Create a `config/swagger_bake.php` file. See the example file [here](assets/swagger_bake.php) for further
explanation.

### Hot Reload Swagger JSON
- Create a route for the SwaggerUI page in `config/routes.php`. See Extensibility for other ways to diplay Swagger.

```php
$builder->connect('/your-api-path', ['controller' => 'Swagger', 'action' => 'index', 'plugin' => 'SwaggerBake']);
```

You can enable hot reloading. This setting re-generates swagger.json on each reload of Swagger UI. Simply set
`hotReload` equal to `true` (using `Configure::read('debug')` is recommended) in your `config/swagger_bake.php` file.
## Complete Setup

If Hot Reload is enabled ([see config](assets/swagger_bake.php)) then you should be able to browse to the above
route. Otherwise you must first run `bin/cake swagger bake` to generate your swagger documentation.

## Automatic Documentation

I built this library to reduce the need for annotations to build documentation. SwaggerBake will automatically
Expand All @@ -80,13 +90,14 @@ components > schemas > Exception as your Swagger documentations Exception schema
## Doc Blocks

SwaggerBake will parse your [DocBlocks](https://docs.phpdoc.org/latest/guides/docblocks.html) for information. The
first line reads as the Path Summary and the second as the Path Description, `@see`, `@deprecated`, and `@throws` are
also supported. Throw tags use the Exception classes HTTP status code. For instance, a `MethodNotAllowedException`
displays as a 405 response in Swagger UI, while a standard PHP Exception displays as a 500 code.
first line reads as the Operation Summary and the second as the Operation Description, `@see`, `@deprecated`, and
`@throws` are also supported. Throw tags use the Exception classes HTTP status code. For instance, a
`MethodNotAllowedException` displays as a 405 response in Swagger UI, while a standard PHP Exception displays as a 500
code.

```php
/**
* Swagger Path Summary
* Swagger Operation Summary
*
* This displays as the operations long description
*
Expand Down
2 changes: 1 addition & 1 deletion assets/swagger_bake.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
*/
return [
'SwaggerBake' => [
'prefix' => '/api',
'prefix' => '/your-relative-api-url',
'yml' => '/config/swagger.yml',
'json' => '/webroot/swagger.json',
'webPath' => '/swagger.json',
Expand Down
8 changes: 8 additions & 0 deletions src/Command/BakeCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
use SwaggerBake\Lib\Configuration;
use SwaggerBake\Lib\Factory\SwaggerFactory;

/**
* Class BakeCommand
* @package SwaggerBake\Command
*/
class BakeCommand extends Command
{
/**
Expand All @@ -26,6 +30,10 @@ public function execute(Arguments $args, ConsoleIo $io)
$output = $config->getJson();

$swagger = (new SwaggerFactory())->create();
foreach ($swagger->getOperationsWithNoHttp20x() as $operation) {
triggerWarning('Operation ' . $operation->getOperationId() . ' does not have a HTTP 20x response');
}

$swagger->writeFile($output);

$io->out("<success>Swagger File Created: $output</success>");
Expand Down
78 changes: 78 additions & 0 deletions src/Command/InstallCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php
declare(strict_types=1);

namespace SwaggerBake\Command;

use Cake\Console\Arguments;
use Cake\Console\Command;
use Cake\Console\ConsoleIo;

/**
* Class InstallCommand
* @package SwaggerBake\Command
*/
class InstallCommand extends Command
{
/**
* Writes a swagger.json file
*
* @param Arguments $args
* @param ConsoleIo $io
* @return int|void|null
*/
public function execute(Arguments $args, ConsoleIo $io)
{
$io->hr();
$io->out("| SwaggerBake Install");
$io->hr();

$io->info('This will create, but not overwrite config/swagger.yml and config/swagger_bake.php');

$io->out(
'If your API exists in a plugin or you have some other non-standard setup, please follow ' .
'the manual installation steps.'
);

if (strtoupper($io->ask('Continue?', 'Y')) !== 'Y') {
return;
}

$assets = __DIR__ . DS . '..' . DS . '..' . DS . 'assets';
if (!dir($assets)) {
$io->error('Unable to locate assets directory, please install manually');
return;
}

if (file_exists(CONFIG . 'swagger.yml') || file_exists(CONFIG . 'swagger_bake.php')) {
$answer = $io->ask('The installer found existing SwaggerBake config files. Overwrite?', 'Y');
if (strtoupper($answer) !== 'Y') {
return;
}
}

if (!copy("$assets/swagger.yml", CONFIG . 'swagger.yml')) {
$io->error('Unable to copy swagger.yml, check permissions');
return;
}

if (!copy("$assets/swagger_bake.php", CONFIG . 'swagger_bake.php')) {
$io->error('Unable to copy swagger_bake.php, check permissions');
return;
}

$path = $io->ask('What is your relative API path (e.g. /api)');
if (!empty($path)) {
$contents = file_get_contents(CONFIG . 'swagger.yml');
$contents = str_replace('YOUR-SERVER-HERE', $path, $contents);
file_put_contents(CONFIG . 'swagger.yml', $contents);

$contents = file_get_contents(CONFIG . 'swagger_bake.php');
$contents = str_replace('/your-relative-api-url', $path, $contents);
file_put_contents(CONFIG . 'swagger_bake.php', $contents);
}

$io->success('Installation Complete!');

$io->out('Now just add a route in your config/routes.php for SwaggerUI and you\'re ready to go!');
}
}
4 changes: 4 additions & 0 deletions src/Command/ModelCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
use SwaggerBake\Lib\Utility\DataTypeConversion;
use SwaggerBake\Lib\Utility\ValidateConfiguration;

/**
* Class ModelCommand
* @package SwaggerBake\Command
*/
class ModelCommand extends Command
{
/**
Expand Down
4 changes: 4 additions & 0 deletions src/Command/RouteCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
use SwaggerBake\Lib\Configuration;
use SwaggerBake\Lib\Utility\ValidateConfiguration;

/**
* Class RouteCommand
* @package SwaggerBake\Command
*/
class RouteCommand extends Command
{
/**
Expand Down
5 changes: 5 additions & 0 deletions src/Controller/AppController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,9 @@

class AppController extends BaseController
{
public function initialize(): void
{
parent::initialize();
$this->loadComponent('Flash');
}
}
16 changes: 14 additions & 2 deletions src/Controller/SwaggerController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@
use Cake\Event\EventInterface;
use SwaggerBake\Lib\Configuration;
use SwaggerBake\Lib\Factory\SwaggerFactory;
use SwaggerBake\Lib\Swagger;

class SwaggerController extends AppController
{
/** @var Swagger */
private $swagger;

/**
* @see https://book.cakephp.org/4/en/controllers.html#controller-callback-methods
* @param EventInterface $event
Expand All @@ -20,8 +24,8 @@ public function beforeFilter(EventInterface $event)

if ($config->getHotReload()) {
$output = $config->getJson();
$swagger = (new SwaggerFactory())->create();
$swagger->writeFile($output);
$this->swagger = (new SwaggerFactory())->create();
$this->swagger->writeFile($output);
}
}

Expand All @@ -32,6 +36,14 @@ public function beforeFilter(EventInterface $event)
*/
public function index()
{
foreach ($this->swagger->getOperationsWithNoHttp20x() as $operation) {
if (!isset($this->Flash)) {
triggerWarning('Operation ' . $operation->getOperationId() . ' does not have a HTTP 20x response');
continue;
}
$this->Flash->error('Operation ' . $operation->getOperationId() . ' does not have a HTTP 20x response');
}

$config = new Configuration();
$title = $config->getTitleFromYml();
$url = $config->getWebPath();
Expand Down
64 changes: 0 additions & 64 deletions src/Lib/AbstractParameter.php

This file was deleted.

24 changes: 0 additions & 24 deletions src/Lib/Annotation/SwagEntityAttributeHandler.php

This file was deleted.

22 changes: 0 additions & 22 deletions src/Lib/Annotation/SwagFormHandler.php

This file was deleted.

Loading

0 comments on commit f2ee3a1

Please sign in to comment.