Springboot에서 REST API(REST API개념 바로가기)를 테스트해보자. 스프링부트 프로젝트 기본설정은 아래와 같다.
스프링부트 기본 설정
Project: Gradle Project
Spring Boot: 2.4.4
(SNAPSHOT)은 개발진행중인 베타버전을 뜻 함. (SNAPSHOT)없는 버전으로 선택하기
Language: Java
Packaging: Jar
Java: 8
Dependencies: Spring Web
port바꾸기
기존 포트는 80 또는 8080이다. 이미 8080포트를 다른 프로젝트에서 사용중이라면 application.properties에서 손쉽게 포트를 변경할 수 있다. 만약 포트를 9090으로 바꾸고 싶다면 아래처럼 설정해주면 된다.
1
server.port=9090
RestAPI
RestAPI를 공부하다보면 멱등성 지원해야한다고 등장하곤한다. 멱등성이란 무엇일까?
멱등성: 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질
예를들어 아래와같은 PUT메서드 있다고 해보자.
1 2 3 4 5 6 7
요청 PUT /api/events/{id} { "type": : "ACCEPT" // ACCEPT/REJECT } 응답 200 OK
위 PUT메서드를 처음 호출해서 ACCEPT로 바꾼 뒤 한 번 더 호출했을때 이미 ACCEPT인데 ACCEPT요청이 중복이라고 에러가 발생한다면? 이건 멱등성을 지원하지 않는 것이다. 멱등성 지원이 잘 된 경우에는 PUT메서드 호출시 이미 ACCEPT인 경우 그냥 200 OK로 응답하는 것을 말한다. 이런 멱등성을 지켜줘야하는 메서드는 보통 POST메서드 빼고 다~ 멱등성있는 API를 지원해야한다.
// 파람이 3개이상되면 너무 많아지므로 DTO를 만들어서 처리하는 것이 좋다. @GetMapping("/query-param2") public String queryParam2( @RequestParam String name, @RequestParam String email, @RequestParam int age ){ return name+" / "+email+" / "+age; }
@RestController// 의미: 해당 class는 REST API 처리하는 Controller다. @RequestMapping("/api/get") // URI를 지정해주는 어노테이션이다. get/post/put/delete다 작동함 publicclassGetAPIController{ // @RequestMapping를 사용하면 get/post/put/delete 다 작동가능 // method속성을 이용하여 한 가지방식을 선택할 수 있음 => 옛날방식으로 요즘은 GetMapping을 사용함 @RequestMapping(path="/hi", method= RequestMethod.GET) public String getHi(){ return"하이 getHi @RequestMapping사용"; }
// http://localhost:9090/api/get/hello @GetMapping(path="/hello") public String getHello(){ return"헬로 getHello @GetMapping사용"; } // PathVariable // http://localhost:9090/api/get/path-variable/{name} @GetMapping("/path-variable1/{name}") public String pathVariable1(@PathVariable String name){ System.out.println("pathVariable1: "+name); return name; } // PathVariable 이용시 이름 매칭이 어려울시 // PathVariable(name="")속성을 이용하면 된다. // 기존에 받아와야할 인수명이 name인경우 PathVariable 이름과도 중복이 된다. // 이때 PathVariable(name="name")속성을 이용하여 @GetMapping의 {name}과 동일하게 처리해준다. @GetMapping("/path-variable2/{name}") public String pathVariable2(@PathVariable(name="name") String pathName, String name) { System.out.println("pathVariable2: "+pathName); return pathName; } // Query parameter // 주로 검색할때 사용하는 인자로 URL의 물음표(?)의 뒷부분으로 &연산자를 기준으로 키=밸류 값이 이어진다. // @RequestParam을 꼭 붙여줘야한다. // http://localhost:9090/api/get/query-param?user=소원데브&email=sowon-dev@이메일.com&age=77 @GetMapping("/query-param") public String queryParam(@RequestParam Map<String, String> queryParam){ StringBuilder sb = new StringBuilder(); // @RequestParam인자를 Map을 사용한 경우 아무 인자 다 받을 수 있어서 key값이 명시적인경우 get으로 이름을 지정해서 사용해야한다. // 이메일을 불러오는 경우 // queryParam.get("email"); // 명시적인 인자의 경우 아래 queryParam2를 사용하는 것이 좋다 queryParam.entrySet().forEach( entry -> { sb.append(entry.getKey() + " : " + entry.getValue()+"\n"); System.out.println(sb.toString()); }); return sb.toString(); } // @RequestParam인자를 Map을 사용한 경우 아무 인자 다 받을 수 있어서 key값이 명시적인경우 // 받을 수 있는 인자가 명확하다면 아래처럼 명시적으로 인자를 받는 것이 좋다. // 명시적인 경우 int형에 문자열을 넣으면 에러 발생 -> 클라이언트 에러인것을 확인할 수 있다. // 파람이 3개이상되면 너무 많아지므로 DTO를 만들어서 처리하는 것이 좋다. @GetMapping("/query-param2") public String queryParam2( @RequestParam String name, @RequestParam String email, @RequestParam int age ){ return name+" / "+email+" / "+age; } // 가장 추천하는 방법 // 중요한 점은 @RequestParam를 붙이지 않는다 // http://localhost:9090/api/get/query-param3?name=소원데브&email=sowon-dev@이메일.com&age=77 @GetMapping("/query-param3") public String queryParam2(userRequest user){ return user.toString(); } }
@RestController// 의미: 해당 class는 REST API 처리하는 Controller다. @RequestMapping("/api/post") // URI를 지정해주는 어노테이션이다. get/post/put/delete다 작동함 publicclassPostAPIController{ // post로 보낼때는 바디에 데이터를 실어보낸다고 표현도 함 // post로 보낼때는 @RequestBody 꼭 붙여줘야함 // Map으로 받으면 어떤 데이터가 들어오는 지 한 눈에 확인이 불가능하기때문에 DTO를 사용하는 것이 좋다. @PostMapping("") publicvoidpost(@RequestBody Map<String, String> requestData){ requestData.entrySet().forEach( stringObjectEntry -> { System.out.println(stringObjectEntry.getKey() + " : "+ stringObjectEntry.getValue()); }); } @PostMapping("/postdto") publicvoidpostDTO(@RequestBody postDTO dto){ System.out.println(dto); } }
html페이지를 리턴하는 컨트롤러
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
@Controller//html 리소스파일을 찾는 컨트롤러 publicclassPageController{ @RequestMapping("/main") public String main(){ return"main.html"; //@Controller을 사용하면 text가 아닌 해당 String값의 html파일을 찾아서 리턴한다. } //ResponseEntity @ResponseBody @GetMapping("/car") public Car car(){ Car car = new Car(); car.setCarName("마티즈"); car.setCarNumber(123456); return car; } }