Skip to content

Commit 9d366ef

Browse files
authored
Merge pull request #552 from MarnuLombard/feature/examples/exclude_from_examples
Allows users to exclude a parameter from having an example
2 parents f2eb99d + e48003e commit 9d366ef

File tree

8 files changed

+85
-11
lines changed

8 files changed

+85
-11
lines changed

docs/documenting.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,19 @@ Note: a random value will be used as the value of each parameter in the example
9797
*/
9898
```
9999

100+
Note: To exclude a particular parameter from the generated examples (for all languages), you can annotate it with `No-example`. For instance:
101+
```php
102+
/**
103+
* @queryParam location_id required The id of the location. Example: 1
104+
* @queryParam user_id required The id of the user. No-example
105+
* @queryParam page required The page number. Example: 4
106+
*/
107+
```
108+
Outputs:
109+
```bash
110+
curl -X GET -G "https://example.com/api?location_id=1&page=4"
111+
```
112+
100113
Note: You can also add the `@queryParam` and `@bodyParam` annotations to a `\Illuminate\Foundation\Http\FormRequest` subclass instead, if you are using one in your controller method
101114

102115
```php

resources/views/partials/example-requests/bash.blade.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
```bash
2-
curl -X {{$route['methods'][0]}} {{$route['methods'][0] == 'GET' ? '-G ' : ''}}"{{ rtrim($baseUrl, '/')}}/{{ ltrim($route['boundUri'], '/') }}@if(count($route['queryParameters']))?@foreach($route['queryParameters'] as $attribute => $parameter)
3-
{{ urlencode($attribute) }}={{ urlencode($parameter['value']) }}@if(!$loop->last)&@endif
2+
curl -X {{$route['methods'][0]}} {{$route['methods'][0] == 'GET' ? '-G ' : ''}}"{{ rtrim($baseUrl, '/')}}/{{ ltrim($route['boundUri'], '/') }}@if(count($route['cleanQueryParameters']))?@foreach($route['cleanQueryParameters'] as $parameter => $value)
3+
{{ urlencode($parameter) }}={{ urlencode($value) }}@if(!$loop->last)&@endif
44
@endforeach
55
@endif" @if(count($route['headers']))\
66
@foreach($route['headers'] as $header => $value)
@@ -12,4 +12,4 @@
1212
-d '{!! json_encode($route['cleanBodyParameters']) !!}'
1313
@endif
1414

15-
```
15+
```

resources/views/partials/example-requests/javascript.blade.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
```javascript
22
const url = new URL("{{ rtrim($baseUrl, '/') }}/{{ ltrim($route['boundUri'], '/') }}");
3-
@if(count($route['queryParameters']))
3+
@if(count($route['cleanQueryParameters']))
44

55
let params = {
6-
@foreach($route['queryParameters'] as $attribute => $parameter)
7-
"{{ $attribute }}": "{{ $parameter['value'] }}",
6+
@foreach($route['cleanQueryParameters'] as $parameter => $value)
7+
"{{ $parameter }}": "{{ $value }}",
88
@endforeach
99
};
1010
Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));
@@ -35,4 +35,4 @@
3535
})
3636
.then(response => response.json())
3737
.then(json => console.log(json));
38-
```
38+
```

resources/views/partials/route.blade.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
@foreach($settings['languages'] as $language)
1515
@include("apidoc::partials.example-requests.$language")
1616

17-
1817
@endforeach
1918

2019
@if(in_array('GET',$route['methods']) || (isset($route['showresponse']) && $route['showresponse']))

