Elysia.js Beispiele

Elysia.js modernes TypeScript Web-Framework-Beispiele einschließlich Hello World, Routing, Validierung und Plugin-Entwicklung

💻 Hello World Grundlagen typescript

🟢 simple

Grundlegende Elysia.js-Server-Einrichtung und Hello World-Anwendung

// Elysia.js Hello World Examples

import { Elysia } from 'elysia'

// 1. Basic Hello World server
const app = new Elysia()
    .get('/', () => 'Hello, World!')
    .listen(3000)

console.log(`🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`)

// 2. Hello World with different routes
const app = new Elysia()
    .get('/', () => 'Hello, Elysia!')
    .get('/hello', () => 'Hello from Elysia.js!')
    .get('/hello/:name', ({ params: { name } }) => `Hello, ${name}!`)
    .listen(3000)

// 3. JSON response
const app = new Elysia()
    .get('/api/hello', () => ({
        message: 'Hello, World!',
        timestamp: new Date().toISOString(),
        version: '1.0.0',
        framework: 'Elysia.js'
    }))
    .listen(3000)

// 4. HTML response
const app = new Elysia()
    .get('/html', () => (
        <html>
            <head>
                <title>Hello Elysia</title>
            </head>
            <body>
                <h1>Hello, World!</h1>
                <p>This is an HTML response from Elysia.js</p>
            </body>
        </html>
    ))
    .listen(3000)

// 5. Typed responses
const app = new Elysia()
    .get('/typed', () => ({
        id: 1,
        name: 'Elysia.js',
        features: ['TypeScript', 'Performance', 'Simple API'] as const
    }))
    .listen(3000)

// 6. Async handlers
const app = new Elysia()
    .get('/async', async () => {
        await new Promise(resolve => setTimeout(resolve, 1000))
        return 'Async response from Elysia!'
    })
    .listen(3000)

// 7. Error handling
const app = new Elysia()
    .get('/error', () => {
        throw new Error('Something went wrong!')
    })
    .onError(({ code, error }) => {
        if (code === 'NOT_FOUND')
            return 'Route not found :('

        return new Response(error.toString(), {
            status: 500
        })
    })
    .listen(3000)

// 8. Chain configuration
const app = new Elysia()
    .state('version', '1.0.0')
    .decorate('getDate', () => new Date())
    .get('/', ({ getDate, store: { version } }) => ({
        date: getDate(),
        version
    }))
    .listen(3000)

💻 Routing und Parameter typescript

🟡 intermediate

Routing-Definitionen, Parameter-Verarbeitung und HTTP-Methoden

// Elysia.js Routing Examples

import { Elysia } from 'elysia'

// 1. HTTP Methods
const app = new Elysia()
    .get('/users', () => 'Get all users')
    .post('/users', () => 'Create a new user')
    .put('/users/:id', ({ params: { id } }) => `Update user ${id}`)
    .patch('/users/:id', ({ params: { id } }) => `Patch user ${id}`)
    .delete('/users/:id', ({ params: { id } }) => `Delete user ${id}`)
    .listen(3000)

// 2. Path parameters
interface UserParams {
    id: string
}

const app = new Elysia()
    .get('/users/:id', ({ params: { id } }: { params: UserParams }) => {
        return `User ID: ${id}`
    })
    .get('/posts/:category/:slug', ({ params }) => {
        return `Category: ${params.category}, Slug: ${params.slug}`
    })
    .listen(3000)

// 3. Query parameters
const app = new Elysia()
    .get('/search', ({ query }) => {
        const { q, limit = '10', page = '1' } = query
        return {
            query: q || 'No query provided',
            limit: parseInt(limit),
            page: parseInt(page),
            results: [`Result for "${q}"`]
        }
    })
    .listen(3000)

// 4. Headers
const app = new Elysia()
    .get('/info', ({ headers }) => {
        return {
            userAgent: headers['user-agent'],
            accept: headers.accept,
            host: headers.host
        }
    })
    .listen(3000)

// 5. Request body
interface CreateUserBody {
    name: string
    email: string
    age?: number
}

const app = new Elysia()
    .post('/users', ({ body }: { body: CreateUserBody }) => {
        return {
            message: `User ${body.name} created successfully!`,
            user: {
                id: Math.random(),
                name: body.name,
                email: body.email,
                age: body.age || 0
            }
        }
    })
    .listen(3000)

// 6. Route groups
const app = new Elysia()
    .group('/api/v1', (app) => app
        .get('/users', () => ['user1', 'user2'])
        .post('/users', () => 'User created')
        .get('/posts', () => ['post1', 'post2'])
    )
    .group('/api/v2', (app) => app
        .get('/users', () => ['user1', 'user2', 'user3'])
        .get('/posts', () => ['post1', 'post2', 'post3'])
    )
    .listen(3000)

// 7. Wildcard routes
const app = new Elysia()
    .get('/static/*', ({ params }) => {
        return `Serving file: ${params['*']}`
    })
    .all('/fallback/*', () => {
        return 'This is a catch-all route'
    })
    .listen(3000)

// 8. Route guards
const app = new Elysia()
    .guard({
        beforeHandle({ set, headers }) {
            const auth = headers.authorization
            if (!auth?.startsWith('Bearer ')) {
                set.status = 401
                return 'Unauthorized'
            }
        }
    }, (app) => app
        .get('/protected', () => 'Protected data')
        .post('/protected', () => 'Protected action')
    )
    .get('/public', () => 'Public data')
    .listen(3000)

// 9. Custom responses
const app = new Elysia()
    .get('/custom-status', ({ set }) => {
        set.status = 418
        return "I'm a teapot"
    })
    .get('/redirect', ({ set }) => {
        set.headers['Location'] = '/'
        set.status = 302
        return
    })
    .listen(3000)

// 10. Route patterns
const app = new Elysia()
    .match('GET|POST', '/users', ({ request }) => {
        return `${request.method} /users`
    })
    .match(['PUT', 'PATCH'], '/users/:id', ({ request, params }) => {
        return `${request.method} /users/${params.id}`
    })
    .listen(3000)

💻 Datenvalidierung typescript

🟡 intermediate

Anfrage- und Antwortvalidierung mit integrierten Validatoren

// Elysia.js Validation Examples

import { Elysia, t } from 'elysia'

// 1. Basic body validation
const app = new Elysia()
    .post('/users', ({ body }) => {
        return `User ${body.name} (${body.email}) created!`
    }, {
        body: t.Object({
            name: t.String(),
            email: t.String({ format: 'email' }),
            age: t.Number({ minimum: 18 })
        })
    })
    .listen(3000)

// 2. Query parameter validation
const app = new Elysia()
    .get('/search', ({ query }) => {
        return `Searching for "${query.q}" with limit ${query.limit}`
    }, {
        query: t.Object({
            q: t.String({ minLength: 1 }),
            limit: t.Optional(t.Number({ minimum: 1, maximum: 100 })),
            category: t.Optional(t.Enum(['tech', 'news', 'sports'] as const))
        })
    })
    .listen(3000)

// 3. Path parameter validation
const app = new Elysia()
    .get('/users/:id', ({ params: { id } }) => {
        return `User ID: ${id}`
    }, {
        params: t.Object({
            id: t.Numeric()
        })
    })
    .listen(3000)

