Skip to content

Commit

Permalink
Add support for custom headers on example calls #76
Browse files Browse the repository at this point in the history
  • Loading branch information
mpociot committed Sep 14, 2016
1 parent de38dad commit 82368fb
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 10 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
5 changes: 3 additions & 2 deletions src/Mpociot/ApiDoc/Commands/GenerateDocumentation.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 ":"}
';

/**
Expand Down Expand Up @@ -253,7 +254,7 @@ private function processLaravelRoutes(AbstractGenerator $generator, $allowedRout
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());
Expand All @@ -279,7 +280,7 @@ private function processDingoRoutes(AbstractGenerator $generator, $allowedRoutes
$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());
}
}
Expand Down
12 changes: 10 additions & 2 deletions src/Mpociot/ApiDoc/Generators/AbstractGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,24 @@ protected function getParameters($routeData, $routeAction, $bindings)

/**
* @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);
}

/**
Expand Down
9 changes: 7 additions & 2 deletions src/Mpociot/ApiDoc/Generators/DingoGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
}
}
Expand All @@ -46,6 +47,10 @@ public function processRoute($route, $bindings = [], $withResponse = true)
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]);
}
Expand Down
9 changes: 5 additions & 4 deletions src/Mpociot/ApiDoc/Generators/LaravelGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ protected function getUri($route)
/**
* @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 = '';

Expand All @@ -35,7 +36,7 @@ public function processRoute($route, $bindings = [], $withResponse = true)


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 {
Expand Down Expand Up @@ -73,10 +74,10 @@ public function callRoute($method, $uri, $parameters = [], $cookies = [], $files
$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,
Expand Down
6 changes: 6 additions & 0 deletions tests/Fixtures/TestController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Mpociot\ApiDoc\Tests\Fixtures;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;

class TestController extends Controller
Expand Down Expand Up @@ -31,6 +32,11 @@ public function addRouteBindingsToRequestClass(DynamicRequest $request)
return '';
}

public function checkCustomHeaders(Request $request)
{
return $request->headers->all();
}

public function fetchRouteResponse()
{
$fixture = new \stdClass();
Expand Down
21 changes: 21 additions & 0 deletions tests/GenerateDocumentationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,27 @@ public function testGeneratedPostmanCollectionFileIsCorrect()
$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
Expand Down

0 comments on commit 82368fb

Please sign in to comment.