0

I am trying to retrieve a user's particular order.


This is how I retrieve the user's orders in my OrderController

@GetMapping("/{id}/orders")
public List<Order> findAll(@PathVariable Long id) throws UserNotFoundException {
    Optional<User> existingUser = this.userRepository.findById(id);

    if (existingUser.isEmpty()) {
        throw new UserNotFoundException("User not found");
    }

    return existingUser.get().getOrders();
}

With the RequestMapping

@RestController
@RequestMapping("/api/users")
public class OrderController {(...)}

This is the OneToMany relationship

User Entity

// ONE TO MANY
@OneToMany(mappedBy = "user")
private List<Order> orders;

Order Entity

// MANY TO ONE
@ManyToOne(fetch = FetchType.LAZY)
@JsonIgnore
private User user;

The UserRepository and OrderRepository interface, both extend JpaRepository


I do manage to retrieve all the user's orders through Postman

enter image description here


I am now wondering, how can I retrieve a user's particular order?

So for instance, as shown in the image let's say I would only like to retrieve the order with the id of 2, in this particular address :

http://localhost:8070/api/users/1/orders/2

How can I make it please ?

Daniel Jacob
  • 1,455
  • 9
  • 17
Finalmix6
  • 375
  • 8
  • 21
  • 1
    Did you try this one? https://stackoverflow.com/questions/11351015/multiple-pathvariable-in-spring-mvc – LuuBie May 26 '20 at 10:57

3 Answers3

1

Create an endpoint with

@GetMapping("/{id}/orders/{orderId}")

and return the particular order.

Create an OrderRepository and simply create the

public Order findByIdAndUserId(long orderId,long userId);

interface method for retrieving the given one.

Just a remark: you should validate that the given user is the same as the logged in one. What happen if I send a request to the backend, where I rewrite the user id to someone else's id?

zlaval
  • 1,941
  • 1
  • 10
  • 11
1

try this,

    @GetMapping("/{userId}/orders/{orderId}")
    public Order findAll(@PathVariable Long userId, @PathVariable Long orderId) throws Exception {
        //your code
    }
Erwin
  • 460
  • 2
  • 6
  • Thank you ! I was actually wondering how to solve it through the repository, but you helped me as well. Thanks. – Finalmix6 May 26 '20 at 11:05
1

Obviously you should had a Get mapping:

@GetMapping("/{userId}/orders/{orderId}")
public List<Order> findAll(@PathVariable Long userId, @PathVariable Long orderId) throws UserNotFoundException {
    ...
}

And for the requesting, you have three options:

  1. Call you this.userRepository.findById(id) and filter after your order.
  2. Create an OrderRepository to limit the request to the order table. But you need to have a reference to the user and you will probably not improve any performance. I would not advise that.
  3. Add a query in your order repository to query the orderId for the userId:

@Repository
public interface UserRepository extends JpaRepository<.., ..> {
    @Query("select ... from User user join user.orders ... where ...user = :userId and order = :orderId")
    Order getUserOrder(@Param("userId") String userId, @Param("orderId") String orderId);
}

Anyway, You should create a service and inject it in the controller to encapsulate the search/filtering complexity and let you endpoints code clean (@Autowired private OrderService orderService):

@RestController
@RequestMapping("/api/users")
public class OrderController {
    @Autowired
    private OrderService orderService;
}

and:

@Service
public class OrderService {

}
Nicolas Dupouy
  • 450
  • 1
  • 7
  • 11