// 4. Header validation
const app = new Elysia()
    .post('/data', ({ headers }) => {
        return 'Data received'
    }, {
        headers: t.Object({
            'content-type': t.Literal('application/json'),
            'x-api-key': t.String({ minLength: 10 })
        })
    })
    .listen(3000)

// 5. Response validation
const app = new Elysia()
    .get('/user/:id', ({ params: { id } }) => {
        return {
            id: parseInt(id),
            name: `User ${id}`,
            email: `user${id}@example.com`,
            createdAt: new Date()
        }
    }, {
        params: t.Object({
            id: t.Numeric()
        }),
        response: {
            200: t.Object({
                id: t.Number(),
                name: t.String(),
                email: t.String({ format: 'email' }),
                createdAt: t.Date()
            }),
            404: t.Object({
                error: t.String()
            })
        }
    })
    .listen(3000)

// 6. Custom validation with transform
const app = new Elysia()
    .post('/register', ({ body }) => {
        return body
    }, {
        body: t.Object({
            username: t.String({
                minLength: 3,
                maxLength: 20,
                pattern: '^[a-zA-Z0-9_]+$'
            }),
            email: t.String({ format: 'email' }),
            password: t.String({ minLength: 8 }),
            confirmPassword: t.String()
        }),
        transform({ body }) {
            body.username = body.username.toLowerCase()
        }
    })
    .listen(3000)

// 7. Array validation
const app = new Elysia()
    .post('/batch', ({ body }) => {
        return `Processed ${body.items.length} items`
    }, {
        body: t.Object({
            items: t.Array(t.Object({
                id: t.Number(),
                name: t.String(),
                price: t.Number({ minimum: 0 })
            })),
            metadata: t.Optional(t.Object({
                total: t.Number(),
                currency: t.String({ default: 'USD' })
            }))
        })
    })
    .listen(3000)

// 8. Nested object validation
const app = new Elysia()
    .post('/order', ({ body }) => {
        return 'Order created'
    }, {
        body: t.Object({
            customer: t.Object({
                name: t.String(),
                address: t.Object({
                    street: t.String(),
                    city: t.String(),
                    zipCode: t.String(),
                    country: t.String()
                })
            }),
            items: t.Array(t.Object({
                productId: t.Number(),
                quantity: t.Number({ minimum: 1 }),
                price: t.Number()
            })),
            shipping: t.Optional(t.Union([
                t.Literal('standard'),
                t.Literal('express'),
                t.Literal('overnight')
            ]))
        })
    })
    .listen(3000)

// 9. File upload validation
const app = new Elysia()
    .post('/upload', ({ body: { file } }) => {
        return `Uploaded file: ${file.name} (${file.size} bytes)`
    }, {
        body: t.Object({
            file: t.File({
                type: ['image/jpeg', 'image/png', 'image/gif'],
                maxSize: '5m'
            }),
            description: t.Optional(t.String({ maxLength: 500 }))
        })
    })
    .listen(3000)

// 10. Custom error messages
const app = new Elysia()
    .onError(({ code, error }) => {
        if (code === 'VALIDATION') {
            return {
                success: false,
                errors: error.all.map(({ path, message }) => ({
                    field: path.join('.'),
                    message
                }))
            }
        }
    })
    .post('/custom-validation', ({ body }) => {
        return 'Success'
    }, {
        body: t.Object({
            username: t.String({
                error: 'Username must be a string'
            }),
            email: t.String({
                format: 'email',
                error: 'Invalid email format'
            })
        })
    })
    .listen(3000)

💻 Middleware und Hooks typescript

🟡 intermediate

Middleware, Lebenszyklus-Hooks und Fehlerbehandlung

// Elysia.js Middleware and Hooks Examples

import { Elysia } from 'elysia'

// 1. Before handle hook
const app = new Elysia()
    .onBeforeHandle({ as: 'global' }, ({ set, headers }) => {
        // Add CORS headers
        set.headers['Access-Control-Allow-Origin'] = '*'
        set.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE'
        set.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
    })
    .get('/data', () => 'CORS enabled data')
    .listen(3000)

// 2. After handle hook
const app = new Elysia()
    .onAfterHandle({ as: 'global' }, ({ response }) => {
        // Wrap all responses
        return {
            success: true,
            timestamp: new Date().toISOString(),
            data: response
        }
    })
    .get('/users', () => ['Alice', 'Bob', 'Charlie'])
    .listen(3000)

// 3. Transform hook
const app = new Elysia()
    .onTransform({ as: 'global' }, ({ request }) => {
        console.log(`${request.method} ${request.url}`)
    })
    .get('/track', () => 'Tracked request')
    .listen(3000)

// 4. Logger middleware
const logger = new Elysia({ name: 'logger' })
    .onBeforeHandle(({ request, set }) => {
        console.log(`[${new Date().toISOString()}] ${request.method} ${request.url}`)
    })
    .onAfterHandle(({ response }) => {
        console.log(`Response: ${JSON.stringify(response)}`)
    })

const app = new Elysia()
    .use(logger)
    .get('/logged', () => 'This request is logged')
    .listen(3000)

// 5. Authentication middleware
const auth = new Elysia({ name: 'auth' })
    .derive({ as: 'global' }, ({ headers }) => {
        const authHeader = headers.authorization
        if (!authHeader?.startsWith('Bearer ')) {
            throw new Error('Unauthorized')
        }

        const token = authHeader.slice(7)
        // Simplified token validation
        const user = { id: 1, name: 'John Doe' }
        return { user }
    })

const app = new Elysia()
    .use(auth)
    .get('/profile', ({ user }) => `Hello, ${user.name}!`)
    .listen(3000)

// 6. Rate limiting middleware
const rateLimiter = new Map<string, { count: number; resetTime: number }>()

const rateLimit = new Elysia({ name: 'rate-limit' })
    .onBeforeHandle(({ set, headers }) => {
        const ip = headers['x-forwarded-for'] || 'unknown'
        const now = Date.now()
        const windowMs = 60 * 1000 // 1 minute
        const maxRequests = 10

        const record = rateLimiter.get(ip)

        if (!record || now > record.resetTime) {
            rateLimiter.set(ip, { count: 1, resetTime: now + windowMs })
            return
        }

        if (record.count >= maxRequests) {
            set.status = 429
            return 'Too many requests'
        }

        record.count++
    })

const app = new Elysia()
    .use(rateLimit)
    .get('/limited', () => 'Rate limited endpoint')
    .listen(3000)

// 7. Error handling
const app = new Elysia()
    .onError(({ code, error, set }) => {
        switch (code) {
            case 'NOT_FOUND':
                set.status = 404
                return { error: 'Route not found' }

            case 'VALIDATION':
                set.status = 400
                return {
                    error: 'Validation failed',
                    details: error.all
                }

            case 'INTERNAL_SERVER_ERROR':
                set.status = 500
                return { error: 'Internal server error' }

            default:
                set.status = 500
                return { error: 'Unknown error' }
        }
    })
    .get('/error', () => {
        throw new Error('Test error')
    })
    .listen(3000)

