بنقرة واحدة
api-designer
Type-safe API design: Zod validation, Result types, SvelteKit endpoints, middleware patterns.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Type-safe API design: Zod validation, Result types, SvelteKit endpoints, middleware patterns.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
{{ 𝚫𝚫𝚫 }} Rebuild roadmap-system.zip, the distributable snapshot of the roadmap tooling (scripts, HTML template, conventions reference, and every roadmap-touching skill, including this one).
{{ 𝛀𝛀𝛀 }} Create a project roadmap in the rich phase-array format — roadmaps.json as source of truth plus a PHASE task list and prose overview
{{ 𝛀𝛀𝛀 }} Recompute and synchronise roadmap task statuses across roadmaps.json and its projections, with optional codebase reconciliation
{{ 𝛀𝛀𝛀 }} Add a task to a rich-format project roadmap with correct ID, dependency wiring, and graph integrity — ID assignment, status computation, dependency edges in both directions, and no unconnected islands.
Git workflow: branch management, commit conventions, PR patterns, conflict resolution.
{{ 𝛀𝛀𝛀 }} Review a pull request and post it as a GitHub review
| name | api-designer |
| description | Type-safe API design: Zod validation, Result types, SvelteKit endpoints, middleware patterns. |
| when_to_use | When designing or reviewing an API endpoint, request/response contract, or validation layer — auto-loads on files under routes/ or api/, or when the conversation turns to API design, Zod schemas, or error handling. |
| user-invocable | false |
| effort | medium |
| paths | ["**/routes/**","**/api/**"] |
| allowed-tools | ["Read","Glob","Grep"] |
Comprehensive guide to designing type-safe APIs with TypeScript. Covers type-safe contracts, validation with Zod, Result types for error handling, SvelteKit endpoints, middleware patterns, and API versioning.
Use this skill when:
// types/api.ts
export interface CreateUserRequest {
email: string;
name: string;
password: string;
}
export interface User {
id: string;
email: string;
name: string;
createdAt: string;
}
export interface ApiError {
code: string;
message: string;
details?: Record<string, string[]>;
}
Key principle: Types ARE documentation. Well-named types with clear structure tell the story.
// For expected failures (not found, validation, etc.)
export type Result<T, E = string> =
| { success: true; data: T }
| { success: false; error: E };
// Usage
function findUser(id: string): Result<User, 'not_found'> {
const user = db.findUser(id);
if (!user) {
return { success: false, error: 'not_found' };
}
return { success: true, data: user };
}
// Consuming
const result = findUser('123');
if (result.success) {
console.log(result.data.email); // Type-safe access
} else {
console.error('Error:', result.error);
}
// Standard success response
export interface ApiSuccess<T> {
success: true;
data: T;
}
// Standard error response
export interface ApiError {
success: false;
error: {
code: string;
message: string;
details?: Record<string, string[]>;
};
}
export type ApiResponse<T> = ApiSuccess<T> | ApiError;
// Optional: Define all endpoints in one place
export interface ApiEndpoints {
'POST /api/users': {
request: CreateUserRequest;
response: User;
};
'GET /api/users/:id': {
params: { id: string };
response: User;
};
'PATCH /api/users/:id': {
params: { id: string };
request: Partial<UpdateUserRequest>;
response: User;
};
'DELETE /api/users/:id': {
params: { id: string };
response: null;
};
}
Deep-dive detail lives in supporting files, loaded only when needed:
// ✓ Good - validate with Zod
const data = CreateUserSchema.parse(input);
const user = await createUser(data);
// ✗ Bad - trusting client input
const user = await createUser(input);
// ✓ Good - Result type for expected failure
function findUser(id: string): Result<User, 'not_found'> {
const user = db.findUser(id);
if (!user) {
return { success: false, error: 'not_found' };
}
return { success: true, data: user };
}
// ✗ Bad - throwing for expected case
function findUser(id: string): User {
const user = db.findUser(id);
if (!user) throw new Error('Not found');
return user;
}
// ✓ Good - throw for exceptional case
async function connectDatabase(): Promise<Database> {
try {
return await connect();
} catch (error) {
throw new DatabaseError('Failed to connect');
}
}
// ✗ Bad - Result type for exceptional case
async function connectDatabase(): Result<Database, string> {
// Database connection should succeed or crash
}
// ✓ Good - explicit types
interface CreateUserRequest {
email: string;
name: string;
}
async function createUser(data: CreateUserRequest): Promise<User> {
// ...
}
// ✗ Bad - implicit any
async function createUser(data): Promise<any> {
// ...
}
// ✓ Good - separated layers
// Handler (thin, delegates to service)
export const POST: RequestHandler = async ({ request }) => {
const data = await validateRequest(request, CreateUserSchema);
const user = await createUser(data);
return json({ success: true, data: user }, { status: 201 });
};
// Service (business logic)
async function createUser(data: CreateUserRequest): Promise<User> {
const passwordHash = await hashPassword(data.password);
return await db.users.create({ ...data, passwordHash });
}
// ✗ Bad - everything in handler
export const POST: RequestHandler = async ({ request }) => {
const body = await request.json();
// validation, hashing, database, all mixed together
};
// ✓ Good - reusable middleware
export const POST: RequestHandler = async (event) => {
const user = await requireAuth(event);
const data = await validateRequest(event.request, CreatePostSchema);
const post = await createPost(user.id, data);
return json({ success: true, data: post });
};
// ✗ Bad - repeating auth/validation everywhere
export const POST: RequestHandler = async ({ request, cookies }) => {
// Repeated auth code
const session = cookies.get('session');
if (!session) throw error(401);
const user = await verifySession(session);
// Repeated validation code
const body = await request.json();
if (!body.title) throw error(400);
// ...
};
// ✓ Good - type tells the story
interface CreateUserRequest {
email: string; // Type is clear
name: string; // Type is clear
password: string; // Min 8 chars (Zod enforces)
}
// ✗ Bad - relying on comments
interface CreateUserRequest {
email: string; // Must be valid email
name: string; // Required, 2-100 chars
password: string; // Min 8, uppercase, lowercase, number, special
}
// Comments get out of sync with code!
API design is well-structured when: