이번에는 도서관리 애플리케이션의 API를 개발할 것인데 이것을 만들려고 하는 애플리케이션의 요구사항을 먼저 살펴보겠다.
도서관리 애플리케이션의 요구사항👉
사용자
- 도서관의 사용자를 등록할 수 있다.(이름 필수, 나이 선택)
- 도서관 사용자의 목록을 볼 수 있다.
- 도서관 사용자 이름을 업데이트 할 수 있다.
- 도서관 사용자를 삭제할 수 있다.
책
- 도서관에 책을 등록 및 삭제할 수 있다.
- 사용자가 책을 빌릴 수 있다.
다른 사람이 그 책을 진작 빌렸다면 빌릴 수 없다. - 사용자가 책을 반납할 수 있다.
사용자와 책 부분을 나누어서 작업을 할 것이다.
우선 강의에 따라 먼저 미리만들어진 셋팅했던 서버에 넣어져 있다. 먼저 그 화면에 접근해 보겠다.
먼저 서버를 동작시켜주고 서버가 동작하고 있는 상태에서
http://localhost:8080/v1/index.html 로 입력해보겠다.
당황하지말고..
해결했다. 주소입력이 잘못되었었다. 오타주의!!
이제 준비된 웹 UI도있으니
도서관 사용자를 등록할 수 있다.(이름 필수, 나이 선택)
가장 먼저 API를 설계해야 한다.
지금 까지는 마음대로 API를 만들었지만 보통의 API는 일종의 약속이기 때문에 약속에 맞춰서 API를 같이 의논하고 설계하고 확정하는 과정을 거쳐야 한다.
이번 경우에는 도서관리 웹 UI가 만들어져있기에 여기서 사용할 기능들을 채워 넣어야 한다.
먼저 사용자를 등록하기 위한 API 명세는 다음과 같다.
- HTTP Method : POST
- HTTP Path : /user
- HTTP Body (JSON)
{
"name" : String (null 불가능)
"age" : Integer
}
- 결과 반환 X (HTTP상태 200 OK 이면 충분하다)
등록하는 거이기에 POST 사용자관련이기에 Path는 /user, POST이기에 Body 는 JSON으로 받으며 name 는 필수이기에 null은 불가능하게 결과는 성공하는 것으로만 하기로 API명세를 정했다.
이렇게 정해놓고 API를 만들어 보겠다.
먼저 아래와 같이 user package를 먼저 만들어주고
그 안에 UserController Class를 만들어주었다.
전에 만들었던 calculator 에다가 같이 만들 수도 있지만 사용자 관련 API는 사용자 Controller에서 책 관련 API는 책 Controller에서 이렇게 역할별로 모아두는 것이 조금 더 깔끔하기에 새로만들어서 사용하는 것이 좋다.
UserController를 새로 만들었기에 여기를 API 처음 진입지점으로 삼기위해 먼저 @RestController를 어노테이션해준다.
그 다음 POST API로 작성할 것이기에 @PostMapping 에 + ("/user")로 작성해준다.
이렇게 되면 Post /user를 했을 때 이 어노테이션 아래에 있는 함수가 호출이 된다.
함수 생성은 아무것도 반환 안하기로 했기에 public void 로 해주고 함수이름은 saveUser로 작성해주겠다.
package com.group.libraryapp.user;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@PostMapping("/user") //POST /user
public void saveUser(){
}
}
이렇게 작성한 후에는 위에 작성한 Body를 객체로 표현할 DTO가 필요하기에 dto package 안에 request package를 만들어 주겠다.
이제 이 안에 UserCreateRequest 라는 Class를 만들어 dto를 만든다.
UserCreateRequest 같은 경우에는 문자열 name, 숫자 age의 두가 필드가 필요하다.
package com.group.dto.user.request;
public class UserCreateRequest {
private String name;
private Integer age; //여기가 Integer인 경우는 null을 표현하게 할 수 있다.
}
여기서 age 앞에 데이터타입이 Integer인 경우 그냥 int 같은 경우에는 null을 표현할 수 없어 Integer로 만들어주었다.
이름 같은 경우에는 필수지만 나이는 선택이기에 이렇게 설정했다.
그 다음에 getter 를 만들어준다.
package com.group.dto.user.request;
public class UserCreateRequest {
private String name;
private Integer age; //여기가 Integer인 경우는 null을 표현하게 할 수 있다.
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
}
이렇게 생성한 후에 POST API에서 들어온 HTTP Body를 위에 만들었던 Class로 변환하기 위해서는 @RequestBody라는 어노테이션이 필요하기에 @RequestBody UserCreatRequest를 입력해준다.
package com.group.libraryapp.user;
import com.group.dto.user.request.UserCreateRequest;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@PostMapping("/user") //POST /user
public void saveUser(@RequestBody UserCreateRequest request){
}
}
여기까지가 전체적으로 API의 구조를 잡았다.
이제 실제로 유저가 저장되도록 구현해 보겠다.
User라는 정보를 저장하기위해 user라는 객체를 만들어 저장할 건데 이 객체를 com.group.libraryapp에 dto package와 같은 위치에 domain이라는 package를 그리고 그 아래 User라는 Class를 하나 더 만들어 준다.
위에 미리 만들었던 saveUser 사용되서 user가 만들어지면 실제 list에 저장을 할 것이다.
이 User 같은 경우에는 이름과 나이를 가지고 있고 생성자도 같이 만들어 준다. 이 때 name같은 경우는 null이 들어올수 없기에
name이 null이거나 name이 비어있다면 IllegalArgumentException을 throw해줘서 String.fomat을 이용해
"잘못된 name(%s)이 들어왔습니다" 라는 예외처리까지 작성해보겠다.
package com.group.libraryapp.domain;
public class User {
private String name;
private Integer age;
public User(String name, Integer age) {
if(name == null || name.isBlank()){
throw new IllegalArgumentException(String.format("잘못된 name(%s)이 들어왔습니다", name));
}
this.name = name;
this.age = age;
}
}
이렇게 입력해주면 API를 통해 들어온 name 값이 null이거나 비어있으면 생성 및 저장이 안된다.
그리고 예외를 던지는 과정에서 어떤 잘못된 값이 들어왔는지 알려주면 좋기에 자바에 있는 String.format을 사용해서 예외에 메세지로 담을 수 있게끔 처리했다.
이제 실제 방금 작성한 User Class에 저장되게 해보겠다.
UserController Class 안에서 코드를 작성한다.
package com.group.libraryapp.controller.user;
import com.group.libraryapp.dto.user.request.UserCreateRequest;
import com.group.libraryapp.domain.user.User;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
@RestController
public class UserController {
private final List<User> users = new ArrayList<>();
@PostMapping("/user") //POST /user
public void saveUser(@RequestBody UserCreateRequest request){
}
}
이렇게 만들면 saveUser 라는 함수가 호출 되면 즉 POST/user가 호출되면 이 user에 새로운 user를 추가할 건데, 이 때 user를 만들 때는 API를 통해 들어온 이름과 나이를 집어 넣어주도록한다.
package com.group.libraryapp.controller.user;
import com.group.libraryapp.dto.user.request.UserCreateRequest;
import com.group.libraryapp.domain.user.User;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
@RestController
public class UserController {
private final List<User> users = new ArrayList<>();
@PostMapping("/user") //POST /user
public void saveUser(@RequestBody UserCreateRequest request){
users.add(new User(request.getName(), request.getAge()));
//user에 새로운 user를 추가할 건데, 이 때 user를 만들 때는
//API를 통해 들어온 이름(request.getName())과
//나이(request.getAge())를 집어 넣어주도록한다.
}
}
전체적으로 보았을 때 POST/user가 호출되면 아래 함수가 실행되고 이 때 JSON형식으로 HTTP Body
UserCreateRequest에 name과 age 에 전체적인 값이 mapping되고 새로만들어진 객체는 List<User> users에 저장되고 예외없이 정상적으로 함수가 마무리 된다면 200ok를 반납하게 될 것이다.(말이 어렵네;)
다음에 user를 반환하는 user정보가 잘 저장되었는지 확인하는 GET API를 WEB UI로 통해 확인하는 것을 공부해 보겠다.
'기록해보기' 카테고리의 다른 글
정리한번 하고 갈께요 🧑💻 (0) | 2023.06.02 |
---|---|
유저 조회 API 개발과 테스트 (0) | 2023.06.02 |
POST API를 개발하고 테스트하기 (0) | 2023.05.28 |
GET API 개발하고 테스트 (0) | 2023.05.28 |
네트워크란 무엇인가? (0) | 2023.05.28 |
댓글