테크레터

테크레터 4편. HTTP request 메서드

chandlerxx 2023. 12. 29. 10:53

웹 개발 시 HTTP 요청/응답 메세지를 처리하기 위해 반드시 공부해야할 내용입니다.

그리고 해당 주제를 정하게 된 이유는 사용하는 기술에 대한 이해도를 높이기 위함입니다. 현재 개인 프로젝트로 스프링 부트를 사용하여 블로그 개발(24.2월 완료예정)에도 많은 도움이 될 것 같네요.

 

외울 필요 없으시고, 많이 하다보면 자연스레 체득하게 되실 겁니다:)

그럼 시작해보겠습니다.

 

`HTTP`란?

온라인으로 원하는 상품을 주문할때 웹페이지(HTML)를 통해 제품에 대한 이미지, 리뷰, 결제까지 이용해보셨던 경험이 있으실 건데요. 클라이언트(웹 브라우저)와 서버 간 어떤 규격을 가지고 메세지를 주고 받기에 가능한 일입니다. 이때, 사용하는 규약이 바로 프로토콜입니다.

즉, HTTP(HyperText Transfer Protocol)는 웹상에서 정보를 주고 받을 수 있는 프로토콜이고, 
사용자는 http(s):로 시작하는 URL(인터넷 주소)로 조회하여 HTTP를 통해 전달되는 자료를 확인할 수 있는거죠 

 

 

시작하며


HTTP 요청/응답은 아래 그림과 같이 수행됩니다.

(request → response 순서로 작성해보았습니다)

source : https://medium.com/@rohitpatil97/http-request-http-response

 

 

1. HTTP Request 메소드 / 메세지 구조


서버로부터 원하는 정보를 가져오기 위해서 HTTP request 정보가 구체적이고 명확해야 합니다. 단순 조회를 원했는데 리소스를 삭제하는 메서드가 사용된다면, 의도와는 다른 동작이 수행됩니다. 이를 위해 메서드 각각의 역할과 언제 사용하는지에 대해 반드시 알아야 합니다.

 

1-1. 요청 메세지구조는 다음과 같이 구성됩니다. (참고)

출처 : https://brunch.co.kr/@swimjiy/3

 

 

1-2. HTTP Request(요청)시 사용되는 메서드는 아래와 같습니다. 

Tip)

HTTP 공부가 처음이시면 여기 블로그를 참고해보세요. 쉽게 설명되어 있습니다!

 

  • `GET` : url 라우팅 시 리소스 조회 → 회원 조회
  • `POST` : 신규 리소스 등록 → 회원 등록
  • `PUT` : 리소스 전체 변경(덮어쓰기 개념), 이때 리소스가 없으면 신규 생성
  • `PATCH` : 리소스 부분 변경 (PUT과의 차이점)
  • `DELETE` : 리소스 삭제

위에서 소개해드린 메소드 외 몇개의 메소드가 더 보입니다.

  • `HEAD` : (GET과 동일하지만) 메시지 부분(body 부분)을 제외하고, 상태 줄과 헤더만 반환
  • `OPTIONS` : 리소스에 대한 통신 가능 옵션을 설명 (주로 CORS에서 사용)
  • `CONNECT` : 리소스로 식별되는 서버에 대한 터널을 설정
  • `TRACE` : 리소스에 대한 경로에 따라 메세지 루프백 테스트 수행 

 

 

2. 코드를 통해 확인해봅시다


개발자라면 직접 코드를 통해 확인해보는게 가장 빠른 방법입니다. 알아볼 메서드는 총 9가지고요.

예시 코드는 레퍼런스 참고해주세요. 참고로 전체 코드에 대한 디테일한 리뷰는 최대한 배제하였습니다. HTTP 메소드 동작 및 응답결과에 집중하겠습니다.

.

.

< 개발 요약 > 

현재 상황은 아래와 같습니다. 

사장님 : 임직원들의 급여를 관리하는 서비스를 만들어주세요.

개발자 : 네.

 

1. 도메인에서 Entity를 생성합니다.

src/main/java/com/xxx/payroll/domain

@Entity
@NoArgsConstructor(access = PROTECTED)
@Getter
@Setter
@ToString
@EqualsAndHashCode
public class Employee {

    @Id
    @GeneratedValue(strategy = IDENTITY)
    private Long id;

    private String name;

    private String role;
}

 

Tip)

