Przejdź do treści
Biblioteka skilli
Programowanie · Planowanie

api-design

/api-design

Projektuje lub recenzuje API HTTP, REST i GraphQL pod kątem wersjonowania, paginacji, kształtu błędów, idempotencji, uwierzytelniania i ewolucji, z naciskiem na kody statusu i nagłówki cache.

Repozytorium
gsd-2 ↗
Licencja
MIT
Ostatnia zmiana repozytorium
22.05.2026

Ocena i bezpieczeństwo

100/ 100Klasa: dobry
Format25 / 25
Frontmatter z nazwą i opisem, poprawna nazwa, opis do 1024 znaków, nazwa zgodna z folderem.
Odkrywalność25 / 25
Opis mówi, kiedy użyć skilla, ma sensowną długość i jest w 3. osobie.
Treść35 / 35
Co najmniej 150 słów i do 500 linii, nagłówki, listy kroków, przykłady albo kod.
Higiena15 / 15
Bez zaślepek typu TODO, bez ścieżek Windows, z licencją.
Ryzykobrak sygnałów w skanie
Pliki w paczce
1
Skrypty
0
Komentarze HTML
0
Adresy URL w SKILL.md
0
Przestarzałość

Brak sygnałów. Repozytorium zmienione 22.05.2026, bez odwołań do wycofanych modeli i API.

Licencja

MIT, otwarta: można używać i zmieniać, z zachowaniem informacji o autorze.

Co robi i kiedy

Projektuje lub recenzuje API HTTP, REST i GraphQL pod kątem wersjonowania, paginacji, kształtu błędów, idempotencji, uwierzytelniania i ewolucji, z naciskiem na kody statusu i nagłówki cache.

Wyzwalacze z opisu

design an APIshape the endpointsdesign the schemaadd a new endpointreview this API
Oryginalny opis (EN)

Design or review an HTTP/REST/GraphQL API for versioning, pagination, error shapes, idempotency, auth, and evolvability. Use when asked to "design an API", "shape the endpoints", "design the schema", "add a new endpoint", "review this API", or when building/modifying a public or internal HTTP surface. Complements `design-an-interface` (which is interface-agnostic) by covering HTTP-specific concerns like status codes, cache headers, and breaking-change management.

Jak działa

  1. Step 1: Gather the contract
  2. Step 2: Resource and operation naming
  3. Step 3: Methods and status codes
  4. Step 4: Pagination
  5. Step 5: Error shape
  6. Step 6: Idempotency, caching, concurrency
  7. Step 7: Versioning and evolution
  8. Step 8: Review or write it up
Sekcje z nagłówków SKILL.md, w oryginale · 187 linii, 1 190 słów
Podgląd SKILL.md
---
name: api-design
description: Design or review an HTTP/REST/GraphQL API for versioning, pagination, error shapes, idempotency, auth, and evolvability. Use when asked to "design an API", "shape the endpoints", "design the schema", "add a new endpoint", "review this API", or when building/modifying a public or internal HTTP surface. Complements `design-an-interface` (which is interface-agnostic) by covering HTTP-specific concerns like status codes, cache headers, and breaking-change management.
---

<objective>
Shape an HTTP or GraphQL API so callers get predictable, evolvable, and honest semantics. The deliverable is a concrete endpoint/schema sketch with: URL or operation names, method/verb, request shape, response shape, error shape, auth model, pagination strategy, and versioning stance. Optimize for "clients that exist in 2 years" over "client that's easy to write today".
</objective>

<context>
GSD-2 has `design-an-interface` for general module-interface design; this skill is the HTTP/GraphQL specialization. REST and GraphQL carry baggage — status codes, verbs, nullability, pagination — that a generic interface-design discussion glosses over.

Invocation points:
- Adding a new public API endpoint
- Redesigning an internal API boundary between services
- Code review of a PR that introduces HTTP handlers
- A slice whose acceptance criteria include "the API works"
- A GraphQL schema change
</context>

<core_principle>
**CALLERS OUTLIVE YOUR ASSUMPTIONS.** An API you ship today has to keep working when your internals change, when the mobile app version two is still in use, and when a third party integrates against it. Design for extension, not just for the current caller.

