Proper vs. Improper Way to Implement CRUD in RESTful Services

In this quick recipe, we'll explore the proper and improper ways to implement CRUD (Create, Read, Update, Delete) operations in RESTful services

Proper Way to Implement CRUD in Spring Boot

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

    @Autowired
    private UserService userService;

    // Create
    @PostMapping
    public ResponseEntity<Object> createUser(@RequestBody User user, UriComponentsBuilder uriBuilder) {
        User createdUser = userService.saveUser(user);

        // Create URI of the created user using UriComponentsBuilder parameter
        URI location = uriBuilder.path("/api/users/{id}")
                                 .buildAndExpand(createdUser.getId())
                                 .toUri();

        return ResponseEntity.created(location).build();
    }

    // Read
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userService.findById(id);
        return ResponseEntity.ok(user);
    }

    // Update
    @PutMapping("/{id}")
    public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User userDetails) {
        User updatedUser = userService.updateUser(id, userDetails);
        return ResponseEntity.ok(updatedUser);
    }

    // Delete
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
        return ResponseEntity.noContent().build();
    }
}

Service Layer:

Assuming basic CRUD operations are defined in the UserService.

Improper Way to Implement CRUD in Spring Boot

Controller:

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

    @Autowired
    private UserService userService;

    // Create
    @GetMapping("/createUser") // Incorrect HTTP method and URI
    public User createUser(@RequestBody User user) {
        return userService.saveUser(user);
    }

    // Read
    @PostMapping("/getUser") // Incorrect HTTP method and URI
    public User getUserById(@RequestParam Long id) {
        return userService.findById(id);
    }

    // Update
    @GetMapping("/updateUser/{id}") // Incorrect HTTP method and URI
    public User updateUser(@PathVariable Long id, @RequestBody User userDetails) {
        return userService.updateUser(id, userDetails);
    }

    // Delete
    @GetMapping("/deleteUser") // Incorrect HTTP method and URI
    public void deleteUser(@RequestParam Long id) {
        userService.deleteUser(id);
    }
}

Key Points:

  • HTTP Methods: The proper implementation uses HTTP methods according to REST principles (POST for creation, GET for reading, PUT for updating, and DELETE for deletion). The improper way misuses HTTP methods, leading to semantic confusion and potential security risks.

  • URI Structure: A RESTful URI should be descriptive and hierarchical, focusing on resources rather than actions. The proper example uses /api/users with resource IDs for specific operations, while the improper example uses action-based URIs like /createUser, which is not recommended.

  • Response Entity: The proper way uses ResponseEntity to provide more control over the HTTP response, allowing for the setting of status codes and headers. The improper way returns the model directly, limiting the ability to respond with appropriate HTTP status codes or headers.

This recipe highlights the importance of adhering to RESTful principles and Spring Boot best practices to create clear, efficient, and maintainable API endpoints.

Last updated

Need US based Java Developers

Visit Katyella

Katyella LLC http://katyella.com