From bb35e0d8aecbdc74c90b79cac334068e0834e455 Mon Sep 17 00:00:00 2001 From: Serreau Jovann Date: Mon, 23 Mar 2026 19:35:36 +0100 Subject: [PATCH] Add Insomnia export and dynamic hostname for API doc Insomnia export (/api/doc/insomnia.json): - Generates Insomnia v4 export format with all API routes - Workspace with environment variables (base_url, env, email, password, jwt_token) - Folders per section (Auth, Events, Categories, Billets, Scanner) - Each request with correct method, URL with Insomnia template vars, headers, body - Auth routes use base_url directly, others use base_url/api/{env}/... - Download button (indigo) next to Spec JSON button Dynamic hostname: - Insomnia export uses request.getSchemeAndHttpHost() (not hardcoded) - Template passes host via data-host attribute - JS env switcher reads host from data-host or falls back to location.origin - Base URLs update dynamically when switching sandbox/live Co-Authored-By: Claude Opus 4.6 (1M context) --- assets/modules/api-env-switcher.js | 46 +++++++------ src/Controller/ApiDocController.php | 100 ++++++++++++++++++++++++++++ templates/api/doc.html.twig | 12 ++-- 3 files changed, 134 insertions(+), 24 deletions(-) diff --git a/assets/modules/api-env-switcher.js b/assets/modules/api-env-switcher.js index feaa985..070cfcc 100644 --- a/assets/modules/api-env-switcher.js +++ b/assets/modules/api-env-switcher.js @@ -1,24 +1,26 @@ -const ENVS = { - sandbox: { - prefix: '/api/sandbox', - baseUrl: 'https://ticket.e-cosplay.fr/api/sandbox', - color: 'text-orange-400', - btnBg: 'bg-orange-500', - desc: 'Environnement de test. Les donnees ne sont pas modifiees.', - }, - live: { - prefix: '/api/live', - baseUrl: 'https://ticket.e-cosplay.fr/api/live', - color: 'text-green-400', - btnBg: 'bg-green-600', - desc: 'Environnement de production. Les donnees sont reelles.', - }, -} - const BTN_BASE = 'env-btn px-5 py-2 font-black uppercase text-xs tracking-widest transition-all cursor-pointer ' -function switchEnv(env) { - const config = ENVS[env] +function getEnvs(host) { + return { + sandbox: { + prefix: '/api/sandbox', + baseUrl: host + '/api/sandbox', + color: 'text-orange-400', + btnBg: 'bg-orange-500', + desc: 'Environnement de test. Les donnees ne sont pas modifiees.', + }, + live: { + prefix: '/api/live', + baseUrl: host + '/api/live', + color: 'text-green-400', + btnBg: 'bg-green-600', + desc: 'Environnement de production. Les donnees sont reelles.', + }, + } +} + +function switchEnv(env, envs) { + const config = envs[env] if (!config) return document.querySelectorAll('.env-btn').forEach(btn => { @@ -42,7 +44,11 @@ export function initApiEnvSwitcher() { const switcher = document.getElementById('env-switcher') if (!switcher) return + const hostEl = document.querySelector('[data-host]') + const host = hostEl ? hostEl.dataset.host : globalThis.location.origin + const envs = getEnvs(host) + document.querySelectorAll('.env-btn').forEach(btn => { - btn.addEventListener('click', () => switchEnv(btn.dataset.env)) + btn.addEventListener('click', () => switchEnv(btn.dataset.env, envs)) }) } diff --git a/src/Controller/ApiDocController.php b/src/Controller/ApiDocController.php index d02d5dd..bc96ae2 100644 --- a/src/Controller/ApiDocController.php +++ b/src/Controller/ApiDocController.php @@ -3,6 +3,7 @@ namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; @@ -23,6 +24,105 @@ class ApiDocController extends AbstractController return $this->json($this->getApiSpec()); } + #[Route('/api/doc/insomnia.json', name: 'app_api_doc_insomnia', methods: ['GET'])] + public function insomnia(Request $request): Response + { + $baseUrl = $request->getSchemeAndHttpHost(); + $resources = []; + $workspaceId = 'wrk_eticket'; + + $resources[] = [ + '_type' => 'workspace', + '_id' => $workspaceId, + 'name' => 'E-Ticket API', + 'description' => 'API E-Ticket - Organisateur & Scanner', + ]; + + $envId = 'env_eticket'; + $resources[] = [ + '_type' => 'environment', + '_id' => $envId, + 'parentId' => $workspaceId, + 'name' => 'E-Ticket', + 'data' => [ + 'base_url' => $baseUrl, + 'env' => 'sandbox', + 'email' => '', + 'password' => '', + 'jwt_token' => '', + ], + ]; + + $folderIndex = 0; + foreach ($this->getApiSpec() as $section) { + ++$folderIndex; + $folderId = 'fld_'.$folderIndex; + + $resources[] = [ + '_type' => 'request_group', + '_id' => $folderId, + 'parentId' => $workspaceId, + 'name' => $section['name'], + ]; + + foreach ($section['endpoints'] as $reqIndex => $endpoint) { + $isAuth = str_starts_with($endpoint['path'], '/api/auth'); + $url = $isAuth + ? '{{ _.base_url }}'.$endpoint['path'] + : '{{ _.base_url }}/api/{{ _.env }}'.str_replace('/api', '', $endpoint['path']); + + $headers = []; + $headers[] = ['name' => 'Content-Type', 'value' => 'application/json']; + if (!$isAuth) { + $headers[] = ['name' => 'ETicket-Email', 'value' => '{{ _.email }}']; + $headers[] = ['name' => 'ETicket-JWT', 'value' => '{{ _.jwt_token }}']; + } + + $body = null; + if ($endpoint['request']) { + $example = []; + foreach ($endpoint['request'] as $name => $field) { + $example[$name] = $field['example'] ?? ''; + } + $body = [ + 'mimeType' => 'application/json', + 'text' => json_encode($example, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_UNICODE), + ]; + } + + $resources[] = [ + '_type' => 'request', + '_id' => 'req_'.$folderIndex.'_'.$reqIndex, + 'parentId' => $folderId, + 'name' => $endpoint['summary'], + 'method' => $endpoint['method'], + 'url' => $url, + 'headers' => $headers, + 'body' => $body, + ]; + } + } + + $export = [ + '_type' => 'export', + '__export_format' => 4, + '__export_date' => date('Y-m-d\TH:i:s\Z'), + '__export_source' => 'eticket.api.doc', + 'resources' => $resources, + ]; + + $response = new Response( + json_encode($export, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_UNICODE | \JSON_UNESCAPED_SLASHES), + 200, + [ + 'Content-Type' => 'application/json', + 'Content-Disposition' => 'attachment; filename="eticket-api-insomnia.json"', + ] + ); + + return $response; + } + /** * @return list */ diff --git a/templates/api/doc.html.twig b/templates/api/doc.html.twig index 2354840..62c4fb4 100644 --- a/templates/api/doc.html.twig +++ b/templates/api/doc.html.twig @@ -38,9 +38,9 @@ -
+

Base URL

-

https://ticket.e-cosplay.fr/api/sandbox

+

{{ app.request.schemeAndHttpHost }}/api/sandbox

Environnement de test. Les donnees ne sont pas modifiees.

L'authentification (/api/auth/login) est commune aux deux environnements (vos vrais identifiants).

@@ -64,10 +64,14 @@
-