// 8. Request context extension
const app = new Elysia()
    .state('version', '1.0.0')
    .decorate('getDb', () => {
        // Mock database connection
        return {
            query: (sql: string) => `Executing: ${sql}`,
            close: () => console.log('DB connection closed')
        }
    })
    .derive({ as: 'global' }, ({ store }) => {
        return {
            appInfo: {
                version: store.version,
                uptime: process.uptime()
            }
        }
    })
    .get('/context', ({ getDb, appInfo }) => {
        return {
            db: getDb().query('SELECT * FROM users'),
            appInfo
        }
    })
    .listen(3000)

// 9. Plugin system
const loggingPlugin = new Elysia({ name: 'logging' })
    .onBeforeHandle(({ request }) => {
        console.log(`📝 ${request.method} ${request.url}`)
    })
    .onAfterHandle(() => {
        console.log('✅ Request completed')
    })
    .onError(({ error }) => {
        console.log(`❌ Error: ${error.message}`)
    })

const timingPlugin = new Elysia({ name: 'timing' })
    .onBeforeHandle(() => ({ startTime: Date.now() }))
    .onAfterHandle({ beforeHandle: ({ startTime }) => ({ startTime }) }, ({ startTime }) => {
        const duration = Date.now() - startTime
        console.log(`⏱️ Request took ${duration}ms`)
    })

const app = new Elysia()
    .use(loggingPlugin)
    .use(timingPlugin)
    .get('/plugged', () => 'This request uses multiple plugins')
    .listen(3000)

// 10. Route-specific hooks
const app = new Elysia()
    .get('/specific',
        () => 'Route with specific hooks',
        {
            beforeHandle({ set }) {
                set.headers['X-Custom'] = 'value'
            },
            afterHandle({ response }) {
                return `Processed: ${response}`
            }
        }
    )
    .listen(3000)

// 11. Lifecycle order demonstration
const app = new Elysia()
    .onRequest(() => console.log('1. onRequest'))
    .onBeforeHandle(() => console.log('2. onBeforeHandle'))
    .onAfterHandle(() => console.log('3. onAfterHandle'))
    .onResponse(() => console.log('4. onResponse'))
    .get('/lifecycle', () => {
        console.log('-> Handler executing')
        return 'Lifecycle demo'
    })
    .listen(3000)

💻 WebSocket-Unterstützung typescript

🟡 intermediate

Echtzeit-WebSocket-Kommunikationsbeispiele

// Elysia.js WebSocket Examples

import { Elysia } from 'elysia'
import { websocket } from '@elysiajs/websocket'

// 1. Basic WebSocket server
const app = new Elysia()
    .use(websocket())
    .ws('/ws', {
        message(ws, message) {
            ws.send(`Echo: ${message}`)
        },
        open(ws) {
            console.log('WebSocket connection opened')
            ws.send('Welcome to the WebSocket server!')
        },
        close(ws) {
            console.log('WebSocket connection closed')
        }
    })
    .listen(3000)

// 2. Chat server
interface ChatMessage {
    type: 'message' | 'join' | 'leave'
    user: string
    content: string
    timestamp: string
}

const clients = new Map<string, any>()

const app = new Elysia()
    .use(websocket())
    .ws('/chat', {
        message(ws, message: ChatMessage) {
            const chatMessage: ChatMessage = {
                type: 'message',
                user: message.user,
                content: message.content,
                timestamp: new Date().toISOString()
            }

            // Broadcast to all connected clients
            app.server?.publish('chat', JSON.stringify(chatMessage))
        },
        open(ws) {
            const userId = `user_${Math.random().toString(36).substr(2, 9)}`
            ws.data.id = userId
            clients.set(userId, ws)

            const joinMessage: ChatMessage = {
                type: 'join',
                user: 'System',
                content: `User ${userId} joined the chat`,
                timestamp: new Date().toISOString()
            }

            app.server?.publish('chat', JSON.stringify(joinMessage))
        },
        close(ws) {
            const userId = ws.data.id
            clients.delete(userId)

            const leaveMessage: ChatMessage = {
                type: 'leave',
                user: 'System',
                content: `User ${userId} left the chat`,
                timestamp: new Date().toISOString()
            }

            app.server?.publish('chat', JSON.stringify(leaveMessage))
        }
    })
    .listen(3000)

// 3. Real-time notifications
const app = new Elysia()
    .use(websocket())
    .ws('/notifications', {
        open(ws) {
            console.log('Notification client connected')

            // Send periodic notifications
            const interval = setInterval(() => {
                const notification = {
                    type: 'notification',
                    title: 'System Update',
                    message: `System time: ${new Date().toLocaleTimeString()}`,
                    timestamp: new Date().toISOString()
                }

                ws.send(JSON.stringify(notification))
            }, 5000)

            ws.data.interval = interval
        },
        close(ws) {
            if (ws.data.interval) {
                clearInterval(ws.data.interval)
            }
        }
    })
    .listen(3000)

// 4. Multi-room chat
interface Room {
    id: string
    name: string
    clients: Map<string, any>
}

const rooms = new Map<string, Room>()

const app = new Elysia()
    .use(websocket())
    .ws('/room/:roomId', {
        params: {
            roomId: t.String()
        },
        message(ws, message) {
            const { roomId } = ws.data.params
            const room = rooms.get(roomId)

            if (!room) return

            const chatMessage = {
                type: 'message',
                user: ws.data.user,
                content: message.content,
                timestamp: new Date().toISOString()
            }

            // Send to all clients in the room
            room.clients.forEach((client) => {
                client.send(JSON.stringify(chatMessage))
            })
        },
        open(ws) {
            const { roomId } = ws.data.params
            const userId = `user_${Math.random().toString(36).substr(2, 9)}`

            ws.data.user = userId
            ws.data.roomId = roomId

            // Get or create room
            let room = rooms.get(roomId)
            if (!room) {
                room = {
                    id: roomId,
                    name: `Room ${roomId}`,
                    clients: new Map()
                }
                rooms.set(roomId, room)
            }

            // Add client to room
            room.clients.set(userId, ws)

            const joinMessage = {
                type: 'join',
                user: 'System',
                content: `${userId} joined the room`,
                timestamp: new Date().toISOString()
            }

            room.clients.forEach((client) => {
                client.send(JSON.stringify(joinMessage))
            })
        },
        close(ws) {
            const { roomId, user } = ws.data
            const room = rooms.get(roomId)

            if (room) {
                room.clients.delete(user)

                const leaveMessage = {
                    type: 'leave',
                    user: 'System',
                    content: `${user} left the room`,
                    timestamp: new Date().toISOString()
                }

                room.clients.forEach((client) => {
                    client.send(JSON.stringify(leaveMessage))
                })

                // Clean up empty rooms
                if (room.clients.size === 0) {
                    rooms.delete(roomId)
                }
            }
        }
    })
    .listen(3000)

// 5. WebSocket with HTTP API
interface Todo {
    id: number
    text: string
    completed: boolean
    createdAt: string
}

const todos: Todo[] = [
    { id: 1, text: 'Learn Elysia.js', completed: true, createdAt: new Date().toISOString() },
    { id: 2, text: 'Build WebSocket app', completed: false, createdAt: new Date().toISOString() }
]

