7.3 Resources and Endpoints
Table of Contents
Understanding Resources and Endpoints
In REST, almost everything starts with two ideas: resources and endpoints. If you understand these well, the rest of REST becomes much easier.
This chapter focuses only on what resources and endpoints are, how to design them, and many concrete examples. Other topics, like HTTP methods and status codes, have their own chapters.
What Is a Resource?
A resource is an object or concept in your system that you want to expose through your API.
You can think of a resource as "a kind of thing" that your API works with.
Some common resource examples:
| Domain | Possible resources |
|---|---|
| Task manager | users, tasks, projects, comments |
| E commerce | products, categories, orders, carts, reviews |
| Blogging platform | posts, users, comments, tags |
| School system | students, courses, enrollments, teachers |
| Social network | users, posts, likes, followers, messages |
You rarely expose every internal object as a resource. You choose the things that make sense to clients of the API.
Key points about resources:
- A resource represents a type of thing, not a single item.
- Example: βtasksβ is a resource type. A particular task with id
42is a resource instance. - Resources can be real world things or conceptual things.
- Real world:
user,product,order. - Conceptual:
auth-token,report,search-result. - Resources usually have:
- A name (like
usersororders) - A representation (usually JSON data)
- A way to identify individual items (like an
id)
Important rule:
Think first about resources (the nouns), then about how to operate on them (the verbs / HTTP methods).
Do not start with actions like /createUser or /deleteOrder. Design the things first.
Identifying Resources
To identify resources in a system, imagine you are explaining your application without any code.
Example: Task management app. You might say:
- "Users can create tasks"
- "Tasks can belong to projects"
- "Each task can have comments and tags"
From this description, you can spot the nouns:
userstasksprojectscommentstags
These are good candidates for resources.
Exercise in your mind
Take a simple "online course platform" and list candidates:
- "Students enroll in courses"
- "Courses have lessons"
- "Lessons have quizzes"
- "Teachers create courses"
Nouns:
- students
- courses
- lessons
- quizzes
- teachers
- enrollments (this is a relationship, but often becomes a resource too)
You do not have to expose all of them. You choose what is useful:
- Maybe you expose
students,courses,lessons,enrollments. - Maybe you hide
teachersbehind an admin API.
What Is an Endpoint?
An endpoint is a URL path that represents a resource (or resources) in your API.
Formally, an endpoint is the combination of:
- A URL path, for example
/usersor/tasks/42/comments - An HTTP method, for example
GETorPOST
You will study methods in detail in other chapters, but for now you can think:
GET /resourceβ retrievePOST /resourceβ createPUT/PATCH /resource/idβ updateDELETE /resource/idβ delete
Examples of endpoints:
| Endpoint | What it refers to |
|---|---|
GET /users | the collection of users |
POST /users | the collection of users (create a new one) |
GET /users/10 | a single user with id 10 |
GET /projects/5/tasks | tasks that belong to project 5 |
DELETE /orders/99 | the order with id 99 |
Notice that the path itself is usually just nouns.
The action is expressed by the HTTP method, not by the path.
Important rule:
Endpoints should use nouns in URLs and HTTP methods for actions, for example:
POST /users(create user)
Not:/createUser
Collections vs Individual Resources
Usually, each resource type has:
- A collection endpoint
- One or more single resource endpoints
Collection endpoints
A collection is the list or set of all items of a resource.
Typical patterns:
GET /tasksβ list all tasks, or tasks for the current userPOST /tasksβ create a new task
The same applies for other resources:
| Resource | Collection endpoints |
|---|---|
| users | GET /users, POST /users |
| orders | GET /orders, POST /orders |
| products | GET /products, POST /products |
| comments | GET /comments, POST /comments |
Later, you may add query parameters for filtering, pagination, and so on, but the base collection endpoint is usually just the plural noun.
Single resource endpoints
A single resource endpoint refers to one specific item, often by ID.
Typical patterns:
GET /tasks/{task_id}β get one taskPUT /tasks/{task_id}/PATCH /tasks/{task_id}β update an existing taskDELETE /tasks/{task_id}β delete a task
Examples for different resources:
| Resource | Single resource endpoints (examples) |
|---|---|
| user | GET /users/123, PATCH /users/123 |
| order | GET /orders/55, DELETE /orders/55 |
| product | GET /products/999, PUT /products/999 |
Here {task_id}, {user_id}, {order_id} are path parameters that identify a particular item of the resource.
You will learn path parameters in more detail in another chapter. For now, just understand that they are part of the URL and used to uniquely identify a resource instance.
Naming Resources and Endpoints
Naming is important for a clean API. There is no single universal rulebook, but there are strong conventions that most APIs follow.
Use plural nouns for collections
Most APIs use plural nouns for the main collection endpoints.
Good examples:
/users/tasks/orders/products/posts/comments
Then single items are under those collections:
/users/1/tasks/42/orders/2023001
Some APIs use singular nouns (like /user), but plural is far more common and easier to reason about:
/users= collection/users/{id}= single item in that collection
Important rule:
Use plural nouns for top level resource collections: /users, /orders, /products.
Keep it consistent across your entire API.
Use lowercase and hyphens
For readability and consistency:
- Use lowercase letters
- Use hyphens
-to separate words, not underscores_or spaces - Avoid camelCase in URLs
Examples:
| Prefer | Avoid |
|---|---|
/user-profiles | /userProfiles |
/order-items | /order_items |
/product-reviews | /ProductReviews |
You may see underscores in some APIs, but hyphens are more common in URL paths.
Avoid verbs in URLs
The path represents resources, which are nouns, not actions.
Good:
POST /usersto create a userDELETE /users/1to delete a userPOST /orders/123/cancel(special case, discussed later)
Avoid:
POST /createUserGET /getAllUsersPOST /deleteUser
The HTTP method already tells you the action. The endpoint path should describe what the method is applied to.
Consistent naming patterns
Try to keep resource names consistent:
- Use the same word across your API:
- Do not mix
/usersand/accountsfor the same thing. - Do not mix singular and plural randomly:
- Pick
/productsrather than having both/productsand/product.
Hierarchical Endpoints and Subresources
Some resources have a natural parent child relationship. For example:
- A project has many tasks
- A post has many comments
- A user has many orders
In these cases, you can express the relationship in your endpoints.
Parent-child collections
Examples:
GET /projects/10/tasksβ tasks that belong to project 10POST /projects/10/tasksβ create a new task under project 10GET /posts/3/commentsβ comments for post 3POST /posts/3/commentsβ add a comment to post 3
Here, tasks and comments are often called subresources or nested resources of the parent.
Individual child resources
Sometimes you also access an individual child resource through the parent.
For example:
GET /projects/10/tasks/5
Task 5, which belongs to project 10.DELETE /posts/3/comments/8
Comment 8 on post 3.
Technically, GET /tasks/5 and GET /projects/10/tasks/5 might refer to the same task.
Some APIs:
- Choose only flat endpoints, like
/tasks/5 - Others allow both flat and nested forms
As a beginner, a simple and common choice is:
- Use flat endpoints for normal CRUD:
GET /tasks,GET /tasks/5, etc.- Use nested endpoints when the parent is always needed or when listing children:
GET /projects/10/tasks
When to nest, when not to nest
Nesting is useful when:
- The child resource only makes sense in the context of a parent.
- Example:
commentsmake sense only for apost. - You usually operate on children through the parent.
- Example: listing tasks per project.
Too much nesting becomes confusing:
/users/1/projects/10/tasks/5/comments/2is hard to read and maintain.
A simple guideline:
- Try to keep nesting at 1 level deep:
/projects/{project_id}/tasks/posts/{post_id}/comments- Avoid more than 2 or 3 levels of nesting.
Relationships and Linking Resources
Resources often have relationships with each other.
Common relationships:
- One to many
- One user has many orders:
GET /users/1/orders - Many to many
- Many users can join many groups:
GET /users/1/groups,GET /groups/5/users
You can represent these relationships in different ways.
Example: Users and Orders
Resources:
usersorders
Possible endpoints:
| Purpose | Endpoint |
|---|---|
| List all users | GET /users |
| Get one user | GET /users/{user_id} |
| List all orders | GET /orders |
| Get one order | GET /orders/{order_id} |
| List orders for a specific user | GET /users/{user_id}/orders |
The API response for GET /users/1 might include links to related resources, for example:
{
"id": 1,
"name": "Alice",
"email": "alice@example.com",
"links": {
"self": "/users/1",
"orders": "/users/1/orders"
}
}This is one way of making relationships discoverable.
Example: Many to many with join resources
Sometimes, a relationship itself becomes its own resource.
Example: A user can enroll in many courses, and a course has many users. The enrollment can be a resource:
studentscoursesenrollments
Possible endpoints:
POST /enrollmentswith body{ "student_id": 1, "course_id": 5 }GET /students/1/enrollmentsGET /courses/5/enrollments
Here, enrollments is a resource that connects two other resources.
Representing a Resource
An endpoint returns a representation of a resource, usually in JSON.
Example resource: task
A typical JSON representation:
{
"id": 42,
"title": "Write API chapter",
"description": "Explain resources and endpoints",
"status": "in_progress",
"project_id": 3,
"created_at": "2026-08-27T10:15:00Z",
"updated_at": "2026-08-27T11:00:00Z"
}Different endpoints can return different views of the same resource:
GET /tasks/42might return full details.GET /tasksmight return a shorter summary for each task:
[
{
"id": 42,
"title": "Write API chapter",
"status": "in_progress"
},
{
"id": 43,
"title": "Review examples",
"status": "todo"
}
]You will study response models and validation in other chapters. Here, focus on the idea that each endpoint is tied to a resource and returns a sensible representation of it.
Examples of Resource and Endpoint Design
To make these ideas concrete, look at some mini APIs.
Example 1: Simple Task API
Resources:
userstasksprojects
Endpoints:
| Purpose | Endpoint |
|---|---|
| List all tasks | GET /tasks |
| Create a new task | POST /tasks |
| Get a single task | GET /tasks/{task_id} |
| Update a task | PATCH /tasks/{task_id} |
| Delete a task | DELETE /tasks/{task_id} |
| List tasks for a specific project | GET /projects/{project_id}/tasks |
| List projects | GET /projects |
| Create a project | POST /projects |
| Get a project | GET /projects/{project_id} |
Notice:
- Collections:
/tasks,/projects - Singles:
/tasks/{id},/projects/{id} - Nested:
/projects/{id}/tasks
No verbs in URLs, only nouns.
Example 2: E commerce API
Resources:
productscategoriescartscart-itemsordersusers
Some endpoints:
| Purpose | Endpoint |
|---|---|
| Browse products | GET /products |
| Get a product | GET /products/{product_id} |
| Browse products in a category | GET /categories/{category_id}/products |
| Get all categories | GET /categories |
| View current user's cart | GET /carts/current |
| Add item to cart | POST /carts/current/items |
| Update quantity of an item in cart | PATCH /carts/current/items/{item_id} |
| Remove item from cart | DELETE /carts/current/items/{item_id} |
| Place an order from current cart | POST /orders |
| Get user's orders | GET /users/{user_id}/orders |
Note a special case: carts/current. That is a resource that represents "the current user's cart," which is a bit more conceptual but still a resource. We will talk about such special resources next.
Special Resources and Action-like Endpoints
Sometimes you need to represent operations that are not simple CRUD on a single resource. Examples:
- Login
- Password reset
- "Cancel" an order
- "Complete" a task
There are different ways to model these.
Conceptual resources
You can model some actions as resources themselves.
Examples:
- An authentication token can be a resource:
POST /tokenswith username and password to create a tokenDELETE /tokens/currentto log out- A password reset request can be a resource:
POST /password-reset-requeststo ask for a reset email
Even though these feel like "actions," you expose them as resources that you create or delete.
Action subresources
Sometimes people use a subresource that looks like an action.
For example, canceling an order:
POST /orders/123/cancel
Here, cancel behaves like a subresource that represents "the cancel operation for this order." The HTTP method POST is still used. This is common and practical, even if it is not purely "resource oriented."
Other examples:
POST /tasks/42/completePOST /users/10/lockPOST /users/10/unlock
You should not overuse this pattern, but it is acceptable for important actions that do not fit perfectly into standard CRUD.
Versioning and Endpoint Structure (Preview)
You will learn API versioning in a dedicated chapter, but here is how resources and endpoints often look when versioned.
Common pattern:
GET /v1/usersGET /v1/tasks/42
The resource names and endpoint structure stay the same, but you prefix them with a version, usually as a first path segment.
Example:
| Version 1 | Version 2 |
|---|---|
GET /v1/tasks | GET /v2/tasks |
GET /v1/users/{user_id}/tasks | GET /v2/users/{user_id}/tasks |
The idea is that clients who use /v1/... are not broken by changes in /v2/....
Checklist for Designing Resources and Endpoints
When designing a new REST API, you can walk through this checklist.
- List your domain nouns.
- What are the main things in your system?
- Example: users, tasks, projects, comments.
- Decide which nouns become resources.
- Not every internal object must be exposed.
- Start with the biggest, most important ones.
- Name collections with plural nouns.
/users,/tasks,/projects- Define collection and single resource endpoints.
- Collection:
GET /tasks,POST /tasks - Single:
GET /tasks/{task_id},PATCH /tasks/{task_id},DELETE /tasks/{task_id} - Identify relationships and nested endpoints.
- Parent child:
GET /projects/{project_id}/tasks,GET /posts/{post_id}/comments - Avoid verbs in paths.
- Use HTTP methods to express actions.
- Only use action-like subresources when you really need them:
/orders/{id}/cancel. - Keep nesting shallow.
- Prefer at most one level:
/projects/{id}/tasks. - Avoid very deep URLs.
- Choose consistent naming style.
- Lowercase, hyphens, plural nouns.
If you follow this checklist, your resources and endpoints will be much easier to understand, both for you and for other developers who use your API.
By now you should be comfortable with the ideas of resources and endpoints, how to identify resources in a domain, and how to map them to clear, consistent URLs. In the following chapters, you will see how HTTP methods, status codes, and other REST concepts build on this foundation.
Views: 8
KAHIBARO