Self Code Review/(sparta) Spring 기초 - CRUD API
[Spring] Spring 구조와 API 흐름 이해하기1 (스파르타코딩클럽 - 웹개발의 봄, Spring 2주차)
밍굥잉
2022. 5. 25. 21:41
{ ⭐ 더 정리된 노션 버전 ⭐}
❗Spring의 구조
1.Controller : 가장 바깥 부분, 요청/응답을 처리함.
2. Service : 중간 부분, 실제 중요한 작동이 많이 일어나는 부분
3. Repo : 가장 안쪽 부분, DB와 맞닿아 있음. (Repository, Entity) - 강의에서는 models
models - person.java
- lombok (import도 해주기)
- person 클래스에 @Getter 적용 (기존 getName, getJob…을 대체함)
- 생성자 만들기
public Person(PersonRequestDto requestDto) {
this.name = requestDto.getName();
this.job = requestDto.getJob();
this.age = requestDto.getAge();
this.address = requestDto.getAddress();
}
models - PersonRequestDto.java
- PersonRequestDto.java 클래스 생성
import lombok.Getter;
@Getter
public class PersonRequestDto {
private String name;
private String job;
private int age;
private String address;
}
API
POST - 생성
- controller - PersonController.java
@PostMapping("/api/persons")
//포스트 요청이 올 때 항상 실행되는 메소드
public Person createPerson(@RequestBody PersonRequestDto requestDto) {
Person person = new Person(requestDto);
return **personRepository**.save(person);
}
- PersonRequestDto requestDto : 데이터를 가져오는 소재(파라미터)
- @RequestBody : Request의 body 영역에 있는 게 제대로 전달되기 위해 사용
- personRepository의 save를 사용해서 person 값을 저장해야함.
- (😋) But! personRepository 아직 생성 안됨
2. models - PersonRepository.java 인터페이스 생성
- JPA를 사용하기 위해서 JpaRepository 상속을 해주는데 (extends JpaRepository)
- person에 대한 것이고 Long이 빠져있다. (<Person, Long>)
public interface PersonRepository extends JpaRepository<Person, Long> {
}
3. models - person.java 파일
- @Entity (테이블임을 알려줌), @NoArgsConstructor (기본 생성자 생성해주는 것) 을 Person 클래스에 추가
- private key를 생성해주기 위해서 Long 타입의 Id 만들기
@GeneratedValue(strategy = GenerationType.AUTO)
// 생성 전략이 자동으로 증가 부여
@Id
private Long id;
// 각각의 컬럼에 대해서 지정하기
// 없으면 안된다 nullable = false
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String job;
@Column(nullable = false)
private int age;
@Column(nullable = false)
private String address;
4. 다시 controller - PersonController.java
@RequiredArgsConstructor
//권한을 줄테니까 스프링에게 알아서 생성자를 생성해주라고 하는 것
@RestController
public class PersonController {
private final PersonRepository personRepository;
// PersonController 할 때 꼭 필요한거야 (final)
}
- @RequiredArgsConstructor : ‘니가 PersonController 갖다 쓰려고 할 때, 멤버로 선언된 것 중에 final로 된 거 있으면 알아서 생성해줘’ 라고 권한을 넘겨줌
- (😋) 이렇게 personRepository 생성 해줬음!!
5. controller - PersonController.java 에서 api 완성하기
@PostMapping("/api/persons")
// 포스트 요청이 올 때 항상 실행되는 메소드
public Person createPerson(@RequestBody PersonRequestDto requestDto) {
Person person = new Person(requestDto);
return personRepository.save(person);
}
- personRepository를 return 해주면 생성하는 POST API가 완성됨 !
GET - 조회
- controller - PersonController.java
@GetMapping("/api/persons")
public List<Person> readPersons() {
return personRepository.findAll();
}
- personRepository를 이용해 findAll을 해서 모든 사용자의 목록을 돌려줌
- 도메인이 같아도 요청 방식에 따라 다른 결과를 보여줌. 최고 ..
PUT - 수정
- controller - PersonController.java
@PutMapping("/api/persons/{id}")
public Long updatePerson(@PathVariable Long id, @RequestBody PersonRequestDto requestDto) {
}
- api 도메인에 {id}를 추가해 어떤 id의 값을 수정할지 알려줘야함
- 파라미터 중요 !
- (Long id, PersonRequestDto requestDto) 만 작성하면 도메인의 {id}와 매칭이 되는지, 요청을 보내는 body와 requestDto가 매칭이 되는지 스프링이 알 수 없음!
- 각 파라미터에 @PathVariable (주소), @RequestBody 로 알려줘야함! 필수!
- Long id : 어떤 id의 값을 수정하는지 주는 파라미터
- PersonRequestDto requestDto : 데이터를 가져오는 파라미터
- 수정을 하기 위해서는 (1) id에 해당하는 person 값을 찾아서, (2) 그것을 업데이트 시켜줘야함
(1) id에 해당하는 person 값 찾기 (personService에 적용할거야)
Person person = personRepository.findById(id).orElseThrow(
() -> new IllegalArgumentException("아이디가 존재하지 않습니다.")
);
- orElseThrow( ) : 없을 때는 이런 오류를 일으켜서 나한테 알려줘.
- (❗) 하지만, 이 코드를 controller의 PUT에서 처리하면, service와 controller의 영역이 겹치게 됨.
(2) 업데이트 하기
@PutMapping("/api/persons/{id}")
public Long updatePerson(@PathVariable Long id, @RequestBody PersonRequestDto requestDto) {
return personService.update(id, requestDto);
}
- personService의 update 메소드에서 id를 반환하는 return 코드 작성.
- (🤩) But! personService 아직 생성 안됨.
2. service - personService.java 클래스 생성
- (🤩) personService 생성해줬음!
@RequiredArgsConstructor
@Service //서비스라고 알려줘야 함.
public class PersonService {
private final PersonRepository personRepository;
@Transactional //이 메소드의 결과가 반드시 반영 돼야 해
public Long update(Long id, PersonRequestDto requestDto) {
Person person = personRepository.findById(id).orElseThrow(
() -> new IllegalArgumentException("해당 id가 존재하지 않습니다.")
);
}
}
- update 메소드를 만드는데 id를 돌려줄 거니까 Long 타입
- (❗) PUT 1 - (1) 코드를 붙여주기
- 즉, id 값으로 해당하는 person 값 찾는 과정을 붙여줌.
- personRepository를 멤버 변수로 선언하고 (private final PersonRepository personRepository;)
- 권한 주기 (@RequiredArgsConstructor)
3. models - person.java 에서 update 메소드 만들기
public void update(PersonRequestDto requestDto) {
this.name = requestDto.getName();
this.job = requestDto.getJob();
this.age = requestDto.getAge();
this.address = requestDto.getAddress();
}
- Person 메소드와 가져오는 데이터(파라미터)와 하는 일도 똑같음
- requestDto에서 name, job, age, address 데이터를 받아서 내가 갖고 있는 person을 업데이트 함.
4. service - personService.java
- service의 update 메소드 안에 update 해서 return 하는 코드를 추가해야 함.
person.update(requestDto);
return person.getId();
5. controller - PersonController.java
@RequiredArgsConstructor
//권한을 줄테니까 스프링에게 알아서 생성자를 생성해주라고 하는 것
@RestController
public class PersonController {
private final PersonRepository personRepository;
private final PersonService personService;
//필요하면 언제든지 personService 써먹어~
}
- personService를 멤버 변수로 선언하고 personService에 사용 권한을 줌.
DELETE - 삭제
- controller - PersonController.java
@DeleteMapping("/api/persons/{id}")
public Long deletePerson(@PathVariable Long id) {
personRepository.deleteById(id);
return id;
}
- api 도메인에 {id}를 추가해 어떤 id의 값을 삭제할지 알려줘야함, Id의 타입은 Long
- id값을 찾기 위해서 @PathVariable (주소)
프로그램 run
- 프로젝트 파일에 있는 HwkWeek01.Application.java
@EnableJpaAuditing
@SpringBootApplication
public class HwkWeek01Application {
public static void main(String[] args) {
SpringApplication.run(HwkWeek01Application.class, args);
}
}
- @EnableJpaAuditing : JPA를 자유롭게 쓸 수 있게 해줌