95 lines
2.3 KiB
Markdown
95 lines
2.3 KiB
Markdown
|
|
# Veza API Frontend Integration Guide
|
||
|
|
|
||
|
|
## 1. Introduction
|
||
|
|
This guide provides instructions for consuming the Veza Backend API in frontend applications (React, Vue, etc.).
|
||
|
|
|
||
|
|
## 2. API Client Setup
|
||
|
|
We recommend creating a typed API client.
|
||
|
|
|
||
|
|
### 2.1. TypeScript Interfaces
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// Base Response Envelope
|
||
|
|
export interface APIResponse<T> {
|
||
|
|
success: boolean;
|
||
|
|
data: T | null;
|
||
|
|
error: APIError | null;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Error Structure
|
||
|
|
export interface APIError {
|
||
|
|
code: number;
|
||
|
|
message: string;
|
||
|
|
details?: ValidationErrorDetail[] | null;
|
||
|
|
request_id?: string;
|
||
|
|
timestamp?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface ValidationErrorDetail {
|
||
|
|
field: string;
|
||
|
|
message: string;
|
||
|
|
value?: string;
|
||
|
|
tag?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Pagination
|
||
|
|
export interface PaginatedList<T> {
|
||
|
|
list: T[];
|
||
|
|
pagination: {
|
||
|
|
page: number;
|
||
|
|
limit: number;
|
||
|
|
total: number;
|
||
|
|
has_next: boolean;
|
||
|
|
};
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 3. Making Requests
|
||
|
|
|
||
|
|
### 3.1. Fetch Wrapper Example
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
async function apiRequest<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
|
||
|
|
const token = localStorage.getItem('access_token');
|
||
|
|
const headers = {
|
||
|
|
'Content-Type': 'application/json',
|
||
|
|
...(token ? { 'Authorization': `Bearer ${token}` } : {}),
|
||
|
|
...options.headers,
|
||
|
|
};
|
||
|
|
|
||
|
|
const response = await fetch(\`/api/v1${endpoint}\`, { ...options, headers });
|
||
|
|
const result: APIResponse<T> = await response.json();
|
||
|
|
|
||
|
|
if (!result.success) {
|
||
|
|
// Handle API Error
|
||
|
|
console.error('API Error:', result.error);
|
||
|
|
throw new Error(result.error?.message || 'Unknown API Error');
|
||
|
|
}
|
||
|
|
|
||
|
|
// Return the data payload directly
|
||
|
|
return result.data as T;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 4. Handling Validation Errors
|
||
|
|
When a `400 Bad Request` or `422 Unprocessable Entity` occurs:
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
try {
|
||
|
|
await apiRequest('/auth/login', { method: 'POST', body: JSON.stringify(creds) });
|
||
|
|
} catch (error) {
|
||
|
|
// If error has details, map them to form fields
|
||
|
|
const apiError = error as APIError; // You might need to adjust error throwing logic
|
||
|
|
if (apiError.details) {
|
||
|
|
apiError.details.forEach(detail => {
|
||
|
|
setFieldError(detail.field, detail.message);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 5. Resources & Endpoints (Swagger)
|
||
|
|
For a full list of endpoints, request/response bodies, please refer to the OpenAPI Specification:
|
||
|
|
- Local URL: `http://localhost:8080/swagger/index.html`
|
||
|
|
- File: `docs/swagger.json`
|