const app = new Elysia()
    .use(websocket())
    .ws('/todos', {
        open(ws) {
            // Send initial todos
            ws.send(JSON.stringify({
                type: 'todos',
                data: todos
            }))
        }
    })
    .get('/api/todos', () => todos)
    .post('/api/todos', ({ body }) => {
        const newTodo: Todo = {
            id: Date.now(),
            text: body.text,
            completed: false,
            createdAt: new Date().toISOString()
        }

        todos.push(newTodo)

        // Broadcast to all WebSocket clients
        app.server?.publish('todos', JSON.stringify({
            type: 'todo-added',
            data: newTodo
        }))

        return newTodo
    })
    .put('/api/todos/:id', ({ params, body }) => {
        const todo = todos.find(t => t.id === parseInt(params.id))
        if (!todo) return null

        Object.assign(todo, body)

        // Broadcast update
        app.server?.publish('todos', JSON.stringify({
            type: 'todo-updated',
            data: todo
        }))

        return todo
    })
    .delete('/api/todos/:id', ({ params }) => {
        const index = todos.findIndex(t => t.id === parseInt(params.id))
        if (index === -1) return null

        const deletedTodo = todos.splice(index, 1)[0]

        // Broadcast deletion
        app.server?.publish('todos', JSON.stringify({
            type: 'todo-deleted',
            data: { id: deletedTodo.id }
        }))

        return deletedTodo
    })
    .listen(3000)

// 6. WebSocket authentication
const app = new Elysia()
    .use(websocket())
    .ws('/auth', {
        beforeHandle({ headers, set }) {
            const token = headers.authorization?.replace('Bearer ', '')

            // Simple token validation
            if (!token || token !== 'valid-token') {
                set.headers['sec-websocket-protocol'] = 'close'
                return 'Unauthorized'
            }
        },
        message(ws, message) {
            ws.send(`Authenticated message: ${message}`)
        },
        open(ws) {
            ws.send('WebSocket connection authenticated')
        }
    })
    .listen(3000)

// 7. WebSocket with binary data
const app = new Elysia()
    .use(websocket())
    .ws('/binary', {
        message(ws, message) {
            if (message instanceof ArrayBuffer) {
                // Echo binary data
                ws.send(message)
            } else {
                ws.send(`Received text: ${message}`)
            }
        },
        open(ws) {
            ws.send('Binary WebSocket server ready')
        }
    })
    .listen(3000)

💻 Authentifizierung typescript

🟡 intermediate

JWT-Authentifizierungs- und Autorisierungs-Middleware

// Elysia.js Authentication Examples

import { Elysia, t } from 'elysia'
import { jwt } from '@elysiajs/jwt'

// 1. JWT Authentication
const app = new Elysia()
    .use(
        jwt({
            name: 'jwt',
            secret: process.env.JWT_SECRET || 'your-secret-key-here'
        })
    )
    .post('/login', async ({ body, jwt }) => {
        // Validate user credentials (in real app, check database)
        const { username, password } = body

        // Mock user validation
        if (username === 'admin' && password === 'password123') {
            const payload = {
                sub: '1234567890',
                name: 'John Doe',
                email: '[email protected]',
                role: 'admin',
                iat: Math.floor(Date.now() / 1000)
            }

            const token = await jwt.sign(payload)
            return {
                success: true,
                token,
                user: {
                    id: payload.sub,
                    name: payload.name,
                    email: payload.email,
                    role: payload.role
                }
            }
        }

        return {
            success: false,
            message: 'Invalid credentials'
        }
    }, {
        body: t.Object({
            username: t.String(),
            password: t.String({ minLength: 6 })
        })
    })
    .get('/protected', async ({ jwt, headers }) => {
        const auth = headers.authorization
        if (!auth?.startsWith('Bearer ')) {
            return { error: 'No token provided' }
        }

        const token = auth.slice(7)
        const payload = await jwt.verify(token)

        if (!payload) {
            return { error: 'Invalid token' }
        }

        return {
            message: 'Access granted',
            user: payload
        }
    })
    .listen(3000)

// 2. Middleware-based Authentication
const authMiddleware = new Elysia({ name: 'auth' })
    .use(
        jwt({
            name: 'jwt',
            secret: 'middleware-secret'
        })
    )
    .derive({ as: 'global' }, async ({ jwt, headers }) => {
        const auth = headers.authorization
        const token = auth?.replace('Bearer ', '')

        let user = null
        if (token) {
            user = await jwt.verify(token)
        }

        return {
            user,
            isAuthenticated: !!user
        }
    })
    .guard({
        beforeHandle({ user, set }) {
            if (!user) {
                set.status = 401
                return { error: 'Unauthorized' }
            }
        }
    }, (app) => app
        .get('/api/users', () => ['Alice', 'Bob', 'Charlie'])
        .post('/api/users', () => 'User created')
        .put('/api/users/:id', () => 'User updated')
    )
    .get('/public', () => 'Public endpoint')

const mainApp = new Elysia()
    .use(authMiddleware)
    .listen(3000)

// 3. Role-based Authorization
interface User {
    id: string
    name: string
    email: string
    role: 'admin' | 'user' | 'moderator'
    permissions: string[]
}

const rbacPlugin = new Elysia({ name: 'rbac' })
    .use(
        jwt({
            name: 'jwt',
            secret: 'rbac-secret'
        })
    )
    .derive({ as: 'global' }, async ({ jwt, headers }) => {
        const token = headers.authorization?.replace('Bearer ', '')

        if (!token) {
            return {
                user: null as User | null,
                hasRole: (role: string) => false,
                hasPermission: (permission: string) => false
            }
        }

        const payload = await jwt.verify(token) as any
        const user: User = payload?.user || null

        const hasRole = (role: string): boolean => {
            return user?.role === role
        }

        const hasPermission = (permission: string): boolean => {
            return user?.permissions?.includes(permission) || false
        }

        return { user, hasRole, hasPermission }
    })
    .guard({
        beforeHandle({ user, set }) {
            if (!user) {
                set.status = 401
                return { error: 'Unauthorized' }
            }
        }
    }, (app) => app
        .guard({
            beforeHandle({ hasRole, set }) {
                if (!hasRole('admin')) {
                    set.status = 403
                    return { error: 'Admin access required' }
                }
            }
        }, (app) => app
            .delete('/admin/users/:id', () => 'User deleted')
            .get('/admin/stats', () => 'Admin statistics')
        )
        .guard({
            beforeHandle({ hasPermission, set }) {
                if (!hasPermission('read:posts')) {
                    set.status = 403
                    return { error: 'Read permission required' }
                }
            }
        }, (app) => app
            .get('/posts', () => 'List of posts')
        )
        .post('/posts', () => 'Post created') // No specific permission required
    )

const app = new Elysia()
    .use(rbacPlugin)
    .listen(3000)

// 4. OAuth Integration (GitHub example)
const app = new Elysia()
    .state('oauth', {
        clientId: process.env.GITHUB_CLIENT_ID,
        clientSecret: process.env.GITHUB_CLIENT_SECRET,
        redirectUri: 'http://localhost:3000/auth/github/callback'
    })
    .get('/auth/github', ({ store: { oauth } }) => {
        const authUrl = `https://github.com/login/oauth/authorize?` +
            `client_id=${oauth.clientId}&` +
            `redirect_uri=${encodeURIComponent(oauth.redirectUri)}&` +
            `scope=user:email`

        return { authUrl }
    })
    .get('/auth/github/callback', async ({ query, store: { oauth }, jwt }) => {
        const { code } = query

        if (!code) {
            return { error: 'Authorization code not provided' }
        }

        // Exchange code for access token
        const tokenResponse = await fetch('https://github.com/login/oauth/access_token', {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                client_id: oauth.clientId,
                client_secret: oauth.clientSecret,
                code
            })
        }).then(res => res.json())

        if (tokenResponse.error) {
            return { error: tokenResponse.error_description }
        }

        // Get user information
        const userResponse = await fetch('https://api.github.com/user', {
            headers: {
                'Authorization': `token ${tokenResponse.access_token}`
            }
        }).then(res => res.json())

        // Create JWT token
        const payload = {
            sub: userResponse.id,
            name: userResponse.name,
            email: userResponse.email,
            avatar: userResponse.avatar_url,
            provider: 'github'
        }

        const token = await jwt.sign(payload)

        return {
            token,
            user: payload
        }
    })
    .listen(3000)

