-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbasic.ts
More file actions
127 lines (113 loc) · 3.01 KB
/
basic.ts
File metadata and controls
127 lines (113 loc) · 3.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/**
* Basic Example - Simple User Creation API
*
* This example demonstrates the core features:
* - Creating an endpoint with validation
* - Request/response schemas with Zod
* - Custom validation errors
* - Automatic Swagger documentation
*
* Run with: npx tsx examples/basic.ts
*/
import { APIServer, ValidationError, z } from '../src/index'
// In-memory data store
const users: Array<{
id: string
name: string
email: string
age?: number
createdAt: string
}> = []
// Create API server
const app = new APIServer({
port: 3000,
apiTitle: 'User API Example',
apiDescription: 'Basic example API built with @bitfocusas/api',
apiTags: [{ name: 'Users', description: 'User management endpoints' }],
})
// Define schemas with .describe() for better OpenAPI documentation
const CreateUserBody = z.object({
name: z
.string()
.min(1, 'Name is required')
.max(100, 'Name must be less than 100 characters')
.describe('Full name of the user'),
email: z.string().email('Invalid email address').describe('Email address (must be unique)'),
age: z.number().int().positive('Age must be a positive number').optional().describe('Age in years (optional)'),
})
const UserResponse = z.object({
id: z.string().describe('Unique user identifier (UUID)'),
name: z.string().describe('Full name of the user'),
email: z.string().describe('Email address'),
age: z.number().optional().describe('Age in years'),
createdAt: z.string().describe('ISO 8601 timestamp of when the user was created'),
})
// Create user endpoint
app.createEndpoint({
method: 'POST',
url: '/users',
body: CreateUserBody,
response: UserResponse,
config: {
description: 'Create a new user',
tags: ['Users'],
summary: 'Create user',
},
handler: async (request) => {
const { name, email, age } = request.body
// Check if email already exists
const existingUser = users.find((u) => u.email === email)
if (existingUser) {
throw new ValidationError([
{
field: 'body.email',
message: 'User with this email already exists',
},
])
}
// Create new user
const newUser = {
id: crypto.randomUUID(),
name,
email,
age,
createdAt: new Date().toISOString(),
}
users.push(newUser)
return newUser
},
})
// Get all users endpoint
app.createEndpoint({
method: 'GET',
url: '/users',
response: z.object({
users: z.array(UserResponse),
total: z.number(),
}),
config: {
description: 'Get all users',
tags: ['Users'],
summary: 'List users',
},
handler: async () => {
return {
users,
total: users.length,
}
},
})
// Setup graceful shutdown
app.setupGracefulShutdown()
// Start the server
;(async () => {
await app.start()
console.log('\n✅ Basic example server is running!')
console.log('\n💡 Try these commands:')
console.log(' # Create a user')
console.log(
' curl -X POST http://localhost:3000/users -H "Content-Type: application/json" -d \'{"name":"John Doe","email":"john@example.com","age":30}\'',
)
console.log('\n # Get all users')
console.log(' curl http://localhost:3000/users')
})()