Browse Source

Add support for custom headers on example calls #76

Marcel Pociot 8 năm trước cách đây
mục cha
commit
82368fbd97

+ 1 - 0
README.md

@@ -50,6 +50,7 @@ Option | Description
 `router` | The router to use, when processing the route files (can be Laravel or Dingo - defaults to Laravel)
 `bindings` | List of route bindings that should be replaced when trying to retrieve route results. Syntax format: `binding_one,id|binding_two,id`
 `force` | Force the re-generation of existing/modified API routes
+`header` | Custom HTTP headers to add to the example requests. Separate the header name and value with ":". For example: `--header 'Authorization: CustomToken'`
 
 ## Publish rule descriptions for customisation or translation.
 

+ 3 - 2
src/Mpociot/ApiDoc/Commands/GenerateDocumentation.php

@@ -31,6 +31,7 @@ class GenerateDocumentation extends Command
                             {--router=laravel : The router to be used (Laravel or Dingo)}
                             {--force : Force rewriting of existing routes}
                             {--bindings= : Route Model Bindings}
+                            {--header=* : Custom HTTP headers to add to the example requests. Separate the header name and value with ":"}
     ';
 
     /**
@@ -253,7 +254,7 @@ class GenerateDocumentation extends Command
         foreach ($routes as $route) {
             if (in_array($route->getName(), $allowedRoutes) || str_is($routePrefix, $route->getUri()) || in_array($middleware, $route->middleware())) {
                 if ($this->isValidRoute($route) && $this->isRouteVisibleForDocumentation($route->getAction()['uses'])) {
-                    $parsedRoutes[] = $generator->processRoute($route, $bindings, $withResponse);
+                    $parsedRoutes[] = $generator->processRoute($route, $bindings, $this->option('header'), $withResponse);
                     $this->info('Processed route: ['.implode(',', $route->getMethods()).'] '.$route->getUri());
                 } else {
                     $this->warn('Skipping route: ['.implode(',', $route->getMethods()).'] '.$route->getUri());
@@ -279,7 +280,7 @@ class GenerateDocumentation extends Command
         $parsedRoutes = [];
         foreach ($routes as $route) {
             if (empty($allowedRoutes) || in_array($route->getName(), $allowedRoutes) || str_is($routePrefix, $route->uri()) || in_array($middleware, $route->middleware())) {
-                $parsedRoutes[] = $generator->processRoute($route, $bindings, $withResponse);
+                $parsedRoutes[] = $generator->processRoute($route, $bindings, $this->option('header'), $withResponse);
                 $this->info('Processed route: ['.implode(',', $route->getMethods()).'] '.$route->uri());
             }
         }

+ 10 - 2
src/Mpociot/ApiDoc/Generators/AbstractGenerator.php

@@ -58,16 +58,24 @@ abstract class AbstractGenerator
 
     /**
      * @param  $route
+     * @param  $bindings
+     * @param  $headers
      *
      * @return \Illuminate\Http\Response
      */
-    protected function getRouteResponse($route, $bindings)
+    protected function getRouteResponse($route, $bindings, $headers = [])
     {
         $uri = $this->addRouteModelBindings($route, $bindings);
 
         $methods = $route->getMethods();
 
-        return $this->callRoute(array_shift($methods), $uri);
+        // Split headers into key - value pairs
+        $headers = collect($headers)->map(function($value) {
+            $split = explode(':', $value);
+            return [trim($split[0]) => trim($split[1])];
+        })->collapse()->toArray();
+
+        return $this->callRoute(array_shift($methods), $uri, [], [], [], $headers);
     }
 
     /**

+ 7 - 2
src/Mpociot/ApiDoc/Generators/DingoGenerator.php

@@ -9,17 +9,18 @@ class DingoGenerator extends AbstractGenerator
     /**
      * @param \Illuminate\Routing\Route $route
      * @param array $bindings
+     * @param array $headers
      * @param bool $withResponse
      *
      * @return array
      */