// 5. API Key Authentication
const apiKeys = new Set(['key1', 'key2', 'key3'])

const apiKeyAuth = new Elysia({ name: 'api-key' })
    .onBeforeHandle({ as: 'global' }, ({ headers, set }) => {
        const apiKey = headers['x-api-key']

        if (!apiKey || !apiKeys.has(apiKey)) {
            set.status = 401
            return { error: 'Invalid API key' }
        }

        // You could also load rate limits based on the API key
        set.headers['X-API-Key-Valid'] = 'true'
    })

const app = new Elysia()
    .use(apiKeyAuth)
    .get('/api/data', () => ({ data: 'Protected by API key' }))
    .post('/api/process', () => ({ result: 'Processing complete' }))
    .listen(3000)

// 6. Session-based Authentication
const sessions = new Map<string, any>()

const sessionAuth = new Elysia({ name: 'session' })
    .derive({ as: 'global' }, ({ headers, cookie }) => {
        const sessionId = cookie?.sessionId || headers['x-session-id']

        const session = sessionId ? sessions.get(sessionId) : null

        const createSession = (userData: any): string => {
            const newSessionId = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
            sessions.set(newSessionId, {
                user: userData,
                createdAt: new Date(),
                lastAccessed: new Date()
            })
            return newSessionId
        }

        const destroySession = (sessionId: string): void => {
            sessions.delete(sessionId)
        }

        return { session, createSession, destroySession }
    })
    .guard({
        beforeHandle({ session, set }) {
            if (!session) {
                set.status = 401
                return { error: 'No valid session' }
            }
        }
    }, (app) => app
        .get('/dashboard', ({ session }) => ({
            user: session.user,
            message: 'Welcome to your dashboard'
        }))
        .post('/logout', ({ headers, cookie, destroySession }) => {
            const sessionId = cookie?.sessionId || headers['x-session-id']
            if (sessionId) {
                destroySession(sessionId)
            }
            return { message: 'Logged out successfully' }
        })
    )
    .post('/login', ({ body, createSession, cookie }) => {
        // Validate credentials
        if (body.username === 'user' && body.password === 'pass') {
            const sessionId = createSession({
                id: 1,
                name: 'John Doe',
                username: body.username
            })

            // Set session cookie
            cookie.sessionId.value = sessionId
            cookie.sessionId.httpOnly = true
            cookie.sessionId.maxAge = 3600

            return {
                success: true,
                sessionId,
                user: { id: 1, name: 'John Doe' }
            }
        }

        return { success: false, message: 'Invalid credentials' }
    })

const app = new Elysia()
    .use(sessionAuth)
    .listen(3000)

// 7. Refresh Token Pattern
const refreshTokens = new Map<string, any>()

const app = new Elysia()
    .use(
        jwt({
            name: 'accessJwt',
            secret: 'access-secret',
            exp: '1h' // Short-lived access token
        })
    )
    .use(
        jwt({
            name: 'refreshJwt',
            secret: 'refresh-secret',
            exp: '7d' // Long-lived refresh token
        })
    )
    .post('/auth/login', async ({ body, accessJwt, refreshJwt }) => {
        // Validate credentials
        if (body.username === 'admin' && body.password === 'password') {
            const user = {
                id: '1',
                name: 'Admin User',
                role: 'admin'
            }

            const accessToken = await accessJwt.sign({ user })
            const refreshToken = await refreshJwt.sign({ userId: user.id })

            // Store refresh token
            refreshTokens.set(refreshToken, {
                userId: user.id,
                createdAt: new Date()
            })

            return {
                accessToken,
                refreshToken,
                user
            }
        }

        throw new Error('Invalid credentials')
    })
    .post('/auth/refresh', async ({ body, accessJwt, refreshJwt }) => {
        const { refreshToken } = body

        // Validate refresh token
        const payload = await refreshJwt.verify(refreshToken)
        if (!payload || !refreshTokens.has(refreshToken)) {
            throw new Error('Invalid refresh token')
        }

        // Generate new access token
        const user = {
            id: payload.userId,
            name: 'User ' + payload.userId,
            role: 'user'
        }

        const accessToken = await accessJwt.sign({ user })

        return { accessToken }
    })
    .post('/auth/logout', ({ body }) => {
        const { refreshToken } = body
        refreshTokens.delete(refreshToken)
        return { message: 'Logged out successfully' }
    })
    .listen(3000)

// 8. Multi-factor Authentication (MFA)
const app = new Elysia()
    .state('mfa', {
        // In real app, use TOTP library
        generateMFACode: (userId: string) => {
            return Math.floor(100000 + Math.random() * 900000).toString()
        },
        verifyMFACode: (userId: string, code: string): boolean => {
            // Mock verification
            return code === '123456'
        }
    })
    .post('/auth/login-mfa', ({ body, store: { mfa } }) => {
        const { username, password } = body

        // Step 1: Validate username/password
        if (username === 'admin' && password === 'password') {
            const mfaCode = mfa.generateMFACode(username)
            // In real app, send MFA code via SMS/email
            console.log(`MFA Code for ${username}: ${mfaCode}`)

            return {
                requiresMFA: true,
                message: 'MFA code sent to your registered device'
            }
        }

        return { error: 'Invalid credentials' }
    })
    .post('/auth/verify-mfa', ({ body, store: { mfa }, jwt }) => {
        const { username, mfaCode } = body

        if (!mfa.verifyMFACode(username, mfaCode)) {
            return { error: 'Invalid MFA code' }
        }

        // Generate final authentication token
        return jwt.sign({
            sub: username,
            mfaVerified: true
        })
    })
    .listen(3000)

💻 GraphQL-Integration typescript

🟡 intermediate

GraphQL-Server und Abfrageverarbeitung

// Elysia.js GraphQL Examples

import { Elysia } from 'elysia'
import { gql } from '@elysiajs/graphql'
import { graphql } from '@elysiajs/graphql'

// 1. Basic GraphQL Server
const typeDefs = gql`
    type Query {
        hello: String
        user(id: ID!): User
        users: [User!]
    }

    type User {
        id: ID!
        name: String!
        email: String!
        createdAt: String!
    }

    type Mutation {
        createUser(name: String!, email: String!): User
        updateUser(id: ID!, name: String): User
        deleteUser(id: ID!): Boolean
    }
`

// Mock data
const users = [
    { id: '1', name: 'John Doe', email: '[email protected]', createdAt: '2024-01-01' },
    { id: '2', name: 'Jane Smith', email: '[email protected]', createdAt: '2024-01-02' }
]