**HONEST STATUS CODES.** 200 OK with `{"error": "not found"}` is a lie. 404 says not found. Use the HTTP semantics the protocol offers — HTTP clients, caches, and intermediaries rely on them.

**PAGINATION IS NON-OPTIONAL.** Any list endpoint that doesn't paginate will eventually get a request for "all records" that kills your database.
</core_principle>

<process>

## Step 1: Gather the contract

Answer, or ask (one round, 1–3 questions):

1. **Who are the callers?** Internal service / mobile app / public third-party / same-repo frontend.
2. **What's the versioning stance?** None / URL-path (`/v1/`) / header-based / GraphQL schema evolution.
3. **Auth model?** Public / API key / OAuth / session cookie / mTLS / none-but-internal-only.
4. **Idempotency expectation?** Is a retry safe? Required?
5. **Consistency model?** Read-your-writes, eventual, serializable?

## Step 2: Resource and operation naming

### REST

- Nouns not verbs in URLs: `POST /users`, not `POST /createUser`.
- Plural resources: `/users/42`, not `/user/42`.
- Nested only when the relationship is hierarchical and the child has no independent identity: `/users/42/sessions/3`. Otherwise flat: `/sessions/3?userId=42`.
- Use subresources for actions that don't fit CRUD: `POST /users/42:deactivate` (colon syntax) or `POST /users/42/actions/deactivate`.

### GraphQL

- Queries are nouns; mutations are verbs: `user(id)`, `createUser(input)`, `deactivateUser(id)`.
- Group related mutations under an input type: `createUser(input: CreateUserInput!)`.
- Return the affected object plus any derived/computed fields from mutations — lets clients avoid a refetch.

## Step 3: Methods and status codes

### REST

| Method | Intent | Idempotent? | Default success |
|---|---|---|---|
| GET | Read | Yes | 200, or 304 if conditional |
| POST | Create or non-idempotent action | No | 201 with `Location` on create, 200 on action |
| PUT | Replace (full-object) | Yes | 200 with body, or 204 |
| PATCH | Partial update | No (usually) | 200 with body |
| DELETE | Remove | Yes | 204 |

Errors:
- 400: caller screwed up the request shape
- 401: no/invalid auth
- 403: authed but not allowed
- 404: resource doesn't exist
- 409: conflict (version mismatch, unique constraint)
- 410: gone (vs 404 when the resource previously existed and you want to signal that)
- 422: validation failed
- 429: rate-limited — include `Retry-After`
- 500: genuinely unexpected server error
- 503: service down or overloaded — include `Retry-After`

Never 200-with-error-body. Never 500 for a 4xx cause.

### GraphQL

- Top-level errors (`errors[]`) for transport-level failures. Domain errors (validation, not-found, forbidden) go in the typed return — use a union or result type.
- Partial results are expected; design the schema so `null` on a field is meaningful, not a signal of generic failure.

## Step 4: Pagination

- **Cursor-based by default.** Opaque cursor string, `limit`, return `nextCursor` when more exists. Scales, stable under writes.
- **Offset-based only when:** dataset is small, user needs jump-to-page semantics (admin tables), and you're willing to accept stability drift.
- **Never "return everything"** as default. Put a hard upper bound on `limit` (e.g., 200).
- GraphQL: use Relay-style connections (`edges`, `pageInfo`) if the ecosystem expects it; otherwise a simpler `{items, nextCursor}` is fine.

## Step 5: Error shape

Standardize one shape and use it everywhere. Example REST:

```json
{
  "error": {
    "code": "user_not_found",
    "message": "No user with id 42",
    "details": { "userId": 42 },
    "requestId": "req_abc123"
  }
}
```

- `code` is machine-readable; stable; documented.
- `message` is human-readable; can change.
- `details` carries structured context.
- `requestId` lets callers report bugs.

Errors don't leak stack traces, file paths, or internal queries.

## Step 6: Idempotency, caching, concurrency

- **Idempotency keys** for POST operations that mustn't double-execute on retry. Caller passes `Idempotency-Key: <uuid>`; server dedupes for a window.
- **ETags** for GET + conditional updates (`If-Match` on PUT/PATCH).
- **Cache-Control** on GETs that are safely cacheable.
- **Optimistic concurrency:** when multiple writers collide, 409 with the current state. Don't silently clobber.

## Step 7: Versioning and evolution

