76 lines
3.2 KiB
Markdown
76 lines
3.2 KiB
Markdown
# Plan: Thymeleaf UI for Dynamic API Server
|
|
|
|
## Context
|
|
The app is currently REST-only. The user wants a browser-accessible UI covering:
|
|
- Generate API key
|
|
- List/view all keys
|
|
- Revoke a key
|
|
- Test dynamic endpoints
|
|
|
|
Since the app is stateless (no sessions), the UI controller will call the service layer directly (bypassing REST auth), with UI paths made public in SecurityConfiguration.
|
|
|
|
---
|
|
|
|
## Files to Create/Modify
|
|
|
|
### 1. `pom.xml` — Add dependencies
|
|
- `spring-boot-starter-thymeleaf`
|
|
- `bootstrap` (WebJar, 5.3.x)
|
|
- `webjars-locator-lite` (auto-resolves WebJar versions in templates)
|
|
|
|
### 2. `SecurityConfiguration.java` — Add public UI paths
|
|
Add `/ui/**` to the permit-all list so browser requests don't need an `X-API-Key` header.
|
|
|
|
### 3. `ApiKeyService.java` — Add `listAllKeys()` method
|
|
Returns `List<ApiKey>` via `apiKeyRepository.findAll()` (already available from JpaRepository).
|
|
|
|
### 4. `UiController.java` (new) — `com/dynamicapi/controller/UiController.java`
|
|
Mapped to `/ui/**`. Injects `ApiKeyService` and `DynamicApiConfigLoader` directly.
|
|
|
|
Endpoints:
|
|
- `GET /ui/` → `index.html` (generate key form)
|
|
- `POST /ui/generate` → calls `apiKeyService.generateApiKey()`, redirects to index with result
|
|
- `GET /ui/keys` → `keys.html` (list all keys)
|
|
- `POST /ui/revoke/{key}` → calls `apiKeyService.revokeApiKey()`, redirects to keys page
|
|
- `GET /ui/test` → `test.html` (test endpoint form, loads endpoint list)
|
|
- `POST /ui/test` → makes RestTemplate call to selected endpoint, returns result to test.html
|
|
|
|
### 5. Templates (new) — `src/main/resources/templates/`
|
|
|
|
**`fragments/layout.html`** — Bootstrap 5 base layout with navbar (links: Home, API Keys, Test Endpoints)
|
|
|
|
**`index.html`** — API Key generation
|
|
- Form: clientName (required), description (optional) → POST `/ui/generate`
|
|
- On success: shows generated key in a highlighted alert box with copy button (JS)
|
|
- On error: shows validation/duplicate error message
|
|
|
|
**`keys.html`** — Key management table
|
|
- Table columns: Client Name, Key (masked, last 8 chars shown), Created At, Last Used, Status (Active/Revoked), Actions
|
|
- Revoke button → POST `/ui/revoke/{key}` (only shown for active keys)
|
|
- Flash message on successful revoke
|
|
|
|
**`test.html`** — Endpoint tester
|
|
- Dropdown: select from registered dynamic endpoints (path + method)
|
|
- Input: API Key (required to call protected endpoints)
|
|
- Submit → POST `/ui/test` → displays JSON response in `<pre>` block
|
|
|
|
---
|
|
|
|
## Implementation Notes
|
|
|
|
- Use Bootstrap 5 via WebJar (no CDN required)
|
|
- Thymeleaf fragment includes for navbar (`th:replace`)
|
|
- Flash attributes (`RedirectAttributes`) for post-redirect-get pattern on generate/revoke
|
|
- RestTemplate in UiController for the endpoint tester (reuse existing pattern from DynamicApiController)
|
|
- The endpoint tester calls `http://localhost:8080/api/dynamic/{path}` with the user-supplied API key
|
|
|
|
---
|
|
|
|
## Verification
|
|
1. `mvn spring-boot:run` compiles and starts cleanly
|
|
2. `GET http://localhost:8080/api/ui/` — renders generate key form
|
|
3. Submit form → key displayed on page
|
|
4. `GET http://localhost:8080/api/ui/keys` — lists all keys
|
|
5. Revoke a key → table reflects revoked status
|
|
6. `GET http://localhost:8080/api/ui/test` — dropdown shows all dynamic endpoints, submit returns JSON response
|