# DataApi in Renderer
This guide covers how to use the DataApi system in React components and the renderer process.
## React Hooks
### useQuery (GET Requests)
Fetch data with automatic caching and revalidation via SWR.
```typescript
import { useQuery } from '@data/hooks/useDataApi'
// Basic usage
const { data, loading, error } = useQuery('/topics')
// With query parameters
const { data: messages } = useQuery('/messages', {
query: { topicId: 'abc123', page: 1, limit: 20 }
})
// With path parameters (inferred from path)
const { data: topic } = useQuery('/topics/abc123')
// Conditional fetching
const { data } = useQuery(topicId ? `/topics/${topicId}` : null)
// With refresh callback
const { data, mutate } = useQuery('/topics')
// Refresh data
await mutate()
```
### useMutation (POST/PUT/PATCH/DELETE)
Perform data modifications with loading states.
```typescript
import { useMutation } from '@data/hooks/useDataApi'
// Create (POST)
const { trigger: createTopic, isMutating } = useMutation('/topics', 'POST')
const newTopic = await createTopic({ body: { name: 'New Topic' } })
// Update (PUT - full replacement)
const { trigger: replaceTopic } = useMutation('/topics/abc123', 'PUT')
await replaceTopic({ body: { name: 'Updated Name', description: '...' } })
// Partial Update (PATCH)
const { trigger: updateTopic } = useMutation('/topics/abc123', 'PATCH')
await updateTopic({ body: { name: 'New Name' } })
// Delete
const { trigger: deleteTopic } = useMutation('/topics/abc123', 'DELETE')
await deleteTopic()
```
## DataApiService Direct Usage
For non-React code or more control.
```typescript
import { dataApiService } from '@data/DataApiService'
// GET request
const topics = await dataApiService.get('/topics')
const topic = await dataApiService.get('/topics/abc123')
const messages = await dataApiService.get('/topics/abc123/messages', {
query: { page: 1, limit: 20 }
})
// POST request
const newTopic = await dataApiService.post('/topics', {
body: { name: 'New Topic' }
})
// PUT request (full replacement)
const updatedTopic = await dataApiService.put('/topics/abc123', {
body: { name: 'Updated', description: 'Full update' }
})
// PATCH request (partial update)
const patchedTopic = await dataApiService.patch('/topics/abc123', {
body: { name: 'Just update name' }
})
// DELETE request
await dataApiService.delete('/topics/abc123')
```
## Error Handling
### With Hooks
```typescript
function TopicList() {
const { data, loading, error } = useQuery('/topics')
if (loading) return
}
```
### With Try-Catch
```typescript
import { DataApiError, ErrorCode } from '@shared/data/api'
try {
await dataApiService.post('/topics', { body: data })
} catch (error) {
if (error instanceof DataApiError) {
switch (error.code) {
case ErrorCode.VALIDATION_ERROR:
// Handle validation errors
const fieldErrors = error.details?.fieldErrors
break
case ErrorCode.NOT_FOUND:
// Handle not found
break
case ErrorCode.CONFLICT:
// Handle conflict
break
default:
// Handle other errors
}
}
}
```
### Retryable Errors
```typescript
if (error instanceof DataApiError && error.isRetryable) {
// Safe to retry: SERVICE_UNAVAILABLE, TIMEOUT, etc.
await retry(operation)
}
```
## Common Patterns
### List with Pagination
```typescript
function TopicListWithPagination() {
const [page, setPage] = useState(1)
const { data, loading } = useQuery('/topics', {
query: { page, limit: 20 }
})
return (
<>