From 5d356cd694c8f4442b144e82b9f8e42efb041c18 Mon Sep 17 00:00:00 2001 From: Marcel Date: Sun, 15 Mar 2026 13:30:57 +0100 Subject: [PATCH] feat: add OpenAPI spec (dev only) with typed frontend client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add springdoc-openapi 3.0.2 (supports Spring Boot 4) to backend - Disable api-docs/swagger-ui in application.yaml (prod default) - Enable both in application-dev.yaml; Swagger UI at /swagger-ui.html - Add openapi-fetch (runtime) and openapi-typescript (dev) to frontend - Add generate:api npm script — run with backend up to regenerate types - Add src/lib/api.server.ts typed client factory (uses SvelteKit fetch) - Gitignore src/lib/generated/api.ts (generated artifact) Co-Authored-By: Claude Sonnet 4.6 --- backend/pom.xml | 7 ++++++ .../src/main/resources/application-dev.yaml | 7 ++++++ backend/src/main/resources/application.yaml | 6 +++++ frontend/.gitignore | 3 +++ frontend/package.json | 7 +++++- frontend/src/lib/api.server.ts | 25 +++++++++++++++++++ frontend/src/lib/generated/.gitkeep | 0 7 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 frontend/src/lib/api.server.ts create mode 100644 frontend/src/lib/generated/.gitkeep diff --git a/backend/pom.xml b/backend/pom.xml index e525f1c1..a48c8137 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -136,6 +136,13 @@ org.flywaydb flyway-database-postgresql + + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 3.0.2 + diff --git a/backend/src/main/resources/application-dev.yaml b/backend/src/main/resources/application-dev.yaml index 45827c3e..56c49e96 100644 --- a/backend/src/main/resources/application-dev.yaml +++ b/backend/src/main/resources/application-dev.yaml @@ -1,3 +1,10 @@ spring: jpa: show-sql: true + +springdoc: + api-docs: + enabled: true + swagger-ui: + enabled: true + path: /swagger-ui.html diff --git a/backend/src/main/resources/application.yaml b/backend/src/main/resources/application.yaml index a604c24c..6b89b8cf 100644 --- a/backend/src/main/resources/application.yaml +++ b/backend/src/main/resources/application.yaml @@ -21,6 +21,12 @@ spring: max-file-size: 50MB max-request-size: 50MB +springdoc: + api-docs: + enabled: false + swagger-ui: + enabled: false + app: s3: endpoint: ${S3_ENDPOINT} diff --git a/frontend/.gitignore b/frontend/.gitignore index 83eb0159..a3537d4e 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -24,3 +24,6 @@ vite.config.ts.timestamp-* # Paraglide src/lib/paraglide + +# Generated OpenAPI types — regenerate with: npm run generate:api +src/lib/generated/api.ts diff --git a/frontend/package.json b/frontend/package.json index cd35f0a5..45c8f35a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -13,9 +13,14 @@ "format": "prettier --write .", "lint": "prettier --check . && eslint .", "test:unit": "vitest", - "test": "npm run test:unit -- --run" + "test": "npm run test:unit -- --run", + "generate:api": "openapi-typescript http://localhost:8080/v3/api-docs -o ./src/lib/generated/api.ts" + }, + "dependencies": { + "openapi-fetch": "^0.13.5" }, "devDependencies": { + "openapi-typescript": "^7.8.0", "@eslint/compat": "^1.4.0", "@eslint/js": "^9.39.1", "@inlang/paraglide-js": "^2.5.0", diff --git a/frontend/src/lib/api.server.ts b/frontend/src/lib/api.server.ts new file mode 100644 index 00000000..927509cc --- /dev/null +++ b/frontend/src/lib/api.server.ts @@ -0,0 +1,25 @@ +/** + * Typed API client for the Familienarchiv backend. + * + * Types are generated from the OpenAPI spec — run `npm run generate:api` + * (with the backend running in dev mode) to regenerate src/lib/generated/api.ts. + * + * Usage in +page.server.ts: + * + * export async function load({ fetch }) { + * const api = createApiClient(fetch); + * const { data, error } = await api.GET('/api/documents/{id}', { + * params: { path: { id } } + * }); + * } + */ +import createClient from 'openapi-fetch'; +import { env } from '$env/dynamic/private'; +import type { paths } from '$lib/generated/api'; + +export function createApiClient(fetch: typeof globalThis.fetch) { + return createClient({ + baseUrl: env.API_INTERNAL_URL || 'http://localhost:8080', + fetch + }); +} diff --git a/frontend/src/lib/generated/.gitkeep b/frontend/src/lib/generated/.gitkeep new file mode 100644 index 00000000..e69de29b