Skip to content

Commit 217b22a

Browse files
authored
Merge pull request #394 from shalvah/v3
Add support for specifying example parameters
2 parents 47f8692 + ca9bc19 commit 217b22a

File tree

6 files changed

+101
-10
lines changed

6 files changed

+101
-10
lines changed

CHANGELOG.md

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

1616

17+
## [3.0.2] - Friday, 26 October 2018
18+
### Added
19+
- Ability to specify examples for body and query parameters (https://github.com/mpociot/laravel-apidoc-generator/pull/394)
20+
### Fixed
21+
- Rendering of example requests' descriptions (https://github.com/mpociot/laravel-apidoc-generator/pull/393)
22+
23+
## [3.0.1] - Monday, 22 October 2018
24+
### Fixed
25+
- Rendering of query parameters' descriptions (https://github.com/mpociot/laravel-apidoc-generator/pull/387)
26+
1727
## [3.0] - Sunday, 21 October 2018
1828
### Added
1929
- Official Lumen support (https://github.com/mpociot/laravel-apidoc-generator/pull/382)

README.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ class UserController extends Controller
188188
### Specifying request parameters
189189

190190
To specify a list of valid parameters your API route accepts, use the `@bodyParam` and `@queryParam` annotations.
191-
- The `@bodyParam` annotation takes the name of the parameter, its type, an optional "required" label, and then its description.
191+
- The `@bodyParam` annotation takes the name of the parameter, its type, an optional "required" label, and then its description.
192192
- The `@queryParam` annotation takes the name of the parameter, an optional "required" label, and then its description
193193

194194

@@ -222,6 +222,19 @@ They will be included in the generated documentation text and example requests.
222222

223223
![](body_params.png)
224224

225+
Note: a random value will be used as the value of each parameter in the example requests. If you'd like to specify an example value, you can do so by adding `Example: your-example` to the end of your description. For instance:
226+
227+
```php
228+
/**
229+
* @queryParam location_id required The id of the location.
230+
* @queryParam user_id required The id of the user. Example: me
231+
* @queryParam page required The page number. Example: 4
232+
* @bodyParam user_id int required The id of the user. Example: 9
233+
* @bodyParam room_id string The id of the room.
234+
* @bodyParam forever boolean Whether to ban the user forever. Example: false
235+
*/
236+
```
237+
225238
### Indicating auth status
226239
You can use the `@authenticated` annotation on a method to indicate if the endpoint is authenticated. A "Requires authentication" badge will be added to that route in the generated documentation.
227240

@@ -299,7 +312,7 @@ If you don't specify an example response using any of the above means, this pack
299312
- 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.
300313
- 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.
301314
- 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.
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).
315+
- By default, the package will generate dummy values for your documented body and query parameters and send in the request. (If you specified example values using `@bodyParam` or `@queryParam`, those will be used instead.) You can configure what headers and additional query and parameters should be sent when making the request (the `headers`, `query`, and `body` keys respectively).
303316

304317

305318
### Postman collections

resources/views/partials/route.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
@endforeach
2020
@endif
2121
@foreach($route['bodyParameters'] as $attribute => $parameter)
22-
-d "{{$attribute}}"="{{$parameter['value']}}" @if(! ($loop->last))\
22+
-d "{{$attribute}}"="{{$parameter['value'] === false ? "false" : $parameter['value']}}" @if(! ($loop->last))\
2323
@endif
2424
@endforeach
2525

src/Tools/Generator.php

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ protected function getBodyParametersFromDocBlock(array $tags)
101101
}
102102

103103
$type = $this->normalizeParameterType($type);
104-
$value = $this->generateDummyValue($type);
104+
list($description, $example) = $this->parseDescription($description, $type);
105+
$value = is_null($example) ? $this->generateDummyValue($type) : $example;
105106

106107
return [$name => compact('type', 'description', 'required', 'value')];
107108
})->toArray();
@@ -137,10 +138,11 @@ protected function getQueryParametersFromDocBlock(array $tags)
137138
$required = trim($required) == 'required' ? true : false;
138139
}
139140

140-
if (str_contains($description, ['number', 'count', 'page'])) {
141-
$value = $this->generateDummyValue('integer');
142-
} else {
143-
$value = $this->generateDummyValue('string');
141+
list($description, $value) = $this->parseDescription($description, 'string');
142+
if (is_null($value)) {
143+
$value = str_contains($description, ['number', 'count', 'page'])
144+
? $this->generateDummyValue('integer')
145+
: $this->generateDummyValue('string');
144146
}
145147

146148
return [$name => compact('description', 'required', 'value')];
@@ -255,4 +257,56 @@ private function generateDummyValue(string $type)
255257

256258
return $fake();
257259
}
260+
261+
/**
262+
* Allows users to specify an example for the parameter by writing 'Example: the-example',
263+
* to be used in example requests and response calls.
264+
*
265+
* @param string $description
266+
* @param string $type The type of the parameter. Used to cast the example provided, if any.
267+
*
268+
* @return array The description and included example.
269+
*/
270+
private function parseDescription(string $description, string $type)
271+
{
272+
$example = null;
273+
if (preg_match('/(.*)\s+Example:\s*(.*)\s*/', $description, $content)) {
274+
$description = $content[1];
275+
276+
// examples are parsed as strings by default, we need to cast them properly
277+
$example = $this->castToType($content[2], $type);
278+
}
279+
280+
return [$description, $example];
281+
}
282+
283+
/**
284+
* Cast a value from a string to a specified type.
285+
*
286+
* @param string $value
287+
* @param string $type
288+
*
289+
* @return mixed
290+
*/
291+
private function castToType(string $value, string $type)
292+
{
293+
$casts = [
294+
'integer' => 'intval',
295+
'number' => 'floatval',
296+
'float' => 'floatval',
297+
'boolean' => 'boolval',
298+
];
299+
300+
// First, we handle booleans. We can't use a regular cast,
301+
//because PHP considers string 'false' as true.
302+
if ($value == 'false' && $type == 'boolean') {
303+
return false;
304+
}
305+
306+
if (isset($casts[$type])) {
307+
return $casts[$type]($value);
308+
}
309+
310+
return $value;
311+
}
258312
}

tests/Fixtures/TestController.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ public function withGroupOverride()
3434
}
3535

3636
/**
37-
* @bodyParam user_id int required The id of the user.
37+
* @bodyParam user_id int required The id of the user. Example: 9
3838
* @bodyParam room_id string The id of the room.
39-
* @bodyParam forever boolean Whether to ban the user forever.
39+
* @bodyParam forever boolean Whether to ban the user forever. Example: false
4040
* @bodyParam another_one number Just need something here.
4141
* @bodyParam yet_another_param object required
4242
* @bodyParam even_more_param array
@@ -48,6 +48,8 @@ public function withBodyParameters()
4848

4949
/**
5050
* @queryParam location_id required The id of the location.
51+
* @queryParam user_id required The id of the user. Example: me
52+
* @queryParam page required The page number. Example: 4
5153
* @queryParam filters The filters.
5254
*/
5355
public function withQueryParameters()

tests/Unit/GeneratorTestCase.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public function can_parse_body_parameters()
5151
'type' => 'integer',
5252
'required' => true,
5353
'description' => 'The id of the user.',
54+
'value' => 9,
5455
],
5556
'room_id' => [
5657
'type' => 'string',
@@ -61,6 +62,7 @@ public function can_parse_body_parameters()
6162
'type' => 'boolean',
6263
'required' => false,
6364
'description' => 'Whether to ban the user forever.',
65+
'value' => false,
6466
],
6567
'another_one' => [
6668
'type' => 'number',
@@ -91,6 +93,16 @@ public function can_parse_query_parameters()
9193
'required' => true,
9294
'description' => 'The id of the location.',
9395
],
96+
'user_id' => [
97+
'required' => true,
98+
'description' => 'The id of the user.',
99+
'value' => 'me',
100+
],
101+
'page' => [
102+
'required' => true,
103+
'description' => 'The page number.',
104+
'value' => '4',
105+
],
94106
'filters' => [
95107
'required' => false,
96108
'description' => 'The filters.',

0 commit comments

Comments
 (0)