코드에 `Setter` 애노테이션은 사용하지 않는게 좋지만, 지금은 예제니까 참고해서 봐주세요. 
무분별한 Setter 생성시 데이터값을 임의 수정할 수 있고, 무엇보다 버그 발생시 언제, 어디서 인스턴스값들이 변해야하는지 등 명확하게 구분할 수가 없습니다. 

제일 좋은건 생성자 생성하여 @Builder 애노테이션을 사용하는 거겠죠. 나중에 별도로 코드 리뷰하는 게시글을 올리겠습니다.

 

 

2. `@RequestMapping` method를 직접 정의함으로써 사용하시면 됩니다.

지금은 `@PostMapping`, `@GetMapping`와 같이 메소드와 통합되어 편리하게 사용하고 있는 점 참고해주세요.

 

3. Application 실행 결과, repository에 데이터가 저장됨을 확인할 수 있습니다.

.

.

기본셋팅이 완료되었으니 이제 HTTP request Method를 확인해보겠습니다.

테스트는 postman으로 진행하겠습니다. 테스트하고자 하는 메소드를 설정하시면 되고, 헤더 설정도 추가/삭제 가능합니다.

Tip)

Header에 어떤 정보들이 포함되는지 여기를 참고해주세요.

postman

 

 

2-1. GET Vs.HEAD 

  • `GET` : 리소스 조회 
  • `HEAD` : (GET과 동일하지만) 메시지 부분(body 부분)을 제외하고, 상태 줄과 헤더만 반환
//@GetMapping("/employees")
@RequestMapping(value = "/employees", method = GET)
public List<Employee> all() {
   return repository.findAll();
}

 

Method = GET

 

 

Method = HEAD

 

 

2-2. POST

 

  • 신규 리소스 등록 

서버를 통해  "manager" 직급의 새로운 임직원 등록 확인했습니다.

 

 

 

2-3. PUT Vs. PATCH

  • `PUT` : 리소스 전체 변경(덮어쓰기 개념), 이때 리소스가 없으면 신규 생성
  • `PATCH` : 리소스 부분 변경 (PUT과의 차이점)
@PutMapping("/employees/{id}")
public Employee replaceEmployee(@RequestBody Employee newEmployee, @PathVariable Long id) {
	return repository.findById(id)
                .map(employee -> {
                    employee.setName(newEmployee.getName());
                    employee.setRole(newEmployee.getRole());
                    return repository.save(employee);
                })
                .orElseGet(() -> {
                    newEmployee.setId(id);
                    return repository.save(newEmployee);
                });
}

 

POST를 통해 memberC의 직급이 manager -> sales 로 덮어쓰기된 걸 확인할 수 있습니다.

 

PATCH는 따로 구현하는게 까다로울 것 같고 많은 개발자분들께서도 선호하진 않으실 것 같습니다. 이유는 파라미터든 필드든 변경된 값만 서버로 전달해야하는데 이때 null이 아닌 값을 조건문이 많이 들어갈 것 같네요.

그냥 POST로 전체를 변경하는게 유지 보수 측면과 클린 코드 측면에서도 좋을 것 같네요.

(참고를 통해 공부해보시면 좋을 것 같아요. 저도 공부해서 게시글로 업로드해볼게요)

 

 

2-4. DELETE

  • 리소스 삭제

비교를 위해 다른 임직원들을 추가 생성한 후에 "Sales"를 삭제하였습니다. 

@DeleteMapping("/employees/{id}")
void deleteEmployee(@PathVariable Long id) {
        repository.deleteById(id);
}

 

2-5. OPTIONS

  • 리소스에 대한 통신 가능 옵션을 설명 (주로 CORS에서 사용)
  • 서버는 Allow 응답 헤더에 사용할 수 있는 HTTP Method 목록을 제공해야 합니다.
@RequestMapping(value = "/employees/", method = OPTIONS)
public void optionsEmployee(@RequestHeader Map<String, String> headers) {
   log.info("headers={}",headers);
}

2-5. CONNECT/TRACE

  • `CONNECT` : 리소스로 식별되는 서버에 대한 터널을 설정
  • `TRACE` : 리소스에 대한 경로에 따라 메세지 루프백 테스트 수행 

두개에 대한 예시는 postman 지원이 안되네요. 코드 확인이 필요한데.. 나중에 추가하도록 하겠습니다 ^^;;

 

 

마치며


mockMVC를 사용했더라면 request뿐만 아니라 response도 빠르게 테스트해볼 수 있었을 것 같은데요. 다 작성하고보니 아쉽네요. 성장통이라고 생각하고 더욱 노력하겠습니다. 

 

 

감사합니다.