const resolvers = {
    Query: {
        hello: () => 'Hello, GraphQL with Elysia!',
        user: (_: any, { id }: { id: string }) => users.find(u => u.id === id),
        users: () => users
    },
    Mutation: {
        createUser: (_: any, { name, email }: { name: string; email: string }) => {
            const newUser = {
                id: (users.length + 1).toString(),
                name,
                email,
                createdAt: new Date().toISOString()
            }
            users.push(newUser)
            return newUser
        },
        updateUser: (_: any, { id, name }: { id: string; name?: string }) => {
            const user = users.find(u => u.id === id)
            if (!user) return null
            if (name) user.name = name
            return user
        },
        deleteUser: (_: any, { id }: { id: string }) => {
            const index = users.findIndex(u => u.id === id)
            if (index === -1) return false
            users.splice(index, 1)
            return true
        }
    }
}

const app = new Elysia()
    .use(
        graphql({
            typeDefs,
            resolvers
        })
    )
    .listen(3000)

// 2. GraphQL with Context and Authentication
const app = new Elysia()
    .state('users', users)
    .derive({ as: 'global' }, ({ headers, store }) => {
        // Extract user from Authorization header
        const auth = headers.authorization
        let currentUser = null

        if (auth?.startsWith('Bearer ')) {
            const token = auth.slice(7)
            // Mock token validation
            currentUser = store.users.find((u: any) => u.id === token)
        }

        return { currentUser }
    })
    .use(
        graphql({
            typeDefs: gql`
                type Query {
                    me: User
                    users: [User!]
                    user(id: ID!): User
                }

                type User {
                    id: ID!
                    name: String!
                    email: String!
                    createdAt: String!
                }

                type Mutation {
                    updateProfile(name: String): User
                }
            `,
            resolvers: {
                Query: {
                    me: (_, __, { currentUser }) => currentUser,
                    users: (_, __, { store }) => store.users,
                    user: (_, { id }, { store }) =>
                        store.users.find((u: any) => u.id === id)
                },
                Mutation: {
                    updateProfile: (_, { name }, { currentUser, store }) => {
                        if (!currentUser) throw new Error('Unauthorized')
                        const user = store.users.find((u: any) => u.id === currentUser.id)
                        if (user && name) user.name = name
                        return user
                    }
                }
            }
        })
    )
    .listen(3000)

// 3. GraphQL Subscriptions
const app = new Elysia()
    .state('posts', [
        { id: '1', title: 'First Post', content: 'Hello, World!', author: 'Admin' }
    ])
    .derive({ as: 'global' }, ({ store }) => {
        const subscriptions = new Set<any>()

        return {
            subscriptions,
            notifyPostCreated(post: any) {
                subscriptions.forEach(ws => {
                    ws.send(JSON.stringify({
                        type: 'postCreated',
                        data: post
                    }))
                })
            }
        }
    })
    .use(graphql({
        typeDefs: gql`
            type Query {
                posts: [Post!]
                post(id: ID!): Post
            }

            type Mutation {
                createPost(title: String!, content: String!): Post
            }

            type Subscription {
                postCreated: Post!
            }

            type Post {
                id: ID!
                title: String!
                content: String!
                author: String!
                createdAt: String!
            }
        `,
        resolvers: {
            Query: {
                posts: (_, __, { store }) => store.posts,
                post: (_, { id }, { store }) =>
                    store.posts.find((p: any) => p.id === id)
            },
            Mutation: {
                createPost: (_, { title, content }, { store, notifyPostCreated }) => {
                    const newPost = {
                        id: (store.posts.length + 1).toString(),
                        title,
                        content,
                        author: 'Anonymous',
                        createdAt: new Date().toISOString()
                    }
                    store.posts.push(newPost)
                    notifyPostCreated(newPost)
                    return newPost
                }
            },
            Subscription: {
                postCreated: {
                    subscribe: (_, __, { subscriptions }) => {
                        const iterator = {
                            [Symbol.asyncIterator]() {
                                return this
                            },
                            async next() {
                                return { value: { postCreated: null }, done: false }
                            }
                        }
                        return iterator
                    }
                }
            }
        }
    }))
    .listen(3000)

// 4. GraphQL with DataLoader
import DataLoader from 'dataloader'

const app = new Elysia()
    .derive({ as: 'global' }, () => {
        // Create a DataLoader for batch user fetching
        const userLoader = new DataLoader(async (ids: string[]) => {
            console.log(`Batch loading users: ${ids.join(', ')}`)
            // Simulate database batch query
            return ids.map(id => users.find(u => u.id === id) || null)
        })

        return { userLoader }
    })
    .use(
        graphql({
            typeDefs: gql`
                type Query {
                    users(ids: [ID!]!): [User]
                    posts: [Post]
                }

                type User {
                    id: ID!
                    name: String!
                    email: String!
                }

                type Post {
                    id: ID!
                    title: String!
                    author: User
                    authorId: ID!
                }
            `,
            resolvers: {
                Query: {
                    users: (_, { ids }, { userLoader }) =>
                        userLoader.loadMany(ids),
                    posts: () => [
                        { id: '1', title: 'Post 1', authorId: '1' },
                        { id: '2', title: 'Post 2', authorId: '2' },
                        { id: '3', title: 'Post 3', authorId: '1' }
                    ]
                }
            },
            resolvers: {
                Post: {
                    author: (post, _, { userLoader }) =>
                        userLoader.load(post.authorId)
                }
            }
        })
    )
    .listen(3000)

// 5. GraphQL Schema Stitching
const userService = new Elysia()
    .use(
        graphql({
            typeDefs: gql`
                type Query {
                    user(id: ID!): User
                }

                type User {
                    id: ID!
                    name: String!
                    email: String!
                }
            `,
            resolvers: {
                Query: {
                    user: (_, { id }) => users.find(u => u.id === id)
                }
            }
        })
    )

const postService = new Elysia()
    .state('posts', [
        { id: '1', title: 'Post 1', authorId: '1' },
        { id: '2', title: 'Post 2', authorId: '2' }
    ])
    .use(
        graphql({
            typeDefs: gql`
                extend type Query {
                    posts: [Post!]
                }

                type Post {
                    id: ID!
                    title: String!
                    author: User
                }

                extend type User {
                    posts: [Post!]
                }
            `,
            resolvers: {
                Query: {
                    posts: (_, __, { store }) => store.posts
                },
                Post: {
                    author: (post) => ({ __typename: 'User', id: post.authorId })
                },
                User: {
                    posts: (user, _, { store }) =>
                        store.posts.filter((p: any) => p.authorId === user.id)
                }
            }
        })
    )

// 6. GraphQL Federation
const accountsService = new Elysia()
    .use(
        graphql({
            typeDefs: gql`
                type Query {
                    me: User
                }

                type User @key(fields: "id") {
                    id: ID!
                    name: String!
                }
            `,
            resolvers: {
                Query: {
                    me: () => ({ id: '1', name: 'John Doe' })
                },
                User: {
                    __resolveReference: (user) =>
                        users.find(u => u.id === user.id) || user
                }
            }
        })
    )

