# API Design Exercises

## Exercise 1: REST Resource Design

**Task:** Design REST endpoints for a "books" API: list books, get one book, create a book, update a book, delete a book. Include: URL, method, request body (where applicable), and key response codes.

**Validation:**
- [ ] Plural resource name (`/books`)
- [ ] Correct HTTP verbs for each action
- [ ] 201 for create, 200 for get/update, 204 for delete
- [ ] Request body for create and update

**Hints:**
1. GET /books — list, GET /books/:id — get one
2. POST /books — create (body: title, author, isbn)
3. PUT or PATCH /books/:id — update
4. DELETE /books/:id — delete (204 No Content)

---

## Exercise 2: GraphQL Query and Mutation

**Task:** Design a GraphQL schema and one query + one mutation for a "tasks" API. Query: get task by id with title, status, assignee name. Mutation: create task with title and assigneeId. Write the schema types and the query/mutation.

**Validation:**
- [ ] Task type with id, title, status, assignee
- [ ] Query: task(id: ID!): Task
- [ ] Mutation: createTask(title: String!, assigneeId: ID!): Task
- [ ] Assignee can be embedded or referenced

**Hints:**
1. type Task { id: ID! title: String! status: String assignee: User }
2. type User { id: ID! name: String }
3. createTask returns Task (with id from server)

---

## Exercise 3: OpenAPI Snippet

**Task:** Write OpenAPI 3.0 for `GET /books` and `POST /books`. Include: parameters (optional: author, limit), request/response schemas, status codes 200, 201, 400.

**Validation:**
- [ ] paths./books with get and post
- [ ] GET has parameters; POST has requestBody
- [ ] Schemas for Book (id, title, author)
- [ ] Correct status codes

**Hints:**
1. openapi: 3.0.0, paths, components.schemas
2. parameters: author (query), limit (query, default 20)
3. requestBody for POST: application/json, required: title, author

---

## Exercise 4: Pagination Comparison

**Task:** Compare offset and cursor pagination for a feed of 10,000 items. Scenario: user requests page 5 (offset 40). Between requests, 3 items are inserted at the start. What does the user see with offset vs cursor? Which is better for a social feed?

**Validation:**
- [ ] Offset: might see duplicates or miss items when data shifts
- [ ] Cursor: stable, no duplicates; better for feeds
- [ ] Recommendation: cursor for feeds, offset for admin UIs

**Hints:**
1. Offset 40 = items 41–50. After insert, "page 5" might return different items
2. Cursor points to last seen item; next page is "after cursor"
3. Social feeds: cursor preferred (consistent infinite scroll)

---

## Exercise 5: Error and Rate Limit Response

**Task:** Design the full HTTP response for: (1) 400 Bad Request — invalid JSON body, (2) 429 Too Many Requests — client exceeded 100 req/min. Include status, headers, and body format.

**Validation:**
- [ ] 400: body has error code, message, optionally details
- [ ] 429: Retry-After header, optionally X-RateLimit-* headers
- [ ] Content-Type: application/json
- [ ] Body is parseable and actionable for clients

**Hints:**
1. 400: { "error": { "code": "INVALID_JSON", "message": "..." } }
2. 429: Retry-After: 60 (seconds)
3. X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
