Skip to content
Back to skills

Api Designer Majiayu000

ASecurity

Design RESTful or GraphQL APIs with proper conventions. Creates endpoint specifications, request/response schemas, and documentation. Use when user says 'design API', 'endpoints', 'REST', 'GraphQL', or 'API spec'.

  • 57 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added May 31, 2026
developmentpythongonoderefactoringapidatabasedocumentation

Works with

  • cursor
  • cli
  • api

Security analysis

A100/100

Scanned May 31, 2026

npx -y skills add diegosouzapw/awesome-omni-skill --skill api-designer-majiayu000 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Api Designer Majiayu000?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Api Designer Majiayu000
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/diegosouzapw-api-designer-majiayu000/badge)](https://www.skillsdirectory.com/skills/diegosouzapw-api-designer-majiayu000)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: api-designer
description: "Design RESTful or GraphQL APIs with proper conventions. Creates endpoint specifications, request/response schemas, and documentation. Use when user says 'design API', 'endpoints', 'REST', 'GraphQL', or 'API spec'."
allowed-tools: Read, Write, Edit
---

# API Designer

You are an expert at designing clean REST and GraphQL APIs.

## When To Use

- User says "Design the API", "What endpoints do we need?"
- User asks to "Create API spec"
- New feature requires API endpoints
- Refactoring existing API

## Inputs

- Feature requirements
- Data models involved
- Authentication requirements

## Outputs

- API specification (OpenAPI/Swagger or markdown)
- Endpoint documentation
- Example requests/responses

## REST Conventions

| Action | Method | Endpoint | Response |
|--------|--------|----------|----------|
| List | GET | `/resources` | `200 + []` |
| Get one | GET | `/resources/:id` | `200` or `404` |
| Create | POST | `/resources` | `201 + object` |
| Update | PUT/PATCH | `/resources/:id` | `200 + object` |
| Delete | DELETE | `/resources/:id` | `204` or `404` |

## Workflow

### 1. Identify Resources

What entities does this feature involve?

### 2. Define Operations

CRUD? Custom actions?

### 3. Design URLs

- Use nouns, not verbs
- Nest appropriately
- Plural for collections

### 4. Define Request/Response

- Fields, types
- Required vs optional
- Pagination for lists

### 5. Error Handling

Standard error format, appropriate status codes.

### 6. Document

OpenAPI spec or markdown.

## URL Design

### Good

```
GET    /users
GET    /users/123
POST   /users
PUT    /users/123
DELETE /users/123

GET    /users/123/posts
POST   /users/123/posts
```

### Bad

```
GET    /getUser/123       # verb in URL
GET    /user/123          # singular
POST   /users/create      # redundant
GET    /users?action=delete  # wrong method
```

## Standard Error Format

```json
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid input",
    "details": [
      {"field": "email", "message": "Invalid email format"}
    ]
  }
}
```

## Status Codes

| Code | When |
|------|------|
| 200 | Success |
| 201 | Created |
| 204 | No Content (deleted) |
| 400 | Bad Request (validation) |
| 401 | Unauthorized (not logged in) |
| 403 | Forbidden (no permission) |
| 404 | Not Found |
| 409 | Conflict |
| 500 | Server Error |

## Pagination

```json
{
  "data": [...],
  "pagination": {
    "page": 1,
    "per_page": 20,
    "total": 100,
    "total_pages": 5
  }
}
```

Or cursor-based:
```json
{
  "data": [...],
  "next_cursor": "abc123",
  "has_more": true
}
```

## OpenAPI Spec Template

```yaml
openapi: 3.0.0
info:
  title: API Name
  version: 1.0.0

paths:
  /resources:
    get:
      summary: List resources
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Resource'

components:
  schemas:
    Resource:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
```

---

## GraphQL

### When to Use GraphQL vs REST

| Use GraphQL | Use REST |
|-------------|----------|
| Complex data relationships | Simple CRUD |
| Mobile apps (reduce over-fetching) | Caching critical |
| Multiple clients need different data | Simpler tooling |
| Nested data in single request | File uploads |

### Schema Design

```graphql
type User {
  id: ID!
  email: String!
  name: String
  posts: [Post!]!
  createdAt: DateTime!
}

type Post {
  id: ID!
  title: String!
  content: String!
  author: User!
  published: Boolean!
}

type Query {
  user(id: ID!): User
  users(first: Int, after: String): UserConnection!
  post(id: ID!): Post
}

type Mutation {
  createUser(input: CreateUserInput!): User!
  updateUser(id: ID!, input: UpdateUserInput!): User!
  deleteUser(id: ID!): Boolean!
}

input CreateUserInput {
  email: String!
  name: String
}

input UpdateUserInput {
  email: String
  name: String
}
```

### Naming Conventions

| Element | Convention | Example |
|---------|------------|---------|
| Types | PascalCase | `User`, `BlogPost` |
| Fields | camelCase | `createdAt`, `firstName` |
| Queries | camelCase, noun | `user`, `users`, `post` |
| Mutations | camelCase, verb+noun | `createUser`, `updatePost` |
| Inputs | PascalCase + Input | `CreateUserInput` |

### Pagination (Relay-style)

```graphql
type UserConnection {
  edges: [UserEdge!]!
  pageInfo: PageInfo!
  totalCount: Int!
}

type UserEdge {
  node: User!
  cursor: String!
}

type PageInfo {
  hasNextPage: Boolean!
  hasPreviousPage: Boolean!
  startCursor: String
  endCursor: String
}

# Query
query {
  users(first: 10, after: "cursor123") {
    edges {
      node { id name }
      cursor
    }
    pageInfo { hasNextPage endCursor }
  }
}
```

### Error Handling

```graphql
type MutationResult {
  success: Boolean!
  message: String
  errors: [FieldError!]
}

type FieldError {
  field: String!
  message: String!
}

# Or use union types
union CreateUserResult = User | ValidationError | AuthError
```

### Resolvers (Code-first with Python)

```python
from ariadne import QueryType, MutationType

query = QueryType()
mutation = MutationType()

@query.field("user")
def resolve_user(_, info, id):
    return db.get_user(id)

@query.field("users")
def resolve_users(_, info, first=10, after=None):
    return db.paginate_users(first, after)

@mutation.field("createUser")
def resolve_create_user(_, info, input):
    return db.create_user(**input)
```

### N+1 Problem (Use DataLoaders)

```python
from ariadne import load_schema_from_path
from graphql import GraphQLResolveInfo

# BAD: N+1 queries
@query.field("users")
def resolve_users(_, info):
    users = db.get_users()
    for user in users:
        user.posts = db.get_posts_for_user(user.id)  # N queries!
    return users

# GOOD: DataLoader
from aiodataloader import DataLoader

async def batch_load_posts(user_ids):
    posts = await db.get_posts_for_users(user_ids)
    return [posts.get(uid, []) for uid in user_ids]

posts_loader = DataLoader(batch_load_posts)

@query.field("user")
async def resolve_user_posts(user, info):
    return await posts_loader.load(user.id)
```

### GraphQL Anti-Patterns

- Deeply nested queries without limits
- No query complexity limits (DoS risk)
- Exposing database IDs directly
- Not using input types for mutations
- Returning null for errors instead of error types

---

## REST vs GraphQL Decision

| Factor | REST | GraphQL |
|--------|------|---------|
| Learning curve | Lower | Higher |
| Caching | Built-in HTTP | Manual |
| Over-fetching | Common | Solved |
| Under-fetching | Common | Solved |
| File uploads | Native | Needs workaround |
| Real-time | WebSocket separate | Subscriptions built-in |

**Default to REST** unless you have specific GraphQL needs.

---

## Anti-Patterns

- Verbs in URLs (`/getUser`, `/createOrder`)
- Inconsistent response formats
- Missing pagination on list endpoints
- No versioning strategy
- Different error formats per endpoint
- Not documenting auth requirements

## Keywords

API, REST, endpoints, design API, OpenAPI, Swagger, routes, GraphQL, schema, query, mutation

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.