const postsService = new Elysia()
    .use(
        graphql({
            typeDefs: gql`
                extend type Query {
                    posts: [Post]
                }

                type Post {
                    id: ID!
                    title: String!
                    author: User
                }

                extend type User @key(fields: "id") {
                    id: ID! @external
                    posts: [Post]
                }
            `,
            resolvers: {
                Query: {
                    posts: () => [
                        { id: '1', title: 'Post 1', authorId: '1' },
                        { id: '2', title: 'Post 2', authorId: '1' }
                    ]
                },
                Post: {
                    author: (post) => ({ __typename: 'User', id: post.authorId })
                },
                User: {
                    posts: (user) => [
                        { id: '1', title: 'Post 1', authorId: user.id },
                        { id: '2', title: 'Post 2', authorId: user.id }
                    ]
                }
            }
        })
    )

// 7. GraphQL with Validation
import { z } from 'zod'

const CreateUserSchema = z.object({
    name: z.string().min(1),
    email: z.string().email()
})

const app = new Elysia()
    .use(
        graphql({
            typeDefs: gql`
                type Query {
                    users: [User!]
                }

                type Mutation {
                    createUser(input: CreateUserInput!): User!
                }

                type User {
                    id: ID!
                    name: String!
                    email: String!
                }

                input CreateUserInput {
                    name: String!
                    email: String!
                }
            `,
            resolvers: {
                Query: {
                    users: () => users
                },
                Mutation: {
                    createUser: (_, { input }) => {
                        // Validate input with Zod
                        const validatedInput = CreateUserSchema.parse(input)

                        const newUser = {
                            id: (users.length + 1).toString(),
                            ...validatedInput,
                            createdAt: new Date().toISOString()
                        }

                        users.push(newUser)
                        return newUser
                    }
                }
            }
        })
    )
    .listen(3000)

// 8. GraphQL Playground and Documentation
const app = new Elysia()
    .use(
        graphql({
            typeDefs,
            resolvers,
            playground: true, // Enable GraphQL Playground
            graphiql: true   // Enable GraphiQL interface
        })
    )
    .get('/', () => ({
        message: 'GraphQL Server',
        endpoints: {
            graphql: '/graphql',
            playground: '/graphql'
        }
    }))
    .listen(3000)

// 9. Custom Scalars
const app = new Elysia()
    .use(
        graphql({
            typeDefs: gql`
                scalar Date
                scalar Email

                type Query {
                    currentUser: User
                }

                type Mutation {
                    updateUser(birthday: Date, email: Email): User
                }

                type User {
                    id: ID!
                    name: String!
                    birthday: Date
                    email: Email
                }
            `,
            resolvers: {
                Date: {
                    serialize: (value: Date) => value.toISOString(),
                    parseValue: (value: string) => new Date(value),
                    parseLiteral: (ast: any) => new Date(ast.value)
                },
                Email: {
                    serialize: (value: string) => value,
                    parseValue: (value: string) => {
                        if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
                            throw new Error('Invalid email format')
                        }
                        return value
                    },
                    parseLiteral: (ast: any) => {
                        if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(ast.value)) {
                            throw new Error('Invalid email format')
                        }
                        return ast.value
                    }
                },
                Query: {
                    currentUser: () => ({
                        id: '1',
                        name: 'John Doe',
                        birthday: new Date('1990-01-01'),
                        email: '[email protected]'
                    })
                },
                Mutation: {
                    updateUser: (_, { birthday, email }) => ({
                        id: '1',
                        name: 'John Doe',
                        birthday,
                        email
                    })
                }
            }
        })
    )
    .listen(3000)

// 10. GraphQL Error Handling
const app = new Elysia()
    .use(
        graphql({
            typeDefs: gql`
                type Query {
                    user(id: ID!): User
                    throwError: String
                }

                type User {
                    id: ID!
                    name: String!
                }
            `,
            resolvers: {
                Query: {
                    user: (_, { id }) => {
                        const user = users.find(u => u.id === id)
                        if (!user) {
                            throw new GraphQLError('User not found', {
                                extensions: { code: 'USER_NOT_FOUND' }
                            })
                        }
                        return user
                    },
                    throwError: () => {
                        throw new GraphQLError('This is a test error', {
                            extensions: {
                                code: 'TEST_ERROR',
                                details: 'Additional error information'
                            }
                        })
                    }
                }
            },
            context: () => ({}),
            formatError: (error) => {
                console.error('GraphQL Error:', error)
                return {
                    message: error.message,
                    code: error.extensions?.code,
                    details: error.extensions?.details,
                    path: error.path,
                    locations: error.locations
                }
            }
        })
    )
    .listen(3000)

💻 Plugin-Entwicklung typescript

🔴 complex

Erstellung und Verwendung benutzerdefinierter Plugins

// Elysia.js Plugin Development Examples

import { Elysia } from 'elysia'

// 1. Basic custom plugin
const timestampPlugin = new Elysia({ name: 'timestamp' })
    .decorate('getTimestamp', () => new Date().toISOString())
    .onBeforeHandle({ as: 'global' }, ({ set, getTimestamp }) => {
        set.headers['X-Timestamp'] = getTimestamp()
    })

// Using the plugin
const app = new Elysia()
    .use(timestampPlugin)
    .get('/time', ({ getTimestamp }) => getTimestamp())
    .listen(3000)

// 2. Database plugin
interface Database {
    query: (sql: string, params?: any[]) => Promise<any[]>
    insert: (table: string, data: any) => Promise<any>
    update: (table: string, id: string, data: any) => Promise<any>
    delete: (table: string, id: string) => Promise<boolean>
}

const databasePlugin = new Elysia({ name: 'database' })
    .derive({ as: 'global' }, () => {
        // Mock database implementation
        const database: Database = {
            async query(sql: string, params: any[] = []) {
                console.log(`Query: ${sql}`, params)
                // Mock data
                return [{ id: 1, name: 'John', email: '[email protected]' }]
            },
            async insert(table: string, data: any) {
                console.log(`Insert into ${table}:`, data)
                return { id: Date.now(), ...data }
            },
            async update(table: string, id: string, data: any) {
                console.log(`Update ${table} ${id}:`, data)
                return { id, ...data }
            },
            async delete(table: string, id: string) {
                console.log(`Delete from ${table} where id=${id}`)
                return true
            }
        }

        return { database }
    })

// Using database plugin
const app = new Elysia()
    .use(databasePlugin)
    .get('/users', async ({ database }) => {
        const users = await database.query('SELECT * FROM users')
        return users
    })
    .post('/users', async ({ body, database }) => {
        const user = await database.insert('users', body)
        return user
    })
    .listen(3000)

// 3. Caching plugin
const cachePlugin = new Elysia({ name: 'cache' })
    .derive({ as: 'global' }, () => {
        const cache = new Map<string, { data: any; expiry: number }>()

        return {
            cache: {
                get(key: string) {
                    const item = cache.get(key)
                    if (!item || Date.now() > item.expiry) {
                        cache.delete(key)
                        return null
                    }
                    return item.data
                },
                set(key: string, data: any, ttl: number = 60000) {
                    cache.set(key, {
                        data,
                        expiry: Date.now() + ttl
                    })
                },
                clear() {
                    cache.clear()
                }
            }
        }
    })

const app = new Elysia()
    .use(cachePlugin)
    .get('/expensive', async ({ cache }) => {
        const cacheKey = 'expensive-data'
        let data = cache.get(cacheKey)

        if (!data) {
            // Simulate expensive operation
            await new Promise(resolve => setTimeout(resolve, 2000))
            data = { message: 'Expensive data', timestamp: Date.now() }
            cache.set(cacheKey, data, 10000) // Cache for 10 seconds
        }

        return data
    })
    .listen(3000)

