Add type-safe API client with utility functions
Introduce a type-safe API client using OpenAPI types for ALHP. Implement utility functions `getPackages` and `getStats` for common API usage, and add comprehensive documentation with examples for ease of integration.
This commit is contained in:
106
frontend/src/api/README.md
Normal file
106
frontend/src/api/README.md
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
# ALHP API Client
|
||||||
|
|
||||||
|
This directory contains a type-safe API client for the ALHP API, generated from the OpenAPI specification.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Importing
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Import the API client and its functions
|
||||||
|
import { apiClient, getPackages, getStats } from '@/api';
|
||||||
|
|
||||||
|
// Import types
|
||||||
|
import type { components } from '@/api';
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fetching Packages
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { getPackages } from '@/api';
|
||||||
|
import type { components } from '@/api';
|
||||||
|
|
||||||
|
// Example: Get packages with filtering
|
||||||
|
async function fetchPackages() {
|
||||||
|
try {
|
||||||
|
const result = await getPackages({
|
||||||
|
status: ['latest', 'building'],
|
||||||
|
pkgbase: 'linux',
|
||||||
|
exact: false,
|
||||||
|
repo: 'core-x86-64-v3',
|
||||||
|
offset: 0,
|
||||||
|
limit: 50
|
||||||
|
});
|
||||||
|
|
||||||
|
// Access the packages
|
||||||
|
const packages: components['schemas']['Package'][] = result.packages || [];
|
||||||
|
const total: number = result.total || 0;
|
||||||
|
|
||||||
|
return { packages, total };
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch packages:', error);
|
||||||
|
return { packages: [], total: 0 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fetching Stats
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { getStats } from '@/api';
|
||||||
|
import type { components } from '@/api';
|
||||||
|
|
||||||
|
// Example: Get build statistics
|
||||||
|
async function fetchStats() {
|
||||||
|
try {
|
||||||
|
const stats = await getStats();
|
||||||
|
|
||||||
|
// Access the stats
|
||||||
|
const failedCount: number = stats.failed || 0;
|
||||||
|
const ltoEnabled: number = stats.lto?.enabled || 0;
|
||||||
|
|
||||||
|
return stats;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch stats:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using the Raw API Client
|
||||||
|
|
||||||
|
If you need more control or want to use endpoints not covered by the utility functions, you can use the raw API client:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { apiClient } from '@/api';
|
||||||
|
|
||||||
|
// Example: Custom API call
|
||||||
|
async function customApiCall() {
|
||||||
|
const { data, error } = await apiClient.GET('/packages', {
|
||||||
|
params: {
|
||||||
|
query: {
|
||||||
|
// Your custom parameters
|
||||||
|
status: ['latest'],
|
||||||
|
limit: 10,
|
||||||
|
offset: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
console.error('API error:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Types
|
||||||
|
|
||||||
|
The API client uses types generated from the OpenAPI specification. The main types are:
|
||||||
|
|
||||||
|
- `components['schemas']['Package']`: Type for package data
|
||||||
|
- `components['schemas']['Stats']`: Type for statistics data
|
||||||
|
|
||||||
|
These types provide full TypeScript intellisense and type checking.
|
59
frontend/src/api/client.ts
Normal file
59
frontend/src/api/client.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import createFetch from 'openapi-fetch'
|
||||||
|
import type { paths } from '@/generated/alhp'
|
||||||
|
|
||||||
|
// Create a type-safe API client using the OpenAPI types
|
||||||
|
const apiClient = createFetch<paths>({
|
||||||
|
baseUrl: import.meta.env.VITE_BASE_URL
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get packages with optional filtering
|
||||||
|
* @param params Query parameters for filtering packages
|
||||||
|
* @returns Promise with the packages response
|
||||||
|
*/
|
||||||
|
export const getPackages = async (params: {
|
||||||
|
status?: Array<
|
||||||
|
| 'latest'
|
||||||
|
| 'failed'
|
||||||
|
| 'built'
|
||||||
|
| 'skipped'
|
||||||
|
| 'delayed'
|
||||||
|
| 'building'
|
||||||
|
| 'signing'
|
||||||
|
| 'unknown'
|
||||||
|
| 'queued'
|
||||||
|
>
|
||||||
|
pkgbase?: string
|
||||||
|
exact?: boolean
|
||||||
|
repo?: string
|
||||||
|
offset: number
|
||||||
|
limit: number
|
||||||
|
}) => {
|
||||||
|
const { data, error } = await apiClient.GET('/packages', {
|
||||||
|
params: {
|
||||||
|
query: params
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw new Error(`Failed to fetch packages: ${(error as any).statusCode}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get build statistics
|
||||||
|
* @returns Promise with the stats response
|
||||||
|
*/
|
||||||
|
export const getStats = async () => {
|
||||||
|
const { data, error } = await apiClient.GET('/stats')
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw new Error(`Failed to fetch stats: ${(error as any).statusCode || 'unknown error'}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
export default apiClient
|
6
frontend/src/api/index.ts
Normal file
6
frontend/src/api/index.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
// Export the API client and its functions
|
||||||
|
export { default as apiClient } from './client';
|
||||||
|
export { getPackages, getStats } from './client';
|
||||||
|
|
||||||
|
// Export types from the generated OpenAPI file
|
||||||
|
export type { components } from '../generated/alhp';
|
Reference in New Issue
Block a user