feat(03-01): add API endpoints for serving images

- Add GET /api/images/[id] for original images
- Add GET /api/images/[id]/thumbnail for thumbnails
- Both endpoints return 404 for missing images
- Immutable cache headers for CDN optimization
This commit is contained in:
Thomas Richter
2026-01-29 15:23:33 +01:00
parent 0987d16dc0
commit b3640e78a1
2 changed files with 69 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
import { error } from '@sveltejs/kit';
import { readFile } from 'node:fs/promises';
import { imageRepository } from '$lib/server/db/repository';
import { getOriginalPath } from '$lib/server/images/storage';
import type { RequestHandler } from './$types';
const MIME_TYPES: Record<string, string> = {
jpg: 'image/jpeg',
jpeg: 'image/jpeg',
png: 'image/png',
gif: 'image/gif',
webp: 'image/webp',
heic: 'image/heic',
heif: 'image/heif'
};
export const GET: RequestHandler = async ({ params }) => {
const { id } = params;
const image = imageRepository.getById(id);
if (!image) {
error(404, 'Image not found');
}
try {
const path = getOriginalPath(id, image.ext);
const buffer = await readFile(path);
const mimeType = MIME_TYPES[image.ext.toLowerCase()] || 'application/octet-stream';
return new Response(buffer, {
headers: {
'Content-Type': mimeType,
'Content-Length': buffer.length.toString(),
'Cache-Control': 'public, max-age=31536000, immutable'
}
});
} catch {
error(404, 'Image file not found');
}
};

View File

@@ -0,0 +1,29 @@
import { error } from '@sveltejs/kit';
import { readFile } from 'node:fs/promises';
import { imageRepository } from '$lib/server/db/repository';
import { getThumbnailPath } from '$lib/server/images/storage';
import type { RequestHandler } from './$types';
export const GET: RequestHandler = async ({ params }) => {
const { id } = params;
const image = imageRepository.getById(id);
if (!image) {
error(404, 'Image not found');
}
try {
const path = getThumbnailPath(id);
const buffer = await readFile(path);
return new Response(buffer, {
headers: {
'Content-Type': 'image/jpeg',
'Content-Length': buffer.length.toString(),
'Cache-Control': 'public, max-age=31536000, immutable'
}
});
} catch {
error(404, 'Thumbnail not found');
}
};