Search code examples
javaspring-bootrest

@RequestParam with Optional Spring REST


I have a Spring REST endpoint with Optional request params like below:

public ResponseEntity<Product> globalProduct(@RequestParam Optional<Integer> id, @RequestParam Optional<String> name){

return ResponseEntity.ok(tm));
}

when I'm trying to test this endpoint which uses Mockito framework

@Test                                                                               
public void testGlobalProduct() throws Exception {                        
    URI uri = UriComponentsBuilder.fromPath("/api/products")                  
            .queryParam("id", Optional.of(1)                                               
            .queryParam("name", Optional.empty())                                 
            .build().toUri();                                                       
    mockMvc.perform( MockMvcRequestBuilders.get(uri)                                
            .accept(MediaType.APPLICATION_JSON))                                    
            .andExpect(status().isOk())                                             
            .andExpect(content().contentType(MediaType.APPLICATION_JSON))           
            .andDo(MockMvcResultHandlers.print())                                   
            .andReturn();                                                           
} 

So the queryParams id and name should be Optional.of(1) and Optional.empty() , but when I debug in the rest api implementaion I see id and name has been wrapped with values Optional[Optional[1]] and Optiona[Optional.empty]] .

I know I can use @RequestParams(required=false) but I dont want to use that way in this context.

How do we unwrap Optional[Optional[1]] Optiona[Optional.empty]] Is this correct? Any suggestions please?

Thanks in Advance!


Solution

  • It's working. I put default value for param 'name'

    public ResponseEntity<Product> globalProduct(@RequestParam Optional<Integer> id,  @RequestParam(value = "") Optional<String> name){
    
            return ResponseEntity.ok(tm));
       }
    

    And I did not pass any requestParam from the test, so it defaults to empty. It works.

    @Test                                                                               
    public void testGlobalProduct() throws Exception {                        
        URI uri = UriComponentsBuilder.fromPath("/api/products")                  
                .queryParam("id", Optional.of(1)                                               
                .build().toUri();                                                       
        mockMvc.perform( MockMvcRequestBuilders.get(uri)                                
                .accept(MediaType.APPLICATION_JSON))                                    
                .andExpect(status().isOk())                                             
                .andExpect(content().contentType(MediaType.APPLICATION_JSON))           
                .andDo(MockMvcResultHandlers.print())                                   
                .andReturn();                                                           
    } 
    

    Thanks all for suggestions.