src/Tools/Generator.php

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ protected function getBodyParametersFromDocBlock(array $tags)
133133
})
134134
->mapWithKeys(function ($tag) {
135135
preg_match('/(.+?)\s+(.+?)\s+(required\s+)?(.*)/', $tag->getContent(), $content);
136+
$content = preg_replace('/\s?No-example.?/', '', $content);
136137
if (empty($content)) {
137138
// this means only name and type were supplied
138139
list($name, $type) = preg_split('/\s+/', $tag->getContent());
@@ -150,7 +151,7 @@ protected function getBodyParametersFromDocBlock(array $tags)
150151

151152
$type = $this->normalizeParameterType($type);
152153
list($description, $example) = $this->parseDescription($description, $type);
153-
$value = is_null($example) ? $this->generateDummyValue($type) : $example;
154+
$value = is_null($example) && ! $this->shouldExcludeExample($tag) ? $this->generateDummyValue($type) : $example;
154155

155156
return [$name => compact('type', 'description', 'required', 'value')];
156157
})->toArray();
@@ -208,6 +209,7 @@ protected function getQueryParametersFromDocBlock(array $tags)
208209
})
209210
->mapWithKeys(function ($tag) {
210211
preg_match('/(.+?)\s+(required\s+)?(.*)/', $tag->getContent(), $content);
212+
$content = preg_replace('/\s?No-example.?/', '', $content);
211213
if (empty($content)) {
212214
// this means only name was supplied
213215
list($name) = preg_split('/\s+/', $tag->getContent());
@@ -224,7 +226,7 @@ protected function getQueryParametersFromDocBlock(array $tags)
224226
}
225227

226228
list($description, $value) = $this->parseDescription($description, 'string');
227-
if (is_null($value)) {
229+
if (is_null($value) && ! $this->shouldExcludeExample($tag)) {
228230
$value = str_contains($description, ['number', 'count', 'page'])
229231
? $this->generateDummyValue('integer')
230232
: $this->generateDummyValue('string');
@@ -394,6 +396,19 @@ private function parseDescription(string $description, string $type)
394396
return [$description, $example];
395397
}
396398

399+
/**
400+
* Allows users to specify that we shouldn't generate an example for the parameter
401+
* by writing 'No-example'.
402+
*
403+
* @param Tag $tag
404+
*
405+
* @return bool Whether no example should be generated
406+
*/
407+
private function shouldExcludeExample(Tag $tag)
408+
{
409+
return strpos($tag->getContent(), ' No-example') !== false;
410+
}
411+
397412
/**
398413
* Cast a value from a string to a specified type.
399414
*

src/Tools/Traits/ParamHelpers.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
trait ParamHelpers
66
{
77
/**
8-
* Create proper arrays from dot-noted parameter names.
8+
* Create proper arrays from dot-noted parameter names. Also filter out parameters which were excluded from having examples.
99
*
1010
* @param array $params
1111
*
@@ -14,6 +14,10 @@ trait ParamHelpers
1414
protected function cleanParams(array $params)
1515
{
1616
$values = [];
17+
$params = array_filter($params, function ($details) {
18+
return ! is_null($details['value']);
19+
});
20+
1721
foreach ($params as $name => $details) {
1822
$this->cleanValueFrom($name, $details['value'], $values);
1923
}

tests/Fixtures/TestController.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,16 @@ public function withQueryParameters()
114114
return '';
115115
}
116116

117+
/**
118+
* @bodyParam included string required Exists in examples. Example: 'Here'
119+
* @bodyParam excluded_body_param int Does not exist in examples. No-example
120+
* @queryParam excluded_query_param Does not exist in examples. No-example
121+
*/
122+
public function withExcludedExamples()
123+
{
124+
return '';
125+
}
126+
117127
/**
118128
* @authenticated
119129
*/

tests/Unit/GeneratorTestCase.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,39 @@ public function can_parse_query_parameters()
209209
], $queryParameters);
210210
}
211211

212+
/** @test */
213+
public function it_does_not_generate_values_for_excluded_params_and_excludes_them_from_clean_params()
214+
{
215+
$route = $this->createRoute('GET', '/api/test', 'withExcludedExamples');
216+
$parsed = $this->generator->processRoute($route);
217+
$cleanBodyParameters = $parsed['cleanBodyParameters'];
218+
$cleanQueryParameters = $parsed['cleanQueryParameters'];
219+
$bodyParameters = $parsed['bodyParameters'];
220+
$queryParameters = $parsed['queryParameters'];
221+
222+
$this->assertArrayHasKey('included', $cleanBodyParameters);
223+
$this->assertArrayNotHasKey('excluded_body_param', $cleanBodyParameters);
224+
$this->assertEmpty($cleanQueryParameters);
225+
226+
$this->assertArraySubset([
227+
'included' => [
228+
'required' => true,
229+
'type' => 'string',
230+
'description' => 'Exists in examples.',
231+
],
232+
'excluded_body_param' => [
233+
'type' => 'integer',
234+
'description' => 'Does not exist in examples.',
235+
],
236+
], $bodyParameters);
237+
238+
$this->assertArraySubset([
239+
'excluded_query_param' => [
240+
'description' => 'Does not exist in examples.',
241+
],
242+
], $queryParameters);
243+
}
244+
212245
/** @test */
213246
public function can_parse_route_group()
214247
{

0 commit comments

Comments
 (0)