In Core Program’s API Testing Tools chapter, you called APIs using curl and Postman. In that role, you were the client.
Now you are switching sides. You will design and build the server. Before you write Spring Boot code, you need a clear mental model for what makes a REST API predictable and pleasant to use.
This chapter covers the design principles behind REST. You will not write Java here. Instead, you will learn how to choose resources, URIs, HTTP methods, headers, and status codes like a backend developer.
The term API gets used constantly because it can mean many things. At its core, it means exactly what the name says: an Application Programming Interface.
Think of it like this.
You run a successful web shop where customers place orders manually through the UI. Then a few companies start buying the same materials from you every week. If the process stays manual, it quickly becomes painful. They do not want to keep logging in and clicking buttons. They want their systems to talk directly to yours and place repeat orders automatically.
That is where an API comes in.
Instead of giving another company access to your website’s buttons and forms, which are designed for humans, you expose a programming interface: a set of clear, documented endpoints that other software can call directly. Their developers can then program their application to use your interface:
flowchart LR
classDef client fill:#fff7ed,stroke:#f97316,stroke-width:2px,color:#7c2d12,rx:20,ry:20,font-size:15
classDef clientCompact fill:#fff7ed,stroke:#f97316,stroke-width:2px,color:#7c2d12,rx:20,ry:20,font-size:13
classDef frontend fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e3a8a
classDef api fill:#faf5ff,stroke:#9333ea,stroke-width:3px,color:#581c87
classDef backend fill:#f0fdf4,stroke:#16a34a,stroke-width:2px,color:#14532d
subgraph ExternalWorld[External world]
direction TB
Human[👤 customers]
Company1[🏢 System1]
Company2[🏢 System2]
style ExternalWorld width:200px
end
subgraph WebShop[Your web shop]
direction TB
Frontend[Web frontend<br/>React, Vue... ]
API[API<br/>/api/orders<br/>/api/products<br/>/api/users]
Backend[Backend server<br/>Implementation]
end
class Human,Company1,Company2 client
class Frontend frontend
class API api
class Backend backend
Human -->|Browser<br/>mobile app| Frontend
Frontend -->|HTTP<br/>requests| API
Company2 -->|HTTP<br/>requests| API
Company1 -->|HTTP<br/>requests| API
API -->|Process| Backend
<aside> 💡
If you would like to dive deeper into APIs, check out the extra resources section for more reading/watching material or a common design mistake that can cost teams a lot of development time.
</aside>
<aside> ⚠️
Please keep in mind that our API example above has a bias towards Web APIs. However, APIs can also be for hardware in which hardware-specific implementation details are abstracted behind an API for end-user-facing programs. Eg: WASAPI (Windows Audio Streaming API), Core Audio (Mac, also API), OpenGL and more…
The term is also used within Java. Eg: Java Networking API under java.net
</aside>
In Week 9 - Networking and APIs you learned that REST stands for Representational State Transfer and that a RESTful API uses standard HTTP methods and structured URLs to manage resources. Let's deepen that.
REST is an architectural style: a set of design constraints for building web APIs. It is not a protocol, not a library, and not a single tool you install. When you follow REST principles, your API becomes more consistent, predictable, and easier for clients to use.
The practical REST constraints for this course are:
There are two more REST constraints, layered system and optional code-on-demand. They matter more for system architecture than for the basic API design work in this chapter.
<aside> ⚠️
“REST” is used loosely in the industry. Many APIs called “REST APIs” do not follow every REST constraint strictly.
</aside>
In everyday backend work, focus on three habits first: model resources clearly, use HTTP methods correctly, and return meaningful status codes.
In comparison to other architectural styles, REST revolves around the concept of resources. Clients interact with representations of resources provided by a RESTful API. For retrieval, each resource has a unique identifier: a URI.
Let’s briefly go over Resources and their unique identifier, URIs.
In REST, a resource is any concept your API exposes: a user, product, order, review, category, invoice, or payment.
Resources naturally represent your domain. If your application has users and users have orders, then users and orders are resources your API might expose a representation* of.
<aside> ⚠️
Clients never interact with the resource directly. Instead, they interact with representations of a resource (usually JSON, XML, etc.).
</aside>
<aside> 💡
Many APIs today that are called "REST" are actually more RPC-like because they focus on operations (/getUser, /createOrder) instead of resources (/users, /orders). True REST requires thinking in resources first.
</aside>
You’ve already learned about URLs (With an L), in URL Format. They are strict in locating a resource right from the scheme ( http:// , file:/// ) which they will always have.
A URI (Uniform Resource Identifier) on the other hand, identifies a resource. A URI can also be a URL but not always whereas all URLs are URIs. The table below should visualize the difference:
| string type | format | notes |
|---|---|---|
| URI | mailto:someone@... |
Identifies an email address |
| URI | /users/123 |
Identifies an API resource |
| URL/URI | ftp://... |
Locates an identified file resource |
| URL/URI | https://... |
Locates an identified web resource |
<aside> 💡
In everyday API conversations, developers often say “URL” when they mean the web address of an endpoint. In REST design, “URI” emphasizes the idea that the address identifies a resource.
</aside>
Good URI design makes your API easier to guess, read, and document.
Use nouns, not verbs. The HTTP method provides the action. The URI identifies the resource.
| Good | Bad | Why |
|---|---|---|
GET /users |
GET /getUsers |
GET already means "read" |
POST /users |
POST /createUser |
POST already means "create" |
DELETE /users/42 |
POST /deleteUser?id=2 |
DELETE already means "remove" |
Use plural nouns. A collection endpoint represents a group of resources.
| Good | Bad |
|---|---|
/products |
/product |
/orders |
/order |
Use path segments for hierarchy. When one resource belongs to another, nest the path:
/users/42 : user with ID 42/users/42/orders : all orders belonging to user 42/users/42/orders/7 : order 7 of user 42Use query parameters for filtering and sorting. Query parameters do not identify a different resource. They narrow or organize a collection:
/products?category=electronics : products filtered by category/products?sort=price&order=asc : products sorted by ascending price<aside> ⌨️
</aside>
HTTP methods tell the server what kind of action the client wants to perform on a resource.
Two words are useful here:
GET should be safe.From the server developer’s perspective, here is what each method usually means:
| --- | --- | --- | --- | --- | --- |
<aside> 💡
</aside>
💬 If a client sends a DELETE request for a resource that does not exist, should the server return 404 or 204?
You will see many HTTP headers over time. For REST API development, these three are especially important: Content-Type, Accept, and Authorization.
Content-TypeContent-Type tells the recipient what format the body is in. For REST APIs, this is usually JSON:
Content-Type: application/json
The sender of the body sets this header. When a client sends a POST request with JSON, the client sets Content-Type: application/json. When your server responds with JSON, your server sets it on the response.
AcceptAccept tells the server what format the client wants in the response:
Accept: application/json
This is called content negotiation: the client and server agree on a response format. If the server cannot produce the requested format, it can respond with 406 Not Acceptable.
In practice, most REST APIs use JSON, so this header is often application/json or */*, which means “accept any format.”
AuthorizationAuthorization carries the client’s credentials, usually a token:
Authorization: Bearer <token>