api-guide
Guide for implementing REST and GraphQL APIs (create, get, search, update, delete, purge, scope prefix patterns, admin_ prefix, SearchScope, BaseFilterAdapter, @api_function, Click CLI)
Best use case
api-guide is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Guide for implementing REST and GraphQL APIs (create, get, search, update, delete, purge, scope prefix patterns, admin_ prefix, SearchScope, BaseFilterAdapter, @api_function, Click CLI)
Teams using api-guide should expect a more consistent output, faster repeated execution, less prompt rewriting, better workflow continuity with your supporting tools.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
- You already have the supporting tools or dependencies needed by this skill.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/api-guide/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How api-guide Compares
| Feature / Agent | api-guide | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Guide for implementing REST and GraphQL APIs (create, get, search, update, delete, purge, scope prefix patterns, admin_ prefix, SearchScope, BaseFilterAdapter, @api_function, Click CLI)
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# API Implementation Guide
Guide for implementing REST and GraphQL APIs with standard operations and scope patterns.
## Standard Operations
APIs implement 6 standard operations:
1. **create** - Create new entity
2. **get** - Retrieve single entity
3. **search** - Query with filters and pagination
4. **update** - Update entity
5. **delete** - Delete entity (soft)
6. **purge** - Permanently remove entity (hard)
**Batch operations:** `batch_update`, `batch_delete`, `batch_purge`
## Scope Prefix Rules
**API layer only** (Service/Repository layers don't use prefix)
### Scoped Operations
Operations within a scope use `{scope}_` prefix:
**REST:**
```
POST /domains/{domain}/users → domain_create_user
GET /domains/{domain}/users/{id} → domain_user
GET /domains/{domain}/users → domain_search_users
PATCH /domains/{domain}/users/{id} → domain_update_user
DELETE /domains/{domain}/users/{id} → domain_delete_user
```
**GraphQL:**
```graphql
mutation domainCreateUser(scope: DomainScope, input: ...)
query domainUser(scope: DomainScope, id: ID)
query domainSearchUsers(scope: DomainScope, filter: ...)
```
### Admin Operations (No Scope)
Operations without scope use `admin_` prefix (superadmin required):
**REST:**
```
POST /admin/domains → admin_create_domain
GET /admin/domains/{id} → admin_domain
GET /admin/domains → admin_search_domains
```
**GraphQL:**
```graphql
mutation adminCreateDomain(input: ...)
query adminDomain(id: ID)
query adminSearchDomains(filter: ...)
```
## REST API Patterns
### Architecture
```
REST Handler → Processor → Service → Repository
```
**Key Files:**
- `src/ai/backend/manager/api/{domain}/handler.py` - Handlers
- `src/ai/backend/manager/api/{domain}/adapter.py` - Filters
- `src/ai/backend/manager/api/adapter.py` - Base adapter
### Processor-Based Service Invocation
**Core principle:**
- REST/GraphQL handlers MUST call service methods through Processors
- Never call service methods directly from handlers
- Processors wrap service methods as Actions and provide cross-cutting concerns (hooks, metrics, monitoring)
**Pattern:**
1. Handler creates Action with operation parameters
2. Handler calls processor's `wait_for_complete()` with Action
3. Processor invokes corresponding service method and returns ActionResult
**ActionProcessor responsibilities:**
- Action-based service method invocation
- Hook execution (pre/post operation)
- Metrics collection and monitoring
- Error handling and logging
**See complete examples:**
- `api/fair_share/handler.py:144` - Handler calling processor
- `services/storage_namespace/processors.py:29-56` - Processor implementation
- `services/processors.py` - ActionProcessor base class
### Scope Pattern
Scope defines access boundaries.
**Repository Scope:**
- `src/ai/backend/manager/repositories/{domain}/types.py`
- Example: `repositories/fair_share/types.py`
- `DomainFairShareSearchScope`, `ProjectFairShareSearchScope`
**Pattern:**
- Frozen dataclass with scope params
- `to_conditions()` converts to query conditions
**See complete examples:**
- `api/fair_share/handler.py` - Scoped handler implementations
### Scope Parameter Usage
**Scope parameter is needed for:**
1. **search** - Filter multiple items within scope
```python
domain_search_users(scope: DomainScope, filter: ...)
```
2. **batch operations** - Process multiple items within scope
```python
domain_batch_update_users(scope: DomainScope, ids: list[ID], ...)
```
**Scope parameter is NOT needed for:**
1. **get** - ID uniquely identifies item
```python
user(id: ID) # ✅ No scope needed
# domain_user(scope: DomainScope, id: ID) # ❌ Unnecessary
```
2. **update/delete/purge** - ID uniquely identifies item
```python
update_user(id: ID, data: ...) # ✅ No scope
delete_user(id: ID) # ✅ No scope
```
3. **create** - Scope info in data
```python
create_user(data: CreateUserData) # data contains domain_name
```
**Note:** Scope prefix in API name (`domain_search_users`) is different from scope parameter (`scope: DomainScope`).
### Filter Pattern
Filters convert API params to QueryCondition.
**Adapter:**
- `api/adapter.py` - BaseFilterAdapter
- `api/fair_share/adapter.py` - Domain adapters
**Pattern:**
- `to_conditions(filters)` → `list[QueryCondition]`
- `to_orders(order_by)` → `list[QueryOrder]`
- Adapter → `BatchQuerier` → Repository
**See complete examples:**
- `api/fair_share/adapter.py` - Filter adapters
- `api/fair_share/handler.py` - Handler implementations with BatchQuerier
### Admin_ Prefix Pattern
Admin operations require superadmin check before processing.
**Pattern:**
- `_check_superadmin(request)` at handler start
- Raise `InsufficientPermission` if not superadmin
**See complete examples:**
- `api/rbac/handler.py` - Admin handler implementations
### Pagination
REST uses offset-based pagination.
```python
class PaginationQuery(BaseModel):
offset: int = 0
limit: int = 20
# Response
class SearchResult(BaseModel):
items: list[Item]
total_count: int
offset: int
limit: int
```
**Client calculates:** `has_next = offset + limit < total_count`
## GraphQL Patterns
### Architecture
```
GraphQL Resolver → check_admin_only (if admin) → Processor → Service → Repository
```
**Key Files:**
- `src/ai/backend/manager/api/gql/{domain}/resolver/` - Resolvers
- `src/ai/backend/manager/api/gql/types.py` - Input types
- `src/ai/backend/manager/api/gql/utils.py` - Utilities
### Type System Rules
**Strawberry Runtime Evaluation:**
- Strawberry types are evaluated at runtime
- NEVER use TYPE_CHECKING for Strawberry types (Connection, Filter, OrderBy, Input, Type)
- ALWAYS import Strawberry types directly at module level
- Only use TYPE_CHECKING for data layer types not used by Strawberry
- If lazy import needed: use strawberry.lazy() or string-based forward references
**Naming Convention:**
- All GraphQL types MUST have `GQL` suffix (DomainGQL, DomainScopeGQL, DomainFilterGQL)
- Distinguishes GraphQL types from data layer types
- Applies to: @strawberry.type, @strawberry.input, @strawberry.enum classes
**Scope vs Filter:**
- Scope: Required context parameters (resource_group, domain_name, project_id)
- Filter: Optional filtering conditions (name contains, status equals, created after)
- NEVER put optional fields in Scope - use Filter instead
- Scope fields must all be required (no default values, no Optional types)
### Cross-Entity Reference Resolvers
When a GQL node references another entity node, use `strawberry.lazy()` to avoid circular imports. Strawberry requires runtime type resolution, so `TYPE_CHECKING` imports alone are insufficient.
**Pattern:**
```python
# 1. TYPE_CHECKING: for static analysis (mypy)
if TYPE_CHECKING:
from ai.backend.manager.api.gql.domain_v2.types.node import DomainV2GQL
# 2. Return type: Annotated with strawberry.lazy() for runtime resolution
# 3. Function body: runtime import + DataLoader
async def domain(self, info: Info[StrawberryGQLContext]) -> Annotated[
DomainV2GQL,
strawberry.lazy("ai.backend.manager.api.gql.domain_v2.types.node"),
]:
from ai.backend.manager.api.gql.domain_v2.types.node import DomainV2GQL
data = await info.context.data_loaders.domain_loader.load(self.domain_name)
return DomainV2GQL.from_data(data)
```
**Optional return type:** `| None` must be **outside** `Annotated[]`:
```python
) -> Annotated[DomainV2GQL, strawberry.lazy("...")] | None: # ✅
) -> Annotated[DomainV2GQL | None, strawberry.lazy("...")]: # ❌ lazy cannot resolve union
```
**DataLoaders** (`info.context.data_loaders`): Use DataLoaders instead of individual fetch functions to prevent N+1 queries. See `api/gql/data_loader/data_loaders.py` for available loaders.
**See examples:**
- `api/gql/fair_share/types/domain.py` - Cross-entity reference with DataLoader
- `api/gql/domain_v2/types/node.py` - DomainV2GQL with fair_shares/usage_buckets
- `api/gql/fair_share/types/*.py` - Scope and Filter patterns
### Scope Pattern
**Input Types:**
- `api/gql/types.py`
- `ResourceGroupDomainScope`, `ResourceGroupProjectScope`, `ResourceGroupUserScope`
**Pattern:**
- Strawberry `@input` maps to repository SearchScope
- GraphQL input → Repository scope type conversion
**See complete examples:**
- `api/gql/types.py` - Scope input types
- `api/gql/fair_share/resolver/domain.py` - Resolver implementations
### Admin Check
**Pattern:**
- `check_admin_only(info)` at resolver start
- Raise `InsufficientPermission` if not superadmin
**See complete examples:**
- `api/gql/utils.py` - `check_admin_only()` utility
- `api/gql/*/resolver/*.py` - Admin resolver implementations
### Pagination
GraphQL supports cursor-based (Relay spec).
```python
@strawberry.type
class PageInfo:
has_next_page: bool
has_previous_page: bool
start_cursor: str | None
end_cursor: str | None
@strawberry.type
class UserConnection:
edges: list[UserEdge]
page_info: PageInfo
total_count: int
```
**See:** `api/gql/` for cursor pagination examples
## REST vs GraphQL
| Aspect | REST | GraphQL |
|--------|------|---------|
| **Scope** | PathParam/QueryParam | Strawberry input |
| **Admin Check** | `_check_superadmin(request)` | `check_admin_only(info)` |
| **Naming** | `domain_create_user` | `domainCreateUser` |
| **Pagination** | Offset | Offset or Cursor |
| **Response** | Pydantic | Strawberry type |
## Client SDK + CLI Integration
**When implementing REST API, also implement:**
1. ✅ **SDK Function** (`client/func/{domain}.py`)
- Use `@api_function` decorator
- Map to REST endpoint
2. ✅ **CLI Command** (`client/cli/admin/{domain}.py`)
- Click command
- Calls SDK function
**Integration flow:**
```
CLI → SDK → REST API → Processor → Service → Repository
```
**See examples:**
- `src/ai/backend/client/func/admin.py` - SDK
- `src/ai/backend/client/cli/admin/user.py` - CLI
## Testing
**See:** `/tdd-guide` skill and `tests/CLAUDE.md` for complete testing strategies.
**Test hierarchy:**
```
Repository Tests → Real DB (with_tables)
Service Tests → Mock repositories
API Handler Tests → Mock processors
CLI Tests → Mock HTTP
```
## Implementation Checklist
**When implementing new API:**
1. ✅ **Repository** (`/repository-guide`)
- Implement standard operations
- Define SearchScope
2. ✅ **Service** (`/service-guide`)
- Define Actions/ActionResults
- Implement service methods
- Create processors
3. ✅ **REST API**
- Handler with scope prefix
- Admin check if needed
- Filter adapter
4. ✅ **GraphQL** (optional)
- Input types
- Resolver with scope prefix
- Admin check if needed
5. ✅ **Client SDK**
- Add SDK function
- `@api_function` decorator
6. ✅ **CLI**
- Click command
- Integrate with SDK
7. ✅ **Tests**
- Repository (real DB)
- Service (mock repo)
- Handler (mock processors)
- CLI (mock HTTP)
## Related Documentation
- **Service Layer**: `/service-guide` - Actions, Processors
- **Repository Layer**: `/repository-guide` - Data access
- **Testing**: `/tdd-guide` - TDD workflow
- **API README**: `src/ai/backend/manager/api/README.md`
## Examples
**REST API:**
- `src/ai/backend/manager/api/fair_share/handler.py`
- `src/ai/backend/manager/api/rbac/handler.py`
**GraphQL:**
- `src/ai/backend/manager/api/gql/fair_share/resolver/domain.py`
- `src/ai/backend/manager/api/gql/types.py`
**Client SDK/CLI:**
- `src/ai/backend/client/func/admin.py`
- `src/ai/backend/client/cli/admin/user.py`
## Summary
**Standard operations:**
- create, get, search, update, delete, purge
- batch_update, batch_delete, batch_purge
**Scope prefix (API only):**
- Scoped: `{scope}_operation` (domain_create_user)
- Admin: `admin_operation` (admin_create_domain)
**Key patterns:**
- Scope → SearchScope → QueryCondition
- Filter → Adapter → QueryCondition
- Admin → check permission first
**Integration:**
- REST API + SDK + CLI (unified stack)
- GraphQL (separate, optional)
**Next steps:**
1. Implement repository (`/repository-guide`)
2. Implement service (`/service-guide`)
3. Implement API handlers
4. Add SDK + CLI
5. Write tests (`/tdd-guide`)Related Skills
institutional-repository-guide
Access papers from institutional and subject repositories at scale
ai-development-guide
Technical decision criteria, anti-pattern detection, debugging techniques, and quality check workflow. Use when making technical decisions, detecting code smells, or performing quality assurance.
web-design-guidelines
Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices".
swift-api-design-guidelines-skill
Write, review, or improve Swift APIs using Swift API Design Guidelines for naming, argument labels, documentation comments, terminology, and general conventions. Use when designing new APIs, refactoring existing interfaces, or reviewing API clarity and fluency.
oiloil-ui-ux-guide
Modern, clean UI/UX guidance + review skill. Use when you need actionable UX/UI recommendations, design principles, or a design review checklist for new features or existing systems (web/app). Focus on CRAP (Contrast/Repetition/Alignment/Proximity) plus task-first UX, information architecture, feedback & system status, consistency, affordances, error prevention/recovery, and cognitive load. Enforce a modern minimal style (clean, spacious, typography-led), reduce unnecessary copy, forbid emoji as icons, and recommend intuitive refined icons from a consistent icon set.
map-workflows-guide
Comprehensive guide for choosing the right MAP workflow based on task type and requirements
hackathon-guideline
このリポジトリで開発するアプリは、2025年1月16日〜18日にかけて行われる次世代オートモーティブ生成AIハッカソン提出用のプロダクトです。開発者は以下のガイドラインに沿ったアイディア・アプリを揃える必要があります。必要に応じてこのSKILLを使って最適なアウトプットを出すようにしてください。
frontend-styleguide
Use when asked to create or edit style guides, design systems, component libraries, or update existing frontend components for web projects
epic-ui-guidelines
Guide on UI/UX guidelines, accessibility, and component usage for Epic Stack
design-and-user-experience-guidelines
Specifies design and user experience guidelines, including dark mode compatibility, responsive design, performance optimization, modern UI, and accessibility. This rule promotes a user-friendly and vi
claude-cowork-guidelines
Règles comportementales pour éviter les erreurs courantes des LLM dans Claude Cowork. S'active pour TOUTES les tâches (documents, spreadsheets, présentations, scripts, automatisations). Basé sur les observations d'Andrej Karpathy - assumptions silencieuses, overcomplexité, modifications non demandées. Utiliser pour toute tâche impliquant création de fichiers, édition, ou automatisation multi-étapes.
brand-guidelines
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.