Designing a REST API: From Concept to Endpoints

Designing a REST API: From Concept to Endpoints

Learn to design a REST API from scratch. Walk through requirements analysis, resource identification, endpoint mapping, and response structure for a real application.

Designing a REST API: From Concept to Endpoints

Understanding how APIs are designed makes you a better API consumer. In this lesson, we will design a complete REST API from scratch for a task management application — the kind you might actually build or work with in your career.


1. The Design Process

graph TD
    A["1. Understand Requirements"] --> B["2. Identify Resources"]
    B --> C["3. Define Relationships"]
    C --> D["4. Map CRUD to Endpoints"]
    D --> E["5. Design Request/Response"]
    E --> F["6. Add Auth and Validation"]
    F --> G["7. Document the API"]

    style A fill:#4f46e5,color:#fff
    style D fill:#0891b2,color:#fff
    style G fill:#059669,color:#fff

2. Step 1: Requirements

Application: TaskFlow — a task management app for teams.

Features:

  • Users can register and log in
  • Users create projects
  • Projects contain task lists
  • Task lists contain tasks
  • Tasks can be assigned to team members
  • Tasks have due dates, priorities, and statuses
  • Users can comment on tasks
  • Users can label tasks with tags

3. Step 2: Identify Resources

Extract the nouns from requirements:

ResourceDescription
UsersPeople using the app
ProjectsTop-level containers
Task ListsGroups of tasks within a project
TasksIndividual work items
CommentsDiscussion on tasks
TagsLabels for organizing tasks

4. Step 3: Define Relationships

graph TD
    U[User] -->|creates| P[Project]
    U -->|assigned to| T[Task]
    P -->|contains| TL[Task List]
    TL -->|contains| T
    T -->|has many| C[Comments]
    T -->|has many| Tag[Tags]
    U -->|writes| C

    style U fill:#4f46e5,color:#fff
    style P fill:#0891b2,color:#fff
    style T fill:#059669,color:#fff

5. Step 4: Map Endpoints

Authentication

MethodEndpointDescription
POST/auth/registerCreate account
POST/auth/loginGet access token
POST/auth/refreshRefresh expired token

Users

MethodEndpointDescriptionAuth
GET/users/meGet current userRequired
PATCH/users/meUpdate profileRequired
GET/users/:idGet user by IDRequired

Projects

MethodEndpointDescriptionAuth
GET/projectsList my projectsRequired
POST/projectsCreate a projectRequired
GET/projects/:idGet project detailsRequired
PATCH/projects/:idUpdate projectOwner
DELETE/projects/:idDelete projectOwner

Tasks

MethodEndpointDescriptionAuth
GET/projects/:id/tasksList tasks in projectMember
POST/projects/:id/tasksCreate a taskMember
GET/tasks/:idGet task detailsMember
PATCH/tasks/:idUpdate a taskMember
DELETE/tasks/:idDelete a taskOwner
POST/tasks/:id/assignAssign to userMember

Comments

MethodEndpointDescriptionAuth
GET/tasks/:id/commentsList commentsMember
POST/tasks/:id/commentsAdd commentMember
DELETE/comments/:idDelete commentAuthor

6. Step 5: Design Request/Response

Create Project (POST /projects)

Request:

{
  "name": "Website Redesign",
  "description": "Complete overhaul of company website",
  "color": "#4f46e5"
}

Response (201 Created):

{
  "id": "proj_abc123",
  "name": "Website Redesign",
  "description": "Complete overhaul of company website",
  "color": "#4f46e5",
  "ownerId": 42,
  "memberCount": 1,
  "taskCount": 0,
  "createdAt": "2026-02-22T14:00:00Z"
}

Create Task (POST /projects/:id/tasks)

Request:

{
  "title": "Design homepage mockup",
  "description": "Create wireframes and hi-fi mockups for the new homepage",
  "priority": "high",
  "dueDate": "2026-03-01",
  "assigneeId": 15,
  "tags": ["design", "homepage"]
}

Response (201 Created):

{
  "id": "task_xyz789",
  "title": "Design homepage mockup",
  "description": "Create wireframes and hi-fi mockups for the new homepage",
  "status": "todo",
  "priority": "high",
  "dueDate": "2026-03-01",
  "assignee": {
    "id": 15,
    "name": "Sarah Chen",
    "avatar": "https://example.com/avatars/sarah.jpg"
  },
  "tags": ["design", "homepage"],
  "commentCount": 0,
  "projectId": "proj_abc123",
  "createdBy": 42,
  "createdAt": "2026-02-22T14:30:00Z"
}

List Tasks with Filtering

# All tasks in project, filtered and sorted
GET /projects/proj_abc123/tasks?status=in-progress&priority=high&sort=dueDate&order=asc&page=1&limit=20

Response:

{
  "data": [
    {
      "id": "task_xyz789",
      "title": "Design homepage mockup",
      "status": "in-progress",
      "priority": "high",
      "dueDate": "2026-03-01",
      "assignee": {"id": 15, "name": "Sarah Chen"}
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 1,
    "totalPages": 1
  }
}

7. Step 6: Error Responses

Every endpoint should have clear error responses:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Task creation failed",
    "details": [
      {"field": "title", "message": "Title is required"},
      {"field": "priority", "message": "Must be one of: low, medium, high, urgent"}
    ]
  }
}

Summary and Key Takeaways

  1. Design before building — identify resources, relationships, and endpoints.
  2. Each resource gets a standard set of CRUD endpoints.
  3. Use nested URLs for parent-child relationships: /projects/:id/tasks.
  4. Design consistent response formats across all endpoints.
  5. Include pagination for all collection endpoints.
  6. Plan error responses as carefully as success responses.

Lesson Review Quiz

?Knowledge Check

In our TaskFlow API design, how would you get all tasks in a specific project?

?Knowledge Check

Which endpoint would assign a task to a team member?

?Knowledge Check

What should the response look like when creating a task with invalid data?

Subscribe to our newsletter

Get the latest posts delivered right to your inbox.

Subscribe on LinkedIn