// 4. Configuration plugin
interface AppConfig {
    database: {
        url: string
        maxConnections: number
    }
    auth: {
        jwtSecret: string
        expiresIn: string
    }
    server: {
        port: number
        host: string
    }
}

const configPlugin = new Elysia({ name: 'config' })
    .derive({ as: 'global' }, () => {
        const config: AppConfig = {
            database: {
                url: process.env.DB_URL || 'sqlite:app.db',
                maxConnections: parseInt(process.env.DB_MAX_CONN || '10')
            },
            auth: {
                jwtSecret: process.env.JWT_SECRET || 'default-secret',
                expiresIn: process.env.JWT_EXPIRES_IN || '1h'
            },
            server: {
                port: parseInt(process.env.PORT || '3000'),
                host: process.env.HOST || 'localhost'
            }
        }

        return { config }
    })

const app = new Elysia()
    .use(configPlugin)
    .get('/config', ({ config }) => config)
    .listen(3000)

// 5. Logging plugin
const loggerPlugin = new Elysia({ name: 'logger' })
    .derive({ as: 'global' }, () => {
        const logLevels = ['debug', 'info', 'warn', 'error'] as const

        const logger = {
            debug: (message: string, ...args: any[]) => {
                console.debug(`[DEBUG] ${new Date().toISOString()} - ${message}`, ...args)
            },
            info: (message: string, ...args: any[]) => {
                console.info(`[INFO] ${new Date().toISOString()} - ${message}`, ...args)
            },
            warn: (message: string, ...args: any[]) => {
                console.warn(`[WARN] ${new Date().toISOString()} - ${message}`, ...args)
            },
            error: (message: string, ...args: any[]) => {
                console.error(`[ERROR] ${new Date().toISOString()} - ${message}`, ...args)
            }
        }

        return { logger }
    })
    .onBeforeHandle({ as: 'global' }, ({ logger, request }) => {
        logger.info(`${request.method} ${request.url}`)
    })
    .onError({ as: 'global' }, ({ logger, error }) => {
        logger.error(error.message)
    })

const app = new Elysia()
    .use(loggerPlugin)
    .get('/logged', ({ logger }) => {
        logger.info('This is an info message')
        logger.warn('This is a warning')
        return 'Logged response'
    })
    .listen(3000)

// 6. Plugin with lifecycle
interface User {
    id: number
    name: string
    email: string
}

const userPlugin = new Elysia({ name: 'user' })
    .derive({ as: 'global' }, ({ headers }) => {
        const authHeader = headers.authorization

        // Extract user from JWT (simplified)
        const getUser = (): User | null => {
            if (!authHeader) return null

            // In real app, decode JWT here
            return {
                id: 1,
                name: 'John Doe',
                email: '[email protected]'
            }
        }

        return {
            getUser,
            requireAuth(): User {
                const user = getUser()
                if (!user) throw new Error('Unauthorized')
                return user
            }
        }
    })
    .onBeforeHandle({ as: 'global' }, ({ set, getUser }) => {
        const user = getUser()
        if (user) {
            set.headers['X-User-ID'] = user.id.toString()
        }
    })

const app = new Elysia()
    .use(userPlugin)
    .get('/profile', ({ getUser }) => {
        const user = getUser()
        return user || { message: 'Not authenticated' }
    })
    .get('/protected', ({ requireAuth }) => {
        const user = requireAuth()
        return `Welcome, ${user.name}!`
    })
    .listen(3000)

// 7. Plugin composition
const basePlugin = new Elysia({ name: 'base' })
    .decorate('baseMethod', () => 'Base functionality')
    .state('baseState', 'Base state')

const extendedPlugin = new Elysia({ name: 'extended' })
    .use(basePlugin)
    .decorate('extendedMethod', ({ baseMethod }) => `${baseMethod} + Extended`)
    .state('extendedState', 'Extended state')

const app = new Elysia()
    .use(extendedPlugin)
    .get('/composed', ({ baseMethod, extendedMethod, store: { baseState, extendedState } }) => ({
        baseMethod,
        extendedMethod,
        baseState,
        extendedState
    }))
    .listen(3000)

// 8. Plugin with options
interface RateLimitOptions {
    windowMs: number
    maxRequests: number
    message?: string
}

const rateLimitPlugin = (options: RateLimitOptions) => {
    const requests = new Map<string, { count: number; resetTime: number }>()

    return new Elysia({ name: 'rate-limit' })
        .onBeforeHandle({ as: 'global' }, ({ set, headers }) => {
            const key = headers['x-forwarded-for'] || 'default'
            const now = Date.now()

            const record = requests.get(key)

            if (!record || now > record.resetTime) {
                requests.set(key, { count: 1, resetTime: now + options.windowMs })
                return
            }

            if (record.count >= options.maxRequests) {
                set.status = 429
                return options.message || 'Too many requests'
            }

            record.count++
        })
}

const app = new Elysia()
    .use(rateLimitPlugin({ windowMs: 60000, maxRequests: 10, message: 'Rate limit exceeded' }))
    .get('/limited', () => 'Rate limited endpoint')
    .listen(3000)

// 9. Third-party plugin example (JWT)
// npm install @elysiajs/jwt
import { jwt } from '@elysiajs/jwt'

const app = new Elysia()
    .use(
        jwt({
            name: 'jwt',
            secret: process.env.JWT_SECRET || 'default-secret'
        })
    )
    .post('/login', async ({ body, jwt }) => {
        // Validate credentials (simplified)
        if (body.username === 'admin' && body.password === 'password') {
            const token = await jwt.sign({
                sub: 'user123',
                name: 'Admin User'
            })
            return { token }
        }

        throw new Error('Invalid credentials')
    })
    .get('/profile', async ({ jwt, headers }) => {
        const auth = headers.authorization
        if (!auth) throw new Error('No token provided')

        const token = auth.replace('Bearer ', '')
        const payload = await jwt.verify(token)

        return payload
    })
    .listen(3000)

// 10. Plugin with external dependencies
// npm install ioredis
import Redis from 'ioredis'

const redisPlugin = new Elysia({ name: 'redis' })
    .derive({ as: 'global' }, async () => {
        const redis = new Redis({
            host: process.env.REDIS_HOST || 'localhost',
            port: parseInt(process.env.REDIS_PORT || '6379')
        })

        return {
            redis: {
                async get(key: string): Promise<string | null> {
                    return await redis.get(key)
                },
                async set(key: string, value: string, ttl?: number): Promise<void> {
                    if (ttl) {
                        await redis.setex(key, ttl, value)
                    } else {
                        await redis.set(key, value)
                    }
                },
                async del(key: string): Promise<boolean> {
                    const result = await redis.del(key)
                    return result > 0
                }
            }
        }
    })

const app = new Elysia()
    .use(redisPlugin)
    .post('/cache/:key', async ({ params: { key }, body, redis }) => {
        await redis.set(key, JSON.stringify(body), 3600)
        return { cached: true, key }
    })
    .get('/cache/:key', async ({ params: { key }, redis }) => {
        const value = await redis.get(key)
        return value ? JSON.parse(value) : null
    })
    .listen(3000)