Skip to content

Commit f16dbe0

Browse files
authored
Merge pull request #384 from shalvah/v3
Update docs and prepare for release
2 parents 92226ed + b7aedfd commit f16dbe0

File tree

9 files changed

+70
-27
lines changed

9 files changed

+70
-27
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616

1717
## [3.0] - unreleased
1818
### Added
19+
- Official Lumen support (https://github.com/mpociot/laravel-apidoc-generator/pull/382)
20+
- `@queryParam` annotation (https://github.com/mpociot/laravel-apidoc-generator/pull/383)
1921
- `@bodyParam` annotation (https://github.com/mpociot/laravel-apidoc-generator/pull/362, https://github.com/mpociot/laravel-apidoc-generator/pull/366)
2022
- `@authenticated` annotation (https://github.com/mpociot/laravel-apidoc-generator/pull/369)
2123
- Ability to override the controller `@group` from the method. (https://github.com/mpociot/laravel-apidoc-generator/pull/372)

README.md

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,31 @@ Automatically generate your API documentation from your existing Laravel/Lumen/[
1414
> Note: this is the documentation for version 3, which changes significantly from version 2. if you're on v2, you can check out its documentation [here](https://github.com/mpociot/laravel-apidoc-generator/blob/2.x/README.md). We strongly recommend you upgrade, though, as v3 is more robust and fixes a lot of the problems with v2.
1515
1616
## Installation
17-
> Note: version 3.x requires PHP 7 and Laravel 5.5 or higher.
17+
> Note: PHP 7 and Laravel 5.5 or higher are required.
1818
1919
```sh
2020
$ composer require mpociot/laravel-apidoc-generator:dev-master
2121
```
2222

23-
Then publish the config file by running:
23+
### Laravel
24+
Publish the config file by running:
2425

2526
```bash
2627
php artisan vendor:publish --provider=Mpociot\ApiDoc\ApiDocGeneratorServiceProvider --tag=config
2728
```
2829
This will create an `apidoc.php` file in your `config` folder.
2930

31+
### Lumen
32+
- Register the service provider in your `bootstrap/app.php`:
33+
```php
34+
$app->register(\Mpociot\ApiDoc\ApiDocGeneratorServiceProvider::class);
35+
```
36+
- Copy the config file from `vendor/mpociot/laravel-apidoc-generator/config/apidoc.php` to your project as `config/apidoc.php`. Then add to your `bootstrap/app.php`:
37+
```php
38+
$app->configure('apidoc');
39+
```
40+
41+
3042
## Usage
3143
Before you can generate your documentation, you'll need to configure a few things in your `config/apidoc.php`.
3244
- `output`
@@ -38,6 +50,9 @@ Set this option to true if you want a Postman collection to be generated along w
3850
- `router`
3951
The router to use when processing the route (can be Laravel or Dingo. Defaults to **Laravel**)
4052

53+
- `logo`
54+
You can specify your custom logo to be used on the generated documentation. Set the `logo` option to an absolute path pointing to your logo file.
55+
4156
- `routes`
4257
This is where you specify what rules documentation should be generated for. You specify routes to be parsed by defining conditions that the routes should meet and rules that should be applied when generating documentation. These conditions and rules are specified in groups, allowing you to apply different rules to different routes.
4358

@@ -174,7 +189,7 @@ class UserController extends Controller
174189

175190
To specify a list of valid parameters your API route accepts, use the `@bodyParam` and `@queryParam` annotations.
176191
- The `@bodyParam` annotation takes the name of the parameter, its type, an optional "required" label, and then its description.
177-
- The `@queryParam` annotation (coming soon!) takes the name of the parameter, an optional "required" label, and then its description
192+
- The `@queryParam` annotation takes the name of the parameter, an optional "required" label, and then its description
178193

179194

180195
```php
@@ -189,6 +204,16 @@ public function createPost()
189204
{
190205
// ...
191206
}
207+
208+
/**
209+
* @queryParam sort Field to sort by
210+
* @queryParam page The page number to return
211+
* @queryParam fields required The fields to include
212+
*/
213+
public function listPosts()
214+
{
215+
// ...
216+
}
192217
```
193218

194219
They will be included in the generated documentation text and example requests.
@@ -274,7 +299,7 @@ If you don't specify an example response using any of the above means, this pack
274299
- By default, response calls are only made for GET routes, but you can configure this. Set the `methods` key to an array of methods or '*' to mean all methods. Leave it as an empty array to turn off response calls for that route group.
275300
- Parameters in URLs (example: `/users/{user}`, `/orders/{id?}`) will be replaced with '1' by default. You can configure this, however.Put the parameter names (including curly braces and question marks) as the keys and their replacements as the values in the `bindings` key.
276301
- You can configure environment variables (this is useful so you can prevent external services like notifications from being triggered). By default the APP_ENV is set to 'documentation'. You can add more variables in the `env` key.
277-
- You can also configure what headers, query parameters and body parameters should be sent when making the request (the `headers`, `query`, and `body` keys respectively).
302+
- By default, the package will generate dummy values for your documented body and query parameters and send in the request. You can configure what headers and additional query and parameters should be sent when making the request (the `headers`, `query`, and `body` keys respectively).
278303

279304

280305
### Postman collections

src/Commands/GenerateDocumentation.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
use Illuminate\Console\Command;
88
use Mpociot\Reflection\DocBlock;
99
use Illuminate\Support\Collection;
10+
use Mpociot\ApiDoc\Tools\Generator;
1011
use Mpociot\ApiDoc\Tools\RouteMatcher;
1112
use Illuminate\Support\Facades\Storage;
12-
use Mpociot\ApiDoc\Generators\Generator;
1313
use Mpociot\Documentarian\Documentarian;
1414
use Mpociot\ApiDoc\Postman\CollectionWriter;
1515

src/Generators/Generator.php renamed to src/Tools/Generator.php

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
<?php
22

3-
namespace Mpociot\ApiDoc\Generators;
3+
namespace Mpociot\ApiDoc\Tools;
44

55
use Faker\Factory;
66
use ReflectionClass;
77
use ReflectionMethod;
88
use Illuminate\Routing\Route;
99
use Mpociot\Reflection\DocBlock;
1010
use Mpociot\Reflection\DocBlock\Tag;
11-
use Mpociot\ApiDoc\Tools\ResponseResolver;
1211

1312
class Generator
1413
{
@@ -47,7 +46,13 @@ public function processRoute(Route $route, array $rulesToApply = [])
4746

4847
$routeGroup = $this->getRouteGroup($controller, $method);
4948
$docBlock = $this->parseDocBlock($method);
50-
$content = ResponseResolver::getResponse($route, $docBlock['tags'], $rulesToApply);
49+
$bodyParameters = $this->getBodyParametersFromDocBlock($docBlock['tags']);
50+
$queryParameters = $this->getQueryParametersFromDocBlock($docBlock['tags']);
51+
$content = ResponseResolver::getResponse($route, $docBlock['tags'], [
52+
'rules' => $rulesToApply,
53+
'body' => $bodyParameters,
54+
'query' => $queryParameters,
55+
]);
5156

5257
$parsedRoute = [
5358
'id' => md5($this->getUri($route).':'.implode($this->getMethods($route))),
@@ -56,8 +61,8 @@ public function processRoute(Route $route, array $rulesToApply = [])
5661
'description' => $docBlock['long'],
5762
'methods' => $this->getMethods($route),
5863
'uri' => $this->getUri($route),
59-
'bodyParameters' => $this->getBodyParametersFromDocBlock($docBlock['tags']),
60-
'queryParameters' => $this->getQueryParametersFromDocBlock($docBlock['tags']),
64+
'bodyParameters' => $bodyParameters,
65+
'queryParameters' => $queryParameters,
6166
'authenticated' => $this->getAuthStatusFromDocBlock($docBlock['tags']),
6267
'response' => $content,
6368
'showresponse' => ! empty($content),
@@ -132,7 +137,13 @@ protected function getQueryParametersFromDocBlock(array $tags)
132137
$required = trim($required) == 'required' ? true : false;
133138
}
134139

135-
return [$name => compact('description', 'required')];
140+
if (str_contains($description, ['number', 'count', 'page'])) {
141+
$value = $this->generateDummyValue('integer');
142+
} else {
143+
$value = $this->generateDummyValue('string');
144+
}
145+
146+
return [$name => compact('description', 'required', 'value')];
136147
})->toArray();
137148

138149
return $parameters;

src/Tools/ResponseResolver.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,21 @@ public function __construct(Route $route)
2525
$this->route = $route;
2626
}
2727

28-
private function resolve(array $tags, array $rulesToApply)
28+
private function resolve(array $tags, array $routeProps)
2929
{
3030
$response = null;
3131
foreach (static::$strategies as $strategy) {
3232
$strategy = new $strategy();
33-
$response = $strategy($this->route, $tags, $rulesToApply);
33+
$response = $strategy($this->route, $tags, $routeProps);
3434
if (! is_null($response)) {
3535
return $this->getResponseContent($response);
3636
}
3737
}
3838
}
3939

40-
public static function getResponse($route, $tags, $rulesToApply)
40+
public static function getResponse($route, $tags, $routeProps)
4141
{
42-
return (new static($route))->resolve($tags, $rulesToApply);
42+
return (new static($route))->resolve($tags, $routeProps);
4343
}
4444

4545
/**

src/Tools/ResponseStrategies/ResponseCallStrategy.php

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@
1212
*/
1313
class ResponseCallStrategy
1414
{
15-
public function __invoke(Route $route, array $tags, array $rulesToApply)
15+
public function __invoke(Route $route, array $tags, array $routeProps)
1616
{
17-
$rulesToApply = $rulesToApply['response_calls'] ?? [];
17+
$rulesToApply = $routeProps['rules']['response_calls'] ?? [];
1818
if (! $this->shouldMakeApiCall($route, $rulesToApply)) {
1919
return;
2020
}
2121

2222
$this->configureEnvironment($rulesToApply);
23-
$request = $this->prepareRequest($route, $rulesToApply);
23+
$request = $this->prepareRequest($route, $rulesToApply, $routeProps['body'], $routeProps['query']);
2424
try {
2525
$response = $this->makeApiCall($request);
2626
} catch (\Exception $e) {
@@ -38,15 +38,20 @@ private function configureEnvironment(array $rulesToApply)
3838
$this->setEnvironmentVariables($rulesToApply['env'] ?? []);
3939
}
4040

41-
private function prepareRequest(Route $route, array $rulesToApply)
41+
private function prepareRequest(Route $route, array $rulesToApply, array $bodyParams, array $queryParams)
4242
{
4343
$uri = $this->replaceUrlParameterBindings($route, $rulesToApply['bindings'] ?? []);
4444
$routeMethods = $this->getMethods($route);
4545
$method = array_shift($routeMethods);
4646
$request = Request::create($uri, $method, [], [], [], $this->transformHeadersToServerVars($rulesToApply['headers'] ?? []));
4747
$request = $this->addHeaders($request, $route, $rulesToApply['headers'] ?? []);
48-
$request = $this->addQueryParameters($request, $rulesToApply['query'] ?? []);
49-
$request = $this->addBodyParameters($request, $rulesToApply['body'] ?? []);
48+
49+
// Mix in parsed parameters with manually specified parameters.
50+
$queryParams = collect($queryParams)->map->value->merge($rulesToApply['query'] ?? [])->toArray();
51+
$bodyParams = collect($bodyParams)->map->value->merge($rulesToApply['body'] ?? [])->toArray();
52+
53+
$request = $this->addQueryParameters($request, $queryParams);
54+
$request = $this->addBodyParameters($request, $bodyParams);
5055

5156
return $request;
5257
}
@@ -188,7 +193,7 @@ private function makeApiCall(Request $request)
188193
*
189194
* @return \Symfony\Component\HttpFoundation\Response
190195
*/
191-
private function callLaravelRoute($request): \Symfony\Component\HttpFoundation\Response
196+
private function callLaravelRoute(Request $request): \Symfony\Component\HttpFoundation\Response
192197
{
193198
$kernel = app(\Illuminate\Contracts\Http\Kernel::class);
194199
$response = $kernel->handle($request);

src/Tools/ResponseStrategies/ResponseTagStrategy.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*/
1111
class ResponseTagStrategy
1212
{
13-
public function __invoke(Route $route, array $tags, array $rulesToApply)
13+
public function __invoke(Route $route, array $tags, array $routeProps)
1414
{
1515
return $this->getDocBlockResponse($tags);
1616
}

src/Tools/ResponseStrategies/TransformerTagsStrategy.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616
class TransformerTagsStrategy
1717
{
18-
public function __invoke(Route $route, array $tags, array $rulesToApply)
18+
public function __invoke(Route $route, array $tags, array $routeProps)
1919
{
2020
return $this->getTransformerResponse($tags);
2121
}

tests/Unit/GeneratorTestCase.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
namespace Mpociot\ApiDoc\Tests\Unit;
44

55
use Orchestra\Testbench\TestCase;
6-
use Mpociot\ApiDoc\Generators\Generator;
6+
use Mpociot\ApiDoc\Tools\Generator;
77
use Mpociot\ApiDoc\ApiDocGeneratorServiceProvider;
88

99
abstract class GeneratorTestCase extends TestCase
1010
{
1111
/**
12-
* @var \Mpociot\ApiDoc\Generators\Generator
12+
* @var \Mpociot\ApiDoc\Tools\Generator
1313
*/
1414
protected $generator;
1515

@@ -228,7 +228,7 @@ public function can_parse_transformer_collection_tag_with_model()
228228
/** @test */
229229
public function can_call_route_and_generate_response()
230230
{
231-
$route = $this->createRoute('PUT', '/shouldFetchRouteResponse', 'shouldFetchRouteResponse', true);
231+
$route = $this->createRoute('POST', '/shouldFetchRouteResponse', 'shouldFetchRouteResponse', true);
232232

233233
$rules = [
234234
'response_calls' => [

0 commit comments

Comments
 (0)