## ⚡ fuapi - Type-Safe Full-Stack API Framework

> fuapi is an API framework designed specifically for TypeScript full-stack development, providing end-to-end type safety

### 🎯 Core Concepts

- **Unified API Definition** - Define once, share between frontend and backend
- **Type Safety** - Runtime type validation based on Zod schemas
- **Automatic Inference** - Automatic type inference for both client and server, no manual typing needed
- **Standardized Communication** - Uses POST method consistently for all data transmission

### 📝 API Definition Patterns

#### 1. Return-Only API (RetAPI)

```typescript
export const getHealthApi = defineAPI({
    path: '/health',
    voSchema: z.object({
        status: z.string(),
        uptime: z.number(),
        timestamp: z.string(),
    }),
})
```

#### 2. Input-Only API (ArgAPI)

```typescript
export const createUserApi = defineAPI({
    path: '/user/create',
    dtoSchema: z.object({
        name: z.string(),
        email: z.string(),
    }),
})
```

#### 3. Full Interaction API (StdAPI)

```typescript
export const getUserApi = defineAPI({
    path: '/user/get',
    dtoSchema: z.object({
        id: z.string(),
    }),
    voSchema: z.object({
        id: z.string(),
        name: z.string(),
        email: z.string(),
    }),
})
```

#### 4. No Parameters API (PlainAPI)

```typescript
export const healthCheckApi = defineAPI({
    path: '/health',
})
```

### 🖥️ Backend Implementation (implApi)

```typescript
// packages/server/src/api/user.ts
import {
    getUserApi,
    createUserApi,
    getHealthApi,
} from '@quickest/apis'
import { implApi } from 'fuapi'

export function setupUserApis(app: Express) {
    // Get user information
    implApi({
        express: app,
        api: getUserApi,
        handler: async ({ dto }) => {
            const { id } = dto // All parameters passed through dto
            // Return type automatically inferred as z.output<getUserApi.voSchema>
            return {
                id,
                name: 'John Doe',
                email: 'john@example.com',
            }
        },
        onError: (err) => {
            console.error('API Error:', err)
        },
    })

    // Create user
    implApi({
        express: app,
        api: createUserApi,
        handler: async ({ dto }) => {
            // dto type automatically inferred as { name: string; email: string }
            const user = await createUser(dto)
            // No return value (void)
        },
    })

    // Health check (no parameters)
    implApi({
        express: app,
        api: getHealthApi,
        handler: async ({ dto }) => {
            // dto is void, no parameters
            return {
                status: 'OK',
                uptime: process.uptime(),
                timestamp: new Date().toISOString(),
            }
        },
    })
}
```

### 🎨 Frontend Usage (clientOfAPI)

```typescript
// packages/web-app/src/apis/user.ts
import { getUserApi, createUserApi, getHealthApi } from '@quickest/apis'
import { clientOfAPI } from 'fuapi'

// Create clients
export const getUserClient = clientOfAPI({
    api: getUserApi,
    axios: axiosInstance,
    onError: async (err) => {
        console.error('Request failed:', err)
    }
})

export const createUserClient = clientOfAPI({
    api: createUserApi,
    axios: axiosInstance
})

export const getHealthClient = clientOfAPI({
    api: getHealthApi,
    axios: axiosInstance
})

// Usage in React components
function UserProfile({ userId }: { userId: string }) {
    const [user, setUser] = useState(null)
    const [health, setHealth] = useState(null)

    useEffect(() => {
        // All parameters passed through dto
        getUserClient({ id: userId }).then(setUser)

        // No parameter API call
        getHealthClient().then(setHealth)

        // Create user
        createUserClient({
            name: "Jane",
            email: "jane@example.com"
        })
    }, [userId])

    return (
        <div>
            <div>User: {user?.name}</div>
            <div>Service Status: {health?.status}</div>
        </div>
    )
}
```

### 🔧 Advanced Usage

#### Parameter Passing

```typescript
// fuapi doesn't support path parameters, all parameters must be passed through dto
export const getUserPostsApi = defineAPI({
    path: '/user/posts', // Clean path
    dtoSchema: z.object({
        userId: z.string(),
        postId: z.string().optional(),
        limit: z.number().optional(),
    }),
    voSchema: z.object({
        posts: z.array(
            z.object({
                id: z.string(),
                title: z.string(),
            })
        ),
    }),
})
```

#### Error Handling

```typescript
// Backend unified error handling
implApi({
    api: myApi,
    handler: async ({ dto }) => {
        throw new Error('Something went wrong') // Will be caught by onError
    },
    onError: (err) => {
        logger.error(err)
        // Can return custom error response
    },
})

// Frontend error handling
const client = clientOfAPI({
    api: myApi,
    axios: axiosInstance,
    onError: async (err) => {
        // Handle network errors, validation errors, etc.
        showNotification('Request failed')
    },
})
```

#### Request Configuration

```typescript
const client = clientOfAPI({
    api: myApi,
    axios: axiosInstance,
    requestConfig: {
        timeout: 5000,
        headers: { 'Custom-Header': 'value' },
    },
})
```

### 🎯 Type Safety Benefits

1. **Compile-time Checking** - Frontend and backend errors synchronously when API interface changes
2. **Auto-completion** - IDE provides complete parameter and return value suggestions
3. **Runtime Validation** - Zod ensures data format correctness
4. **Refactoring Friendly** - Frontend and backend update together when renaming fields