-    public function processRoute($route, $bindings = [], $withResponse = true)
+    public function processRoute($route, $bindings = [], $headers = [], $withResponse = true)
     {
         $response = '';
 
         if ($withResponse) {
             try {
-                $response = $this->getRouteResponse($route, $bindings);
+                $response = $this->getRouteResponse($route, $bindings, $headers);
             } catch (Exception $e) {
             }
         }
@@ -46,6 +47,10 @@ class DingoGenerator extends AbstractGenerator
     public function callRoute($method, $uri, $parameters = [], $cookies = [], $files = [], $server = [], $content = null)
     {
         $dispatcher = app('Dingo\Api\Dispatcher')->raw();
+        
+        collect($server)->map(function($key, $value) use ($dispatcher) {
+            $dispatcher->header($key, $value);
+        });
 
         return call_user_func_array([$dispatcher, strtolower($method)], [$uri]);
     }

+ 5 - 4
src/Mpociot/ApiDoc/Generators/LaravelGenerator.php

@@ -21,11 +21,12 @@ class LaravelGenerator extends AbstractGenerator
     /**
      * @param  \Illuminate\Routing\Route $route
      * @param array $bindings
+     * @param array $headers
      * @param bool $withResponse
      *
      * @return array
      */
-    public function processRoute($route, $bindings = [], $withResponse = true)
+    public function processRoute($route, $bindings = [], $headers = [], $withResponse = true)
     {
         $content = '';
 
@@ -35,7 +36,7 @@ class LaravelGenerator extends AbstractGenerator
 
 
         if ($withResponse) {
-            $response = $this->getRouteResponse($route, $bindings);
+            $response = $this->getRouteResponse($route, $bindings, $headers);
             if ($response->headers->get('Content-Type') === 'application/json') {
                 $content = json_encode(json_decode($response->getContent()), JSON_PRETTY_PRINT);
             } else {
@@ -73,10 +74,10 @@ class LaravelGenerator extends AbstractGenerator
         $kernel = App::make('Illuminate\Contracts\Http\Kernel');
         App::instance('middleware.disable', true);
 
-        $server = [
+        $server = collect([
             'CONTENT_TYPE' => 'application/json',
             'Accept' => 'application/json',
-        ];
+        ])->merge($server)->toArray();
 
         $request = Request::create(
             $uri, $method, $parameters,

+ 6 - 0
tests/Fixtures/TestController.php

@@ -2,6 +2,7 @@
 
 namespace Mpociot\ApiDoc\Tests\Fixtures;
 
+use Illuminate\Http\Request;
 use Illuminate\Routing\Controller;
 
 class TestController extends Controller
@@ -31,6 +32,11 @@ class TestController extends Controller
         return '';
     }
 
+    public function checkCustomHeaders(Request $request)
+    {
+        return $request->headers->all();
+    }
+
     public function fetchRouteResponse()
     {
         $fixture = new \stdClass();

+ 21 - 0
tests/GenerateDocumentationTest.php

@@ -120,6 +120,27 @@ class GenerateDocumentationTest extends TestCase
         $this->assertEquals($generatedCollection, $fixtureCollection);
     }
 
+    public function testCanAppendCustomHttpHeaders()
+    {
+        RouteFacade::get('/api/headers', TestController::class.'@checkCustomHeaders');
+
+        $output = $this->artisan('api:generate', [
+            '--routePrefix' => 'api/*',
+            '--header' => [
+                'Authorization: customAuthToken',
+                'X-Custom-Header: foobar',
+            ]
+        ]);
+
+        $generatedMarkdown = file_get_contents(__DIR__.'/../public/docs/source/index.md');
+        $this->assertContains('"authorization": [
+        "customAuthToken"
+    ],
+    "x-custom-header": [
+        "foobar"
+    ]', $generatedMarkdown);
+    }
+
     /**
      * @param string $command
      * @param array $parameters