[CRUD 연습] RestTemplate으로 GET, POST
ResponseEntity<Long> responseEntity = restTemplate.postForEntity(url,requestDto,Long.class);
진짜 요즘 이 코드 한 줄로 엄청나게 많은 공부를 하고 있다.
책을 보면서 따라쳐볼 때는 몰랐지.. 이렇게까지 많은 것이 담겨 있을 줄이야..
진짜 잼민 펀치가 필요할 것 같다. 옥상,, 아니 카페로 따라와,,,
🥓 RestTemplate 사용해서 객체 GET, POST 해보기
이전 포스팅에서 한 번 다룬 내용이다. 그 때보다 더 구체적으로 공부해보았다!
참고로, 밑에서 사용할 restTemplate은 TestRestTemplate 객체의 인스턴스이다!
class MusicAPIControllerTest {
@Autowired
private TestRestTemplate restTemplate;
...
}
GET | POST | |
응답 형태 - Object | getForObject( ) | postForObject( ) |
응답 형태 - ResponseEntity | getForEntity( ) | postForEntity( ) |
위에 작성한 표처럼, 크게 4가지 방식을 사용할 수 있다. 하나하나 살펴보자.
1️⃣ GET 방식
// 1. 주어진 URL로 HTTP GET 요청 & Object로 결과를 반환받음
Employee employee = restTemplate.getForObject("http://localhost:8080/employee", Employee.class);
// 2. 주어진 URL로 HTTP GET 요청 & ResponseEntity로 결과를 반환받음
ResponseEntity<Employee> response = restTemplate.getForEntity("http://localhost:8080/employee", Employee.class);
GET 방식은 Deserialize(JSON → Java Object) 과정이라고 할 수 있다! (JSON 데이터 받아오는거니까!)
URI에 매핑된 JSON 형태의 데이터를 어떤 형태로 가져오냐 차이인데, 객체 타입으로 바로 받으면 getForObject 를 사용한다.
파라미터의 정보는 ① URL (말 그대로 주소), ② 리턴 타입 (어떤 형태의 그릇에 담을건지 정해라!) 으로 이루어져있다.
반면, getForEntity를 사용하면 ResponseEntity<T> 타입으로 받을 수 있는데,
ResponseEntity 객체 인스턴스를 사용해서 HTTP에 대한 추가 정보를 확인할 수 있는 것이 차이점이다.
response.getStatusCode() // HTTP Status Code를 확인할 수 있다. ex) 200, 201..
Employee newEmployee = response.getBody() // HTTP Body 부분에 담긴 데이터를 객체로 꺼낼 수 있다.
// ResponseEntity<타입> 부분에서 지정한 타입과 일치해야 한다!
위 코드처럼 getStatusCode( ) 메서드를 사용해 HTTP Status Code를 확인할 수 있고,
HTTP body 부분에 담긴 데이터를 꺼내서 받아올 수도 있다.
또한 getForEntity 에서 지정한 리턴 타입은, getBody( ) 를 했을 때 받을 리턴 타입과 일치해야한다.
쉽게 말해서, ResponseEntity<타입> 부분을 getBody( ) 로 벗겼을 때 나오는 '타입'을 지정한다고 생각하면 된다!
사실 getForObject 로 바로 꺼내오나, getForEntity 로 꺼내온 후 getBody( ) 로 꺼내나 똑같은 body 정보가 나온다.
하지만 ResponseEntity는 HTTP에 대한 추가 정보들을 확인할 수 있다는 유용한 점이 있다!
2️⃣ POST 방식
List<Employee> employeeList = new ArrayList<>();
employeeList.add(new Employee(3, "Intern"));
employeeList.add(new Employee(4, "CEO"));
// 1. 주어진 URL로 HTTP POST 요청 & Object로 결과를 반환받음
Employee employee = restTemplate.postForObject("http://localhost:8080/employee", employeeList, Employee.class);
// 2. 주어진 URL로 HTTP POST 요청 & ResponseEntity로 결과를 반환받음
ResponseEntity<Long> responseEntity = restTemplate.postForEntity("http://localhost:8080/employee", employeeList, Long.class);
POST 방식은 Serialize(Java Object → JSON) 과정이라고 할 수 있다! (객체 타입 데이터를 올리는거니까!)
파라미터가 하나 늘어났다. 왜냐! 객체 타입의 데이터를 POST 해야하지 않나!
파라미터의 정보는 ① URL (주소),② 객체 (데이터), ③ 리턴 타입 (어떤 형태의 그릇에 담을건지 정해라!) 으로 이루어져있다.
GET은 객체 타입으로 데이터를 받아와서, 해당 객체를 활용하는 방식이지만, POST는 올리면 끝이지 않나!
postForObject 에서 반환한 데이터는 활용성이 없는 것 같고, postForEntity 는 HTTP 정보라도 들고 있어 이를 활용할 수 있다.
(반환 값에 대해서 그렇게 큰 의미는 없다고 생각한다..! 활용하려면 얼마든지 활용은 가능하나, GET에 비해서는 떨어진다는 뜻)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class MusicAPIControllerTest {
@LocalServerPort private int port;
@Autowired private TestRestTemplate restTemplate;
@Test
void 등록() {
// given
MusicSaveRequestDto requestDto
= new MusicSaveRequestDto("Sneakers", "ITZY", "CHECKMATE", "Put my sneakers on!");
String url = "http://localhost:" + port + "/api/v1/music";
// when
ResponseEntity<Long> responseEntity
= restTemplate.postForEntity(url, requestDto, Long.class);
// then
List<Music> musicList = musicRepository.findAll();
assertThat(musicList.get(0).getTitle()).isEqualTo(requestDto.getTitle());
assertThat(responseEntity.getStatusCode()).isEqualTo(OK);
assertThat(responseEntity.getBody()).isEqualTo(2);
}
}
위 코드는 등록(POST)에 대한 테스트 코드인데, when 부분만 살펴보면 requestDto 객체를 POST 하였다.
그리고 ResponseEntity<Long> 타입으로 받음으로써, getStatusCode( )를 활용해 Status Code를 확인할 수도 있다.
(여기서 responseEntity.getBody( ) 를 하면 '2' 가 나온다! 타입은 'Long' 으로 지정되었을 것이다!)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class MusicAPIControllerTest {
@LocalServerPort private int port;
@Autowired private TestRestTemplate restTemplate;
@Test
void 조회() {
// given
Music music = new Music("Loco", "ITZY", "Crazy in Love", "I'm gettin loco");
musicRepository.save(music);
String url = "http://localhost:" + port + "/api/v1/music" + music.getId();
// when
ResponseEntity<Music> responseEntity
= restTemplate.getForEntity(url, Music.class); // 리턴 타입 주의!
MusicResponseDto responseDto = new MusicResponseDto(responseEntity.getBody());
// then
assertThat(responseDto.getTitle()).isEqualTo(music.getTitle());
assertThat(responseEntity.getStatusCode()).isEqualTo(OK);
}
}
위 코드는 조회(GET)에 대한 테스트 코드이고, when 부분만 살펴보면 url 주소에 매핑된 데이터를 GET 하였다.
그리고 ResponseEntity<Music> 타입으로 받은 것을 getBody( ) 해서 HTTP body 부분을 통해 전달된 데이터를 사용할 수 있다.
getBody( ) 해서 얻은 Entity 데이터(Music 객체)를 DTO에 매핑해서 활용할 수 있도록! 테스트 코드를 작성했다. 😆😆