- **Additive changes are free:** new optional fields, new endpoints, new optional query params.
- **Breaking changes need a plan:** path-versioned (`/v2/`), sunset headers on `/v1/`, deprecation window communicated. Or, for GraphQL, `@deprecated` on fields with a migration note.
- **Document the contract:** OpenAPI/GraphQL SDL. Keep it in the repo. Make it part of the PR that introduces the change.

## Step 8: Review or write it up

If this is a review, produce findings in the same shape as `security-review` / `review` — file:line, category, recommendation.

If this is a new design, produce:

```markdown
## <API name>

### Scope
<what the API is for, who calls it>

### Endpoints / Operations
- `POST /users` — create user. Request: `{email, name}`. Response 201: `{id, email, name, createdAt}` + `Location: /users/<id>`. Errors: 409 email taken, 422 invalid.
- ...

### Auth
<model + where to put the credential>

### Pagination
<cursor shape, max limit>

### Error shape
<one canonical shape>

### Idempotency / concurrency
<rules>

### Versioning
<stance + how breaking changes will be handled>

### OpenAPI / SDL
<link or inline>
```

Append architectural decisions to `.gsd/DECISIONS.md`.

</process>

<anti_patterns>

- **200 OK with `{"error": "..."}`.** Lies to caches, proxies, retry libraries.
- **Unbounded list endpoints.** `GET /users` without a `limit` cap will bite you.
- **Offset pagination at scale.** Drifts under writes; slow at high offsets.
- **Free-form error messages with no code.** Machine callers can't branch on prose.
- **Breaking changes in-place.** Callers break; versioning exists for a reason.
- **Ignoring idempotency on retriable POSTs.** Double-charges, duplicate records.
- **Auth checks at the handler only, not the service layer.** Defense in depth.

</anti_patterns>

<success_criteria>

- [ ] Every endpoint/operation has named request, response, and error shapes.
- [ ] Status codes match HTTP semantics — no 200-with-error.
- [ ] List endpoints paginate; max limit is documented.
- [ ] A single error shape is used everywhere, with a machine-readable code.
- [ ] Versioning stance is stated — even if the answer is "additive only for now."
- [ ] OpenAPI/SDL reflects the design and lives in the repo.
- [ ] Decisions appear in `.gsd/DECISIONS.md`.

</success_criteria>

Wersje

RepozytoriumWynikLicencja
Ta strona · gsd-build/gsd-2100MIT
proyecto26/system-design-skills100MIT
ericrisco/rsc-harness100MIT
yonatangross/orchestkit100MIT
travisjneuman/.claude100MIT
wrongstack/wrongstack100MIT
komluk/scaffolding100MIT
OKHP3/skillz100MIT
event4u-app/agent-config100MIT

Migawka bazy z 28.10.2026 · wersja paczki 48757dbbb9be (skrót SHA-256 całej paczki)

Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.

Podobne skille

  • 100design-api
    Projektuje API REST i GraphQL: nazewnictwo, wersjonowanie, kształt błędów i uwierzytelnianie.
  • 85backend-api-design-review
    Sprawdza projekt API REST i GraphQL: modelowanie zasobów, semantykę metod, kody statusu, idempotentność, wersjonowanie i paginację.
  • 100api-design-expert
    Wspiera projektowanie i recenzję API REST i GraphQL: modelowanie zasobów, kody statusu, wersjonowanie, paginacja kursorowa, idempotencja, błędy, limity i kontrakty.
  • 90api-design-review
    Przegląda kontrakt API REST lub GraphQL: nazwy zasobów, kody statusu, kształt błędów, paginację i zgodność wsteczną, z konkretnymi poprawkami.
  • 100rest-api
    Opisuje zasady projektowania REST API: zasoby, metody i kody statusu, przy projektowaniu lub przeglądzie API.
  • 100api
    Pomaga projektować, recenzować i zmieniać API HTTP, REST lub GraphQL: endpointy, nazwy zasobów, odpowiedzi błędów, paginacja, wersjonowanie, idempotencja i kontrakty między usługami.

Uwagi i zgłoszenia

Wiadomość trafi do Bartosza Sokolińskiego. Adres e-mail jest potrzebny tylko do odpowiedzi. Szczegóły w polityce prywatności.