Web console
Two Nette components let you click through your API: ApiListingControl lists the endpoints and ApiConsoleControl renders a form for one, sends the request with cURL and shows the response.
Not for production
The console can call every endpoint with any token you type. Protect the presenter, or leave it out of production.
The presenter
<?php
declare(strict_types=1);
namespace App\UI\Console;
use Nette\Application\UI\Presenter;
use Tomaj\NetteApi\ApiDecider;
use Tomaj\NetteApi\Component\ApiConsoleControl;
use Tomaj\NetteApi\Component\ApiListingControl;
use Tomaj\NetteApi\Link\ApiLink;
/**
* The web console: a list of all endpoints and a generated form to call one.
* Protect it (or leave it out) in production, it can call every endpoint.
*/
final class ConsolePresenter extends Presenter
{
private string $method = '';
private string $version = '';
private string $package = '';
private ?string $apiAction = null;
public function __construct(private ApiDecider $apiDecider, private ApiLink $apiLink)
{
parent::__construct();
}
public function actionShow(string $method, string $version, string $package, ?string $apiAction = null): void
{
$this->method = $method;
$this->version = $version;
$this->package = $package;
$this->apiAction = $apiAction;
$this->template->endpoint = $this->apiDecider->getApi($method, $version, $package, $apiAction)->getEndpoint();
}
protected function createComponentApiListing(): ApiListingControl
{
$listing = new ApiListingControl($this->apiDecider);
$listing->onClick[] = function (string $method, string $version, string $package, ?string $apiAction): void {
$this->redirect('show', $method, $version, $package, $apiAction);
};
return $listing;
}
protected function createComponentApiConsole(): ApiConsoleControl
{
$api = $this->apiDecider->getApi($this->method, $this->version, $this->package, $this->apiAction);
return new ApiConsoleControl(
$this->getHttpRequest(),
$api->getEndpoint(),
$api->getHandler(),
$api->getAuthorization(),
$this->apiLink,
);
}
}The default view (default.latte) renders the endpoint list. Clicking an endpoint redirects to actionShow, which renders show.latte with the console form for that one endpoint.
{block content}
<h1>API console</h1>
<p>
OpenAPI document: <a href="{apiLink 'GET', '1', 'openapi'}">JSON</a>,
<a href="{apiLink 'GET', '1', 'openapi', null, ['format' => 'yaml']}">YAML</a>
</p>
{control apiListing}
{/block}{block content}
<p><a n:href="default">All endpoints</a></p>
<h1>{$endpoint->getMethod()} /{$endpoint->getUrl()}</h1>
{control apiConsole}
{/block}The components
| Component | Constructor | Notes |
|---|---|---|
ApiListingControl | (ApiDecider) | onClick[] gets method, version, package, apiAction |
ApiConsoleControl | (IRequest, EndpointInterface, ApiHandlerInterface, ApiAuthorizationInterface, ?ApiLink, ?ApiConsoleFormFactoryInterface) | setTemplateFilePath(), setFormRenderer() |
The form has one field per param, a field for the token or API key (or user and password for Basic), and a timeout. Write your own ApiConsoleFormFactoryInterface to change it.
FAQ
Why does the form submit fail with a CSRF error?
Nette forms accept a POST only from the same site, with the _nss cookie. Open the console in the browser, not through a script without cookies.
Can the console call another server?
It calls the URL in the form, which defaults to the endpoint on the current host.
How do I change the look?
Use setTemplateFilePath() with your own Latte template, or setFormRenderer().
Does the console show the request it sent?
Yes, the response panel shows the URL, the headers, the body and the time.
Do I need the console if I have OpenAPI?
No, they are independent. OpenAPI works with any OpenAPI tool.