Examples
Practical, real-world examples showing how to use vite-plugin-universal-api in different scenarios.
Overview
Browse through these examples to learn common patterns and best practices:
File-Based Mocking
- Simple File-Based API - Basic JSON file serving
- Static mock data for rapid prototyping
REST API Examples
- Custom Handlers - Dynamic REST endpoints
- Stateful Server - In-memory database
- Authentication - JWT-based auth
WebSocket Examples
- WebSocket Chat - Real-time chat with rooms
- WebSocket Game - Multiplayer game server
Quick Examples
1. File-Based API
Serve JSON files directly:
typescript
// vite.config.ts
// import mockApi from '@ndriadev/vite-plugin-universal-api' //Default export
import { universalApi } from '@ndriadev/vite-plugin-universal-api' // Named export
export default {
plugins: [
universalApi({
endpointPrefix: '/api',
fsDir: 'mock'
})
]
}json
// mock/users.json → GET /api/users
[
{"id": 1, "name": "Alice"},
{"id": 2, "name": "Bob"}
]2. REST Handler
Custom endpoint with logic:
typescript
universalApi({
handlers: [
{
pattern: '/users/{id}',
method: 'GET',
handle: async (req, res) => {
const user = await db.findUser(req.params.id)
res.writeHead(200, { 'Content-Type': 'application/json' })
res.end(JSON.stringify(user))
}
}
]
})3. WebSocket Chat
Real-time messaging:
typescript
universalApi({
enableWs: true,
wsHandlers: [
{
pattern: '/ws/chat',
onMessage: (conn, msg) => {
conn.broadcast(msg, { includeSelf: true })
}
}
]
})Browse All Examples
Click on any example below to see the complete implementation:
📁 File-Based
- Basic File Serving
- Pagination & Filtering
- Directory Structure
🔄 REST APIs
⚡ WebSocket
- Chat Application
- Game Server
- Rooms & Broadcasting
Example Project Structure
Typical project layout using all three approaches:
my-app/
├── mock/ # File-based API
│ ├── users.json # GET /api/users
│ ├── posts/
│ │ └── index.json # GET /api/posts
│ └── products/
│ ├── 1.json # GET /api/products/1
│ └── 2.json # GET /api/products/2
│
├── src/
│ ├── main.ts
│ └── api/
│ ├── users.ts # Fetch from /api/users
│ └── websocket.ts # Connect to WebSocket
│
└── vite.config.ts # Plugin configurationCommon Use Cases
Development Workflow
typescript
universalApi({
endpointPrefix: '/api',
fsDir: 'mock',
logLevel: 'debug', // See all requests
delay: 500, // Simulate network latency
handlers: [
// Override specific endpoints
{
pattern: '/users/me',
method: 'GET',
handle: (req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' })
res.end(JSON.stringify({
id: 1,
name: 'Dev User',
role: 'admin'
}))
}
}
]
})Testing Edge Cases
typescript
universalApi({
handlers: [
// Simulate errors
{
pattern: '/api/error',
method: 'GET',
handle: (req, res) => {
res.writeHead(500)
res.end('Internal Server Error')
}
},
// Simulate slow responses
{
pattern: '/api/slow',
method: 'GET',
delay: 5000,
handle: (req, res) => {
res.writeHead(200)
res.end('Finally!')
}
},
// Simulate timeout
{
pattern: '/api/timeout',
method: 'GET',
delay: 35000, // Exceeds gatewayTimeout
handle: (req, res) => {
// Will timeout before this executes
}
}
]
})Prototyping New Features
typescript
universalApi({
fsDir: 'mock',
handlers: [
// New feature being developed
{
pattern: '/beta/feature',
method: 'POST',
handle: async (req, res) => {
// Test new endpoint before backend is ready
const result = await processNewFeature(req.body)
res.writeHead(200, { 'Content-Type': 'application/json' })
res.end(JSON.stringify(result))
}
}
],
// Real-time updates for new feature
enableWs: true,
wsHandlers: [
{
pattern: '/ws/beta',
onMessage: (conn, data) => {
conn.broadcast({ type: 'beta-update', data })
}
}
]
})Integration Examples
With React
tsx
// src/hooks/useWebSocket.ts
import { useEffect, useState } from 'react'
export function useWebSocket(url: string) {
const [ws, setWs] = useState<WebSocket | null>(null)
const [messages, setMessages] = useState<any[]>([])
useEffect(() => {
const socket = new WebSocket(url)
socket.onmessage = (event) => {
const data = JSON.parse(event.data)
setMessages(prev => [...prev, data])
}
setWs(socket)
return () => socket.close()
}, [url])
const send = (data: any) => {
ws?.send(JSON.stringify(data))
}
return { messages, send }
}
// In component
function ChatComponent() {
const { messages, send } = useWebSocket('ws://localhost:5173/api/ws/chat')
return (
<div>
{messages.map((msg, i) => (
<div key={i}>{msg.text}</div>
))}
<button onClick={() => send({ text: 'Hello!' })}>
Send
</button>
</div>
)
}With Vue
vue
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
const messages = ref<any[]>([])
let ws: WebSocket | null = null
onMounted(() => {
ws = new WebSocket('ws://localhost:5173/api/ws/chat')
ws.onmessage = (event) => {
messages.value.push(JSON.parse(event.data))
}
})
onUnmounted(() => {
ws?.close()
})
function sendMessage(text: string) {
ws?.send(JSON.stringify({ text }))
}
</script>
<template>
<div>
<div v-for="(msg, i) in messages" :key="i">
{{ msg.text }}
</div>
<button @click="sendMessage('Hello!')">Send</button>
</div>
</template>Next Steps
Ready to build? Pick an example that matches your use case:
- Starting simple? → File-Based API
- Need custom logic? → Custom Handlers
- Building chat/notifications? → WebSocket Chat
- Need authentication? → Authentication
- Want full CRUD? → Stateful Server
