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:
40
src/routes/api/images/[id]/+server.ts
Normal file
40
src/routes/api/images/[id]/+server.ts
Normal 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');
|
||||
}
|
||||
};
|
||||
29
src/routes/api/images/[id]/thumbnail/+server.ts
Normal file
29
src/routes/api/images/[id]/thumbnail/+server.ts
Normal 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');
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user