Skip to content

Commit 622b7c8

Browse files
authored
Merge pull request #377 from shalvah/v3
Reimplement response calls
2 parents adc96fc + 4be52a6 commit 622b7c8

16 files changed

+858
-638
lines changed

README.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,7 @@ They will be included in the generated documentation text and example requests.
200200
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.
201201

202202
### Providing an example response
203-
You can provide an example response for a route. This will be disaplyed in the examples section. There are several ways of doing this.
204-
203+
You can provide an example response for a route. This will be displayed in the examples section. There are several ways of doing this.
205204

206205
#### @response
207206
You can provide an example response for a route by using the `@response` annotation with valid JSON:
@@ -223,7 +222,7 @@ public function show($id)
223222
#### @transformer, @transformerCollection, and @transformerModel
224223
You can define the transformer that is used for the result of the route using the `@transformer` tag (or `@transformerCollection` if the route returns a list). The package will attempt to generate an instance of the model to be transformed using the following steps, stopping at the first successful one:
225224

226-
1. Check if there is a `@transformerModel` tag to define the model being transformed. If there is none, use the class of the first parameter to the method.
225+
1. Check if there is a `@transformerModel` tag to define the model being transformed. If there is none, use the class of the first parameter to the transformer's `transform()` method.
227226
2. Get an instance of the model from the Eloquent model factory
228227
2. If the parameter is an Eloquent model, load the first from the database.
229228
3. Create an instance using `new`.
@@ -261,7 +260,17 @@ public function showUser(int $id)
261260
```
262261
For the first route above, this package will generate a set of two users then pass it through the transformer. For the last two, it will generate a single user and then pass it through the transformer.
263262

264-
#### Postman collections
263+
#### Gnerating responses automatically
264+
If you don't specify an example response using any of the above means, this package will attempt to get a sample response by making a request to the route (a "response call"). A few things to note about response calls:
265+
- They are done within a database transaction and changes are rolled back afterwards.
266+
- The configuration for response calls is located in the `config/apidoc.php`. They are configured within the `['apply']['response_calls']` section for each route group, allowing you to apply different settings for different sets of routes.
267+
- 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.
268+
- 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.
269+
- 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.
270+
- 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).
271+
272+
273+
### Postman collections
265274

266275
The generator automatically creates a Postman collection file, which you can import to use within your [Postman app](https://www.getpostman.com/apps) for even simpler API testing and usage.
267276

config/apidoc.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,62 @@
8484
// 'Authorization' => 'Bearer: {token}',
8585
// 'Api-Version' => 'v2',
8686
],
87+
88+
/*
89+
* If no @response or @transformer declaratons are found for the route,
90+
* we'll try to get a sample response by attempting an API call.
91+
* Configure the settings for the API call here,
92+
*/
93+
'response_calls' => [
94+
/*
95+
* API calls will be made only for routes in this group matching these HTTP methods (GET, POST, etc).
96+
* List the methods here or use '*' to mean all methods. Leave empty to disable API calls.
97+
*/
98+
'methods' => ['GET'],
99+
100+
/*
101+
* For URLs which have parameters (/users/{user}, /orders/{id?}),
102+
* specify what values the parameters should be replaced with.
103+
* Note that you must specify the full parameter, including curly brackets and question marks if any.
104+
*/
105+
'bindings' => [
106+
// '{user}' => 1
107+
],
108+
109+
/*
110+
* Environment variables which should be set for the API call.
111+
* This is a good place to ensure that notifications, emails
112+
* and other external services are not triggered during the documentation API calls
113+
*/
114+
'env' => [
115+
'APP_ENV' => 'documentation',
116+
'APP_DEBUG' => false,
117+
// 'env_var' => 'value',
118+
],
119+
120+
/*
121+
* Headers which should be sent with the API call.
122+
*/
123+
'headers' => [
124+
'Content-Type' => 'application/json',
125+
'Accept' => 'application/json',
126+
// 'key' => 'value',
127+
],
128+
129+
/*
130+
* Query parameters which should be sent with the API call.
131+
*/
132+
'query' => [
133+
// 'key' => 'value',
134+
],
135+
136+
/*
137+
* Body parameters which should be sent with the API call.
138+
*/
139+
'body' => [
140+
// 'key' => 'value',
141+
],
142+
],
87143
],
88144
],
89145
],

src/Commands/GenerateDocumentation.php

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@
88
use Mpociot\Reflection\DocBlock;
99
use Illuminate\Support\Collection;
1010
use Mpociot\ApiDoc\Tools\RouteMatcher;
11+
use Mpociot\ApiDoc\Generators\Generator;
1112
use Mpociot\Documentarian\Documentarian;
1213
use Mpociot\ApiDoc\Postman\CollectionWriter;
13-
use Mpociot\ApiDoc\Generators\DingoGenerator;
14-
use Mpociot\ApiDoc\Generators\LaravelGenerator;
15-
use Mpociot\ApiDoc\Generators\AbstractGenerator;
1614

1715
class GenerateDocumentation extends Command
1816
{
@@ -47,15 +45,14 @@ public function __construct(RouteMatcher $routeMatcher)
4745
*/
4846
public function handle()
4947
{
50-
$usingDIngoRouter = config('apidoc.router') == 'dingo';
51-
if ($usingDIngoRouter) {
48+
$usingDingoRouter = config('apidoc.router') == 'dingo';
49+
if ($usingDingoRouter) {
5250
$routes = $this->routeMatcher->getDingoRoutesToBeDocumented(config('apidoc.routes'));
53-
$generator = new DingoGenerator();
5451
} else {
5552
$routes = $this->routeMatcher->getLaravelRoutesToBeDocumented(config('apidoc.routes'));
56-
$generator = new LaravelGenerator();
5753
}
5854

55+
$generator = new Generator();
5956
$parsedRoutes = $this->processRoutes($generator, $routes);
6057
$parsedRoutes = collect($parsedRoutes)->groupBy('group')
6158
->sort(function ($a, $b) {
@@ -175,19 +172,19 @@ private function writeMarkdown($parsedRoutes)
175172
}
176173

177174
/**
178-
* @param AbstractGenerator $generator
175+
* @param Generator $generator
179176
* @param array $routes
180177
*
181178
* @return array
182179
*/
183-
private function processRoutes(AbstractGenerator $generator, array $routes)
180+
private function processRoutes(Generator $generator, array $routes)
184181
{
185182
$parsedRoutes = [];
186183
foreach ($routes as $routeItem) {
187184
$route = $routeItem['route'];
188185
/** @var Route $route */
189186
if ($this->isValidRoute($route) && $this->isRouteVisibleForDocumentation($route->getAction()['uses'])) {
190-
$parsedRoutes[] = $generator->processRoute($route) + $routeItem['apply'];
187+
$parsedRoutes[] = $generator->processRoute($route, $routeItem['apply']);
191188
$this->info('Processed route: ['.implode(',', $generator->getMethods($route)).'] '.$generator->getUri($route));
192189
} else {
193190
$this->warn('Skipping route: ['.implode(',', $generator->getMethods($route)).'] '.$generator->getUri($route));

0 commit comments

Comments
 (0)