|
| 1 | +--- |
| 2 | +description: |
| 3 | +globs: |
| 4 | +alwaysApply: false |
| 5 | +--- |
| 6 | + |
| 7 | + |
| 8 | +## Directory Structure |
| 9 | +``` |
| 10 | +api-clients/ |
| 11 | +├── _common/ |
| 12 | +│ ├── composables/ |
| 13 | +│ │ └── use-api-query-key.ts |
| 14 | +│ └── schema/ |
| 15 | +│ ├── api-verbs/ |
| 16 | +│ └── model.ts |
| 17 | +└── {service-name}/ |
| 18 | + ├── {resource}/ |
| 19 | + │ ├── composables/ |
| 20 | + │ │ └── use-{resource}-api.ts |
| 21 | + │ └── schema/ |
| 22 | + │ ├── api-verbs/ |
| 23 | + │ │ ├── {verb}.ts |
| 24 | + │ └── model.ts |
| 25 | + └── index.ts |
| 26 | +``` |
| 27 | + |
| 28 | +## API Client Composable Template |
| 29 | +```typescript |
| 30 | +// use-{resource}-api.ts template |
| 31 | +import { SpaceConnector } from '@cloudforet/core-lib/space-connector'; |
| 32 | + |
| 33 | +import { useAPIQueryKey } from '@/api-clients/_common/composables/use-api-query-key'; |
| 34 | +import type { ListResponse } from '@/api-clients/_common/schema/api-verbs/list'; |
| 35 | +import type { {Resource}CreateParameters } from '@/api-clients/{service}/{resource}/schema/api-verbs/create'; |
| 36 | +import type { {Resource}Model } from '@/api-clients/{service}/{resource}/schema/model'; |
| 37 | + |
| 38 | +export const use{Resource}Api = () => { |
| 39 | + // Define API actions |
| 40 | + const actions = { |
| 41 | + create: SpaceConnector.clientV2.{service}.{resource}.create<{Resource}CreateParameters, {Resource}Model>, |
| 42 | + list: SpaceConnector.clientV2.{service}.{resource}.list<{Resource}ListParameters, ListResponse<{Resource}Model>>, |
| 43 | + // ... other actions |
| 44 | + }; |
| 45 | + |
| 46 | + return { |
| 47 | + {resource}QueryKey, |
| 48 | + {resource}ListQueryKey, |
| 49 | + {resource}API: actions, |
| 50 | + }; |
| 51 | +}; |
| 52 | +``` |
| 53 | + |
| 54 | +## Schema Templates |
| 55 | + |
| 56 | +### Model Definition |
| 57 | +```typescript |
| 58 | +// model.ts template |
| 59 | +export interface {Resource}Model { |
| 60 | + // Define resource properties |
| 61 | + resource_id: string; |
| 62 | + name: string; |
| 63 | + // ... other properties |
| 64 | +} |
| 65 | +``` |
| 66 | + |
| 67 | +### API Verb Parameters |
| 68 | +```typescript |
| 69 | +// create.ts template |
| 70 | +export interface {Resource}CreateParameters { |
| 71 | + // Define create operation parameters |
| 72 | + name: string; |
| 73 | + // ... other parameters |
| 74 | +} |
| 75 | + |
| 76 | +// list.ts template |
| 77 | +export interface {Resource}ListParameters { |
| 78 | + query?: { |
| 79 | + filter?: Array<{ |
| 80 | + k: string; |
| 81 | + v: any; |
| 82 | + o: string; |
| 83 | + }>; |
| 84 | + // ... other query parameters |
| 85 | + }; |
| 86 | +} |
| 87 | +``` |
| 88 | + |
| 89 | +## Usage Rules |
| 90 | + |
| 91 | +1. **Naming Conventions** |
| 92 | + - Use PascalCase for interface names: `{Resource}Model`, `{Resource}{Verb}Parameters` |
| 93 | + - Use camelCase for variables and functions: `use{Resource}Api` |
| 94 | + - Follow existing naming patterns in the codebase |
| 95 | + |
| 96 | +2. **Type Safety** |
| 97 | + - Always define proper TypeScript interfaces for all parameters and responses |
| 98 | + - Use generics with SpaceConnector client methods |
| 99 | + - Define all possible API parameters in schema files |
| 100 | + |
| 101 | +3. **Query Key Management** |
| 102 | + - Use `useAPIQueryKey` for generating consistent query keys |
| 103 | + - Create separate query keys for different operations |
| 104 | + - Include contextual information in query keys when needed |
| 105 | + |
| 106 | +4. **Code Organization** |
| 107 | + - Keep schema definitions separate from API logic |
| 108 | + - Group related files in appropriate directories |
| 109 | + - Follow the established directory structure |
| 110 | + |
| 111 | +5. **Documentation** |
| 112 | + - Add JSDoc comments for public interfaces and functions |
| 113 | + - Document any special behaviors or requirements |
| 114 | + - Include examples for complex parameter structures |
| 115 | + |
| 116 | +## Example Usage in Components |
| 117 | +```typescript |
| 118 | +const { {resource}API } = use{Resource}Api(); |
| 119 | + |
| 120 | +const { key, params } = useServiceKey(service, resource, verb, { |
| 121 | + params: ... |
| 122 | +}) |
| 123 | + |
| 124 | +// In composables |
| 125 | +const query = useScopedQuery({ |
| 126 | + queryKey: {resource}QueryKey.value, |
| 127 | + queryFn: () => {resource}API.{verb}(params.value), |
| 128 | + // ... other options |
| 129 | +}, ['WORKSPACE', 'ADMIN']); |
| 130 | +``` |
| 131 | + |
| 132 | +## Notes |
| 133 | +- Always check existing API clients for consistent patterns |
| 134 | +- Consider reusability and maintainability |
| 135 | +- Follow the service's API documentation for accurate parameter definitions |
| 136 | +- Use appropriate error handling and loading states |
| 137 | +- Consider implementing proper caching strategies |
| 138 | +- Add comments only when it is really complex. (English only) |
| 139 | + |
| 140 | + |
0 commit comments