[스프링 부트 어드민 페이지] 1. HTTP GET, POST

2021. 5. 11. 23:13개발공부/[패스트캠퍼스] 스프링 부트 어드민 페이지 만들기


Github 코드

 

서버 개발자가 되기 위해서 체계적인 학습이 필요하다 생각했습니다. 실무에서 사용할 수 있는 REST API 구현을 배우고 싶어 패스트캠퍼스 Java 웹 개발자 강좌를 신청했습니다. 패키지 강좌는 Java 기초, 객체지향, 스프링 부트 API 실습(어드민 페이지/회원관리/레스토랑 예약)으로 구성되어 있습니다. (본 글은 어드민 페이지 강좌를 바탕으로 합니다.)

 

강사님은 예상국님이며 어드민 페이지로 Java 서버 개발자 강의를 시작한 이유는 신입 개발자한테 처음으로 주어질 업무가 어드민 페이지 API 구현일 가능성이 높기 때문이라고 합니다. 어드민 페이지를 들여다보면 프로젝트나 서비스의 전체적인 비즈니스 모델이 보이고 DB 아키텍처도 알 수 있기 때문에 이제 막 서비스를 이해하는 단계에서 다루기 적합하다고 합니다.


서버 개발자란?


클라이언트로부터 요청을 받아 데이터베이스에 접근하여 얻어진 데이터를 가공한 뒤 해당 요청에 대한 응답을 전달해주는 일을 합니다. 

 

요청과 응답은 통신 이란 한 단어로 표현 가능하며 클라이언트(사용자나 또 다른 서버)의 요청이 오면 데이터를 잘 가공해서 요청 포맷(JSON, XML, text, HTML 등)에 맞게 응답해줘야 합니다. 이러한 포맷은 요청과 함께 전달됩니다(Header).

 

따라서 앞으론 요청 데이터에 대한 응답을 어떻게 만들고(Controller), JPA(데이터베이스 접근)를 어떻게 구성하고, 데이터를 어떻게 가공해줄 것인지(Java.util.Collection과 같은 자료구조 사용)에 대해 배우게됩니다.

 

어드민 페이지를 구현하는 프로젝트를 맡게 된다면 실무에선 어드민 기획자(PM), 프론트엔드 개발자와 협업하게 되어있습니다.


HTTP Method


REST API의 REST 방식은 HTTP 프로토콜에 있는 메서드들을 활용해서 리소스, 데이터 자원을 처리하는(CRUD) 방법입니다. 메서드 종류는 GET, POST, PUT/PATCH, DELETE가 있습니다. 

HTTP Method 동작 URL 형태
GET 조회 (SELECT) /user/{id}
POST 생성 (CREATE) /user
PUT/PATCH 수정 (UPDATE) /user
DELETE 삭제 (DELETE) /user/{1}

 

1. GET 

주소창(URL)에 파라미터가 노출되며 URL에 대한 캐시가 이루어지므로 정보를 얻을 때 사용합니다. 캐시는 브라우저가 자주 요청되는 정보를 빠르게 보여줄 수 있도록 브라우저에 저장해두는 방식을 말합니다. 

 

앞서 말했다시피 서버는 사용자가 특정 데이터를 요청하면 가지고 있는 데이터를 가공하여 여러 자료형태로 준비해 응답을 내려주는 역할을 합니다.

 

Spring에서 파라미터를 받는 방법 중 URL로 담아 @RequestParam 어노테이션으로 받아줄 수 있습니다. 

 

