Understanding REST Protocol and HTTP Methods with Java & Spring Boot

2 min read

Understanding REST Protocol and HTTP Methods with Java & Spring Boot

Introduction

REST (Representational State Transfer) is an architectural style used for designing networked applications. It relies on a stateless, client-server communication model and uses HTTP as its protocol. REST is widely adopted in web services, and Spring Boot makes it incredibly easy to build RESTful APIs.

In this article, we’ll explore how REST works, what each HTTP method means, and how to implement them using Spring Boot.


Core Concepts of REST

  • Stateless: No session data is stored on the server between requests.
  • Client-Server: The client and server are separate entities.
  • Cacheable: Responses must define themselves as cacheable or not.
  • Uniform Interface: Consistent way to interact with the service (typically via URIs and standard HTTP methods).
  • Resource-Based: Everything is considered a resource, identified by a URI (e.g., /users/1).

Common HTTP Methods in REST

MethodDescription
GETFetches data from the server
POSTCreates a new resource
PUTUpdates or replaces a resource
PATCHPartially updates a resource
DELETEDeletes a resource

What is Idempotency?

Idempotency means that making the same request multiple times has the same effect as making it once.

In RESTful design, this is important for safety and predictability—especially in situations like network retries. Let’s see how it applies to HTTP methods:

MethodIdempotentExplanation
GETYesRepeating a GET request does not change data. It only reads.
PUTYesReplacing a resource with the same data multiple times results in no change.
DELETEYesDeleting a resource multiple times results in the same state—it’s gone.
POSTNoRepeating POST creates new resources each time.
PATCHNoRepeating may incrementally change data depending on the patch logic.

Why Idempotency Matters

If a client times out after sending a request, it might retry. If the request isn’t idempotent (like a POST), it could unintentionally create duplicate resources. That’s why methods like PUT and DELETE are designed to be idempotent.

Building a REST API with Spring Boot

Let’s build a simple User API that supports all the HTTP methods.

Step 1: Project Setup

Make sure you have the following dependencies in your pom.xml:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

Step 2: Create the User Model

public class User {
    private Long id;
    private String name;
    private String email;

    // Constructors, getters, setters
}

Step 3: Create the Controller

@RestController
@RequestMapping("/users")
public class UserController {

    private Map<Long, User> userRepo = new HashMap<>();
    private AtomicLong idGenerator = new AtomicLong();

    // GET - Fetch all users
    @GetMapping
    public List<User> getAllUsers() {
        return new ArrayList<>(userRepo.values());
    }

    // GET - Fetch user by ID
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userRepo.get(id);
        return user != null ? ResponseEntity.ok(user) : ResponseEntity.notFound().build();
    }

    // POST - Create new user
    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        long id = idGenerator.incrementAndGet();
        user.setId(id);
        userRepo.put(id, user);
        return ResponseEntity.status(HttpStatus.CREATED).body(user);
    }

    // PUT - Replace user
    @PutMapping("/{id}")
    public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User updatedUser) {
        if (!userRepo.containsKey(id)) {
            return ResponseEntity.notFound().build();
        }
        updatedUser.setId(id);
        userRepo.put(id, updatedUser);
        return ResponseEntity.ok(updatedUser);
    }

    // PATCH - Partially update user
    @PatchMapping("/{id}")
    public ResponseEntity<User> patchUser(@PathVariable Long id, @RequestBody Map<String, Object> updates) {
        User user = userRepo.get(id);
        if (user == null) {
            return ResponseEntity.notFound().build();
        }

        if (updates.containsKey("name")) {
            user.setName((String) updates.get("name"));
        }

        if (updates.containsKey("email")) {
            user.setEmail((String) updates.get("email"));
        }

        return ResponseEntity.ok(user);
    }

    // DELETE - Remove user
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        if (userRepo.remove(id) == null) {
            return ResponseEntity.notFound().build();
        }
        return ResponseEntity.noContent().build();
    }
}

Testing the API

You can test the REST API using tools like Postman or cURL:

  • GET /users – List all users
  • POST /users – Create a user (with body)
  • PUT /users/1 – Replace the user with id 1
  • PATCH /users/1 – Partially update the user
  • DELETE /users/1 – Delete the user

Conclusion

The REST protocol provides a clean and scalable way to build APIs, and Spring Boot makes it incredibly easy to implement them. By understanding how HTTP methods map to CRUD operations, you can design intuitive and powerful APIs.

🤞 Never miss a story from us, get weekly updates to your inbox!

Leave a Reply

Your email address will not be published. Required fields are marked *