Skip to content
Back to skills

Api Design

ASecurity

REST and GraphQL API design conventions — resource modeling, pagination, error envelopes, versioning, idempotency. Use when adding, changing, or reviewing endpoints.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added May 26, 2026
developmentrustgoapi

Works with

  • cursor
  • cli
  • api

Security analysis

A100/100

Scanned May 27, 2026

npx -y skills add atuljha23/holocron --skill api-design --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Api Design?

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

Security grade badge for Api Design
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/atuljha23-api-design/badge)](https://www.skillsdirectory.com/skills/atuljha23-api-design)

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-design
description: REST and GraphQL API design conventions — resource modeling, pagination, error envelopes, versioning, idempotency. Use when adding, changing, or reviewing endpoints.
---

# API design

## REST

### Resource, not action
URLs name nouns. Actions are verbs.

Good: `POST /users/:id/password-reset`
Bad:  `POST /resetUserPassword?id=123`

### Status codes mean things
- `200` success with body
- `201` created (include `Location`)
- `204` success, no body
- `400` client sent something invalid (bad syntax, bad shape)
- `401` not authenticated
- `403` authenticated but not authorized
- `404` resource doesn't exist (or the caller isn't allowed to know it does)
- `409` conflict (version conflict, duplicate, precondition failed)
- `422` semantic validation failed (body parses but rules reject)
- `429` rate limited
- `5xx` server fault — internal detail logged, opaque to caller

### Error envelope
Pick one. Use it everywhere.

```json
{
  "error": {
    "code": "resource_not_found",
    "message": "User alice@example.com not found.",
    "requestId": "abc123"
  }
}
```

- `code` is machine-readable, stable, lowercase_snake.
- `message` is human-readable. Safe to surface.
- `requestId` lets the caller tell you what went wrong without you reading prod logs.

### Pagination
Cursor-based for anything you'll scale. Offset paging breaks under concurrent writes.

```
GET /messages?cursor=abc&limit=50
→ { items: [...], nextCursor: "xyz" }
```

### Idempotency
Any POST that has side-effects and will be retried needs an idempotency key:

```
POST /payments
Idempotency-Key: <uuid-v4>
```

Server stores the (key → response) for a reasonable TTL. Retries return the cached response, not a second charge.

### Versioning
Prefer additive changes. Add fields; don't remove or rename. When you must break, version:

- URL (`/v2/...`) — simple, explicit, slightly ugly
- Accept header (`Accept: application/vnd.foo.v2+json`) — prettier URLs, slightly opaque

Pick one per service. Never mix.

## GraphQL

### Nullability is a contract
`String!` says "this WILL be present". If you're not sure, it's `String` (nullable). A lie here cascades.

### Relay-style pagination
Connections, edges, pageInfo, cursors. Don't invent your own.

### One mutation per intent
`updateUser(input: { name, email, password })` is three different operations glued together. Split them.

### Errors as types
Return `{ user: User | UserNotFoundError | ValidationError }` unions where it matters. Generic `errors[]` at the top is for transport-level fault, not business rules.

## Across both

- **Typed shapes.** Schemas (OpenAPI / GraphQL / proto). Generate clients from them.
- **Rate limit** expensive or abuse-prone endpoints.
- **Observability.** Every request has a `requestId`. Log it. Return it on errors. Tie logs, metrics, and traces together with it.
- **Auth at the edge** — check in the handler or middleware the handler trusts. Never rely on the gateway alone.

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…