1
2
3
4
5
6
    @GetMapping("/getParameter"// localhost:8080/api/getParameter?id=1234&password=abcd
    public String getParameter(@RequestParam String id, @RequestParam(name = "password"String pwd) {
        String password = "aaaa";
        System.out.println("id : " + id + "\npw : " + pwd);
        return id + pwd;
    }
cs

 

만일 단일 객체로 바인딩 하고 싶다면 메서드 Argument에 객체 인스턴스를 적어주면 됩니다. 서버-클라이언트 통신에서 자주 사용되는 JSON 데이터 형태로 만들어지는 과정을 제가 이해한대로 그려보았습니다. 

 

일단 요청이 들어오면 Spring은 DispatcherServlet를 통해 주소를 Handler Adapter로 전달해 매칭되는 Controller 메서드를 찾습니다. 요청 시 처리해줄 데이터가 있다면 어노테이션이나 객체를 메서드 파라미터에 기재해 받아줍니다. 그런 다음 (RestController의 경우) 스프링 부트는 내장된 Jackson 라이브러리를 사용해 가장 흔히 사용되는  통신 데이터 형태 JSON으로 데이터를 가공해 객체를 리턴시켜줍니다. 리턴된 화면에는 아래와 같은 JSON 형태 문자열이 찍힙니다. 

 

GET방식으로 데이터를 받아 객체로 매핑해준 값을 리턴해주는 API의 코드는 이렇습니다.

1
2
3
4
5
6
7
8
9
10
    // localhost:8080/api/multiParameter?account=abcd&email=study@gmail.com&page=10
    @GetMapping("/getMultiParameter")
    public SearchParam getMultiParameter(SearchParam searchParam) {
        System.out.println(searchParam.getAccount());
        System.out.println(searchParam.getEmail());
        System.out.println(searchParam.getPage());
 
        // {"account" : "", "email" : "", "page" : 0}
        return searchParam;
    }
cs

 

2. POST

GET과 달리 주소창(URL)에 파라미터가 노출되지 않습니다. 주소 길이 제한이 없기 때문에 GET 방식보다 긴 데이터를 보낼 수 있다는 장점이 있습니다. 

 

POST 방식이 보안에 유리하다는 것은 URL에 데이터 노출이 되지 않기 때문만은 아닙니다. 마음만 먹으면 body에 담긴 정보를 꺼내볼 수 있습니다. 따라서 프로덕션에선 민감정보인 유저 패스워드는 SSL(Secure Socket Layer)로 encrypt시켜 확실히 보안을 지켜야 합니다. 참고 Stackoverflow(How secure is a HTTP POST?) SSL은 간략히 얘기해서 네트워크 링크를 암호화하고 인증하는 기능을 추가해서 보안을 형성하는 프로토콜 입니다.

 

그럼에도 데이터가 브라우저 캐시로 저장되지 않기 때문에 가벼운 보안은 구축될 수 있다는 장점이 있습니다.

 

POST 방식은 주로 HTML <form> 태그를 사용하거나 ajax 검색 시 사용합니다. 데이터를 전달할 땐 헤더의 Body에 담기 때문에 POST 메서드 Argument엔 @RequestBody를 사용해 데이터를 처리해줘야 합니다. 요청이 들어오고 리턴을 하기 까지 과정을 시각화 해보았습니다.

 

 

HTTP Request 포맷은 JSON, XML, multipart-form, text-plain 등이 있습니다. 어떤 포맷으로 처리해줄지는 @PostMapping(produces = "{타입}"을 사용해 정해줄 수 있습니다.

 

REST API 테스팅 크롬 익스텐션 설치 - Talend API Tester

요청 URL에 대해 요청 데이터 타입을 지정하고 전달할 수 있으며 응답 헤더 정보를 확인할 수 있는 테스팅 익스텐션입니다. 

 

 

 

3. PUT/PATCH, DELETE

PUT, PATCH 메서드는 POST와 마찬가지로 BODY에 데이터가 들어있으며 주로 업데이트에 사용합니다. 업데이트는 DB 데이터를 변경할 때 정보를 받아 수정해주는 것을 말합니다.

@PutMapping, @PatchMapping 사용, 하지만 REST API에선 이런 용도로 사용하지 않습니다.

DELETE는 Get과 마찬가지로 주소에 파라미터가 들어가며, 데이터를 삭제할 때 사용합니다.

 

이번 시간까지는 Spring에서 GET 방식일 때 어떻게 파라미터를 받아서 리턴해주는지, 그리고 POST 방식일 땐 Body 데이터에 어떻게 접근해서 JSON 형태로 어떻게 리턴해주는지를 배워봤습니다.


강의에선 테스트 코드로 Controller 요청처리 실행결과를 체크하진 않지만 Junit을 이용해 테스트 코드도 작성해보고 있습니다. 한동안 안쓰면 학습한 것도 처음 배운 느낌이 들어서 시간이 들지만 적용시킬 수 있을 때 해보는 것이 좋은 것 같습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@WebMvcTest(PostController.class)
class PostControllerTest {
 
    @Autowired
    private MockMvc mvc;
 
    @Test
    public void postMethodTest() throws Exception {
        this.mvc.perform(post("/api/postMethod")
                .requestAttr("account""lee")
                .requestAttr("email""lee@gmail.com")
                .requestAttr("page"2))
                .andExpect(request().attribute("account""lee"));
    }
}
 
@WebMvcTest(GetController.class)
class GetControllerTest {
 
    @Autowired
    private MockMvc mvc;
 
    @Test
    public void getMethodTest() throws Exception {
        this.mvc.perform(get("/api/getMethod"))
                .andExpect(status().isOk())
                .andExpect(content().string(containsString("Hi ")));
    }
 
    @Test
    public void getMultiParameterTest() throws Exception {
        this.mvc.perform(get("/api/getMultiParameter")
                .requestAttr("account""lee")
                .requestAttr("email""lee@gmail.com")
                .requestAttr("page"2))
                .andExpect(request().attribute("account""2"));
    }
}
 
 
cs

출처 : 패스트캠퍼스 Java 웹 개발 마스터 올인원 패키지