DEV Community

DevCorner
DevCorner

Posted on

API Best Practices: The Ultimate Guide

Introduction

APIs (Application Programming Interfaces) act as bridges between different systems, enabling them to communicate. A well-designed API ensures scalability, maintainability, and security. This guide covers best practices for designing, developing, and maintaining APIs, particularly in Spring Boot.


1. API Design Best Practices

1.1 Use RESTful Principles

  • Use nouns in resource URLs (avoid verbs).
  • Follow CRUD operations mapping:
    • GET /users → Fetch users
    • POST /users → Create a user
    • PUT /users/{id} → Update a user
    • DELETE /users/{id} → Delete a user

Bad API Design:

POST /createUser  
GET /fetchUserDetails?id=123  
Enter fullscreen mode Exit fullscreen mode

Good API Design:

POST /users  
GET /users/123  
Enter fullscreen mode Exit fullscreen mode

1.2 Use Versioning

APIs evolve over time. Use versioning to ensure backward compatibility.

Approaches:

  1. URI versioning: GET /v1/users
  2. Query parameter: GET /users?version=1
  3. Header-based versioning: Accept: application/vnd.myapi.v1+json

Best practice: Use URI versioning for simplicity.


1.3 Use Proper HTTP Methods

HTTP Method Purpose
GET Retrieve a resource
POST Create a resource
PUT Update a resource (entire)
PATCH Update a resource (partial)
DELETE Remove a resource

1.4 Use Consistent and Predictable Status Codes

Status Code Meaning
200 OK Successful request
201 Created Resource created
204 No Content No response body (DELETE)
400 Bad Request Invalid input
401 Unauthorized Authentication required
403 Forbidden Insufficient permissions
404 Not Found Resource not found
409 Conflict Conflict (duplicate data)
500 Internal Server Error Server-side issue

Example in Spring Boot:

@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
    return ResponseEntity.ok(userService.getUserById(id));
}
Enter fullscreen mode Exit fullscreen mode

2. Response Handling & Error Management

2.1 Use Consistent JSON Responses

Return structured JSON responses instead of plain text messages.

Example:

{
  "timestamp": "2025-03-20T12:00:00Z",
  "status": 404,
  "error": "Not Found",
  "message": "User not found",
  "path": "/users/123"
}
Enter fullscreen mode Exit fullscreen mode

Spring Boot Exception Handling:

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleResourceNotFound(ResourceNotFoundException ex) {
        ErrorResponse error = new ErrorResponse(LocalDateTime.now(), 404, "Not Found", ex.getMessage());
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
    }
}
Enter fullscreen mode Exit fullscreen mode

3. Pagination, Filtering, and Sorting

3.1 Pagination

Large datasets should be paginated to improve performance.

Example API Call:

GET /users?page=2&size=10
Enter fullscreen mode Exit fullscreen mode

Spring Boot Implementation:

@GetMapping
public ResponseEntity<Page<User>> getUsers(Pageable pageable) {
    return ResponseEntity.ok(userService.getUsers(pageable));
}
Enter fullscreen mode Exit fullscreen mode

3.2 Sorting

Allow sorting results dynamically.

Example API Call:

GET /users?sort=name,asc
Enter fullscreen mode Exit fullscreen mode

Spring Boot Implementation:

@GetMapping
public ResponseEntity<List<User>> getUsers(@RequestParam String sortBy) {
    List<User> users = userService.getUsersSorted(sortBy);
    return ResponseEntity.ok(users);
}
Enter fullscreen mode Exit fullscreen mode

3.3 Filtering

Allow filtering based on fields.

Example API Call:

GET /users?role=admin&active=true
Enter fullscreen mode Exit fullscreen mode

4. Security Best Practices

4.1 Use Authentication & Authorization

Implement OAuth2, JWT, or API keys to secure APIs.

Spring Security with JWT:

public class JwtRequestFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
        // Extract JWT, validate, and set authentication context
    }
}
Enter fullscreen mode Exit fullscreen mode

4.2 Avoid Exposing Sensitive Data

Mask passwords, tokens, or internal error messages in API responses.

Example:

{
  "id": 123,
  "username": "john_doe",
  "email": "hidden"
}
Enter fullscreen mode Exit fullscreen mode

4.3 Use HTTPS

Always enforce HTTPS to protect data in transit.


4.4 Rate Limiting

Prevent abuse by setting API rate limits (e.g., 100 requests per minute).

Spring Boot Implementation (Bucket4j):

@Bean
public FilterRegistrationBean<RateLimitFilter> rateLimitFilter() {
    return new FilterRegistrationBean<>(new RateLimitFilter());
}
Enter fullscreen mode Exit fullscreen mode

5. API Caching for Performance

5.1 Use HTTP Caching Headers

  • Cache-Control: Cache-Control: max-age=3600
  • ETag: ETag: "abc123"

5.2 Use Redis for Caching

@Cacheable(value = "users", key = "#id")
public User getUserById(Long id) {
    return userRepository.findById(id).orElseThrow();
}
Enter fullscreen mode Exit fullscreen mode

6. Logging & Monitoring

6.1 Centralized Logging

Use ELK Stack (Elasticsearch, Logstash, Kibana) or Grafana for log aggregation.

private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);

@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
    LOGGER.info("Fetching user with ID: {}", id);
    return ResponseEntity.ok(userService.getUserById(id));
}
Enter fullscreen mode Exit fullscreen mode

6.2 API Metrics & Monitoring

Use Spring Boot Actuator for monitoring API health.

Enable Actuator Endpoints:

management:
  endpoints:
    web:
      exposure:
        include: health,metrics
Enter fullscreen mode Exit fullscreen mode

7. API Documentation

Use Swagger for API documentation.

Add Swagger Dependency:

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.0.0</version>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Access API Docs:

http://localhost:8080/swagger-ui.html
Enter fullscreen mode Exit fullscreen mode

Conclusion

By following these best practices, your APIs will be:

Scalable

Secure

Maintainable

Performant

Would you like a downloadable PDF version of this guide?

AWS Q Developer image

Your AI Code Assistant

Implement features, document your code, or refactor your projects.
Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

Top comments (0)

Playwright CLI Flags Tutorial

5 Playwright CLI Flags That Will Transform Your Testing Workflow

  • 0:56 --last-failed
  • 2:34 --only-changed
  • 4:27 --repeat-each
  • 5:15 --forbid-only
  • 5:51 --ui --headed --workers 1

Learn how these powerful command-line options can save you time, strengthen your test suite, and streamline your Playwright testing experience. Click on any timestamp above to jump directly to that section in the tutorial!

Watch Full Video 📹️

👋 Kindness is contagious

DEV is better (more customized, reading settings like dark mode etc) when you're signed in!

Okay