Skip to content

Commit

Permalink
Add support for specifying example parameters (closes #391)
Browse files Browse the repository at this point in the history
  • Loading branch information
shalvah committed Oct 26, 2018
1 parent 9219179 commit c7e4952
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 10 deletions.
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ class UserController extends Controller
### Specifying request parameters

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


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

![](body_params.png)

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:

```php
/**
* @queryParam location_id required The id of the location.
* @queryParam user_id required The id of the user. Example: me
* @queryParam page required The page number. Example: 4
* @bodyParam user_id int required The id of the user. Example: 9
* @bodyParam room_id string The id of the room.
* @bodyParam forever boolean Whether to ban the user forever. Example: false
*/
```

### Indicating auth status
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.

Expand Down Expand Up @@ -299,7 +312,7 @@ If you don't specify an example response using any of the above means, this pack
- 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.
- 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.
- 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.
- 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).
- 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).


### Postman collections
Expand Down
2 changes: 1 addition & 1 deletion resources/views/partials/route.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
@endforeach
@endif
@foreach($route['bodyParameters'] as $attribute => $parameter)
-d "{{$attribute}}"="{{$parameter['value']}}" @if(! ($loop->last))\
-d "{{$attribute}}"="{{$parameter['value'] === false ? "false" : $parameter['value']}}" @if(! ($loop->last))\
@endif
@endforeach

Expand Down
64 changes: 59 additions & 5 deletions src/Tools/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ protected function getBodyParametersFromDocBlock(array $tags)
}

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

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

if (str_contains($description, ['number', 'count', 'page'])) {
$value = $this->generateDummyValue('integer');
} else {
$value = $this->generateDummyValue('string');
list($description, $value) = $this->parseDescription($description, 'string');
if (is_null($value)) {
$value = str_contains($description, ['number', 'count', 'page'])
? $this->generateDummyValue('integer')
: $this->generateDummyValue('string');
}

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

return $fake();
}

/**
* Allows users to specify an example for the parameter by writing 'Example: the-example',
* to be used in example requests and response calls.
*
* @param string $description
* @param string $type The type of the parameter. Used to cast the example provided, if any.
*
* @return array The description and included example.
*/
private function parseDescription(string $description, string $type)
{
$example = null;
if (preg_match('/(.*)\s+Example:\s*(.*)\s*/', $description, $content)) {
$description = $content[1];

// examples are parsed as strings by default, we need to cast them properly
$example = $this->castToType($content[2], $type);
}

return [$description, $example];
}

/**
* Cast a value from a string to a specified type.
*
* @param string $value
* @param string $type
*
* @return mixed
*/
private function castToType(string $value, string $type)
{
$casts = [
'integer' => 'intval',
'number' => 'floatval',
'float' => 'floatval',
'boolean' => 'boolval',
];

// First, we handle booleans. We can't use a regular cast,
//because PHP considers string 'false' as true.
if ($value == 'false' && $type == 'boolean') {
return false;
}

if (isset($casts[$type])) {
return $casts[$type]($value);
}

return $value;
}
}
6 changes: 4 additions & 2 deletions tests/Fixtures/TestController.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ public function withGroupOverride()
}

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

/**
* @queryParam location_id required The id of the location.
* @queryParam user_id required The id of the user. Example: me
* @queryParam page required The page number. Example: 4
* @queryParam filters The filters.
*/
public function withQueryParameters()
Expand Down
12 changes: 12 additions & 0 deletions tests/Unit/GeneratorTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public function can_parse_body_parameters()
'type' => 'integer',
'required' => true,
'description' => 'The id of the user.',
'value' => 9,
],
'room_id' => [
'type' => 'string',
Expand All @@ -61,6 +62,7 @@ public function can_parse_body_parameters()
'type' => 'boolean',
'required' => false,
'description' => 'Whether to ban the user forever.',
'value' => false,
],
'another_one' => [
'type' => 'number',
Expand Down Expand Up @@ -91,6 +93,16 @@ public function can_parse_query_parameters()
'required' => true,
'description' => 'The id of the location.',
],
'user_id' => [
'required' => true,
'description' => 'The id of the user.',
'value' => 'me',
],
'page' => [
'required' => true,
'description' => 'The page number.',
'value' => '4',
],
'filters' => [
'required' => false,
'description' => 'The filters.',
Expand Down

0 comments on commit c7e4952

Please sign in to comment.