
In this article, I will discuss some key points that we need to consider when creating REST APIs. This is a practical guide focused on improving the design, performance, and usability of RESTful APIs. Learn best practices, avoid common pitfalls, and build APIs that are clean, efficient, and developer-friendly.
🔷 Do not expose domain models
- If you expose domain objects as the return, it will tightly couple your domain objects. In the future, you may have changes. On that day, you will have to refactor many things.
- Domain objects should be dedicated to the domain, rather than serving as representation objects or DTOs.
- Another reason is that there will be a security risk of exposing sensitive data.
- A domain object may have relationships with other domain objects. So you may get additional performance issues as well.
DO NOT ❌
@GetMapping("...")
public List<Client> getClients(){
...
}DO ✅
@GetMapping("...")
public ResponseEntity<ApiResponse> getClients(){
...
}🔷 Use dedicated DTOs
- Use dedicated DTOs for each task.
- For example, createClientDto and updateClientDto.
- Because updateClientDto may have the id, but it is not available in createClientDto.
- Now you can use Java records as well.
public record CreateClientInput(
String clientName,
String clientCode,
String clientDescription,
Boolean isActive,
String createdBy) {}🔷 Never return a stacktrace in APIs
- Stacktrace may contain the exact reason for an error, line numbers, class names, etc. You are helping a hacker 🤷♂️
- We should not expose these details as the output of the API. But we can log them for our internal investigations.
- Instead of returning a stacktrace, a meaningful message can be returned.
🔷 Do not use the POST method for everything
- Each HTTP method has its own work.
- Some developers use POST for everything. This is doubtful.
GET — Retrieve data
POST — Send data to create a new resource
PUT — Update existing resource with new data
DELETE — Delete a resource
PATCH — Update a specific field in a resource
- If you use the POST method to retrieve data, it violates the HTTP standard. Also, you may not be able to use the advantages of the GET method, like caching.
Wait but,
If your queries are complex, it’s better to use the POST method; otherwise, the URL may become too long, and some older browsers might not handle it properly.
🔷 Make your URLs as short as possible
- Always try to use short URLs in a standardized way that meets your requirements.
- Avoid using long phrases in URLs, use short, meaningful phrases.
- Move sensitive data to the header section. Ex. Auth tokens
- For the complex queries, you may have to use POST to keep your URLs short.
- You need to use query params for searching, filtering, and pagination.
- You can use path variables for identifying objects. Ex: FindById
🔷 Build a custom response object

- As I explained before, do not use domain objects as the response.
- Instead, you can create a separate response object with the details that the frontend requires.
- This article will show “How to create a custom response object”
🔷 Use HTTP status codes meaningfully
- Do not return the 200 status code for everything.
- Each status code has its own meaning.
200, 201, 204 —Success
301, 302, 304 — Redirection
400, 401, 403, 404 — Client errors
500, 502, 503, 504 — Server erros
🔷 Using verbs in APIs
- It is not recommended to use verbs in REST APIs.
- Because HTTP methods themselves have meanings. (get, post, delete…etc)

- However, sometimes we must use verbs when creating meaningful endpoints. Ex: /send-mail
- Use kebab-case. Because it is readable. Ex: /client-profile
🔷 Handle exceptions and return a meaningful message
- You need to handle exceptions in each layer, but never return a stacktrace or a meaningless message like “Error occurred, internal error,” etc.
- It would be better if you could also return the error code with the error message.
No comments: