Spring Security 연동 (7) (자동 회원가입 후 처리, Remeber me)
Spring Security 연동 (7) (자동 회원가입 후 처리, Remeber me)
Spring Security 연동 (6) (소셜 로그인 처리 - ②) Spring Security 연동 (6) (소셜 로그인 처리 - ②) Spring Security 연동 (5) (소셜 로그인 처리 - ①) Spring Security 연동 (5) (소셜 로그인 처리 - ①) Spring Security 연
soohykeee.tistory.com
최근 Server는 XML이나 JSON 데이터를 전송하는 역할이 점점 커지고 있다. 이처럼 클라이언트가 원하는 데이터를 제공하는 서버를 API 서버라고 한다. 이번 API 서버 구성을 통해 JSON을 이용하는 API 서버를 어떻게 만드는지 알아볼것이다. Spring Security를 이용하여 보안을 처리하고, JWT를 이용하여 인증을 처리할 것이다. 하단에 간단히 API와 API 서버에 대해 정리해놓았다.
[개념] API Server란 무엇인가?
API와 API 서버 API 서버에 대해 알아보기 전, 우선적으로 API에 대해 알아봐야한다. 평소 API란 말을 많이 들어왔고, 사용도 해보았지만 제대로 개념을 알지 못했었다. 이번 기회로 간단하게 정리를
soohykeee.tistory.com
API Server를 위한 구성
위에서 정리본을 올려놓았지만, 다시한번 간단히 말하자면, API 서버는 순수하게 원하는 데이터만을 제공하는 서버이다. 현재 예제에서는 간단한 Note를 작성하고 이용하는 예제를 구현해줄 것이다. 이전에 다룬적이 있는 JSON 데이터를 위주로 처리하고, 이를 GET / POST / PUT / DELETE 등을 사용해서 처리해줄것이다.
Note Entity, Repository
이를 구현해주기 위해서 entity 디렉토리 하위에 Note 클래스를, repository 디렉토리 하위에 NoteRepository 인터페이스를 생성해준다.
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Getter
@ToString
public class Note extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long num;
private String title;
private String content;
@ManyToOne(fetch = FetchType.LAZY)
private ClubMember writer;
public void changeTitle(String title) {
this.title = title;
}
public void changeContent(String content) {
this.content = content;
}
}
public interface NoteRepository extends JpaRepository<Note, Long> {
// 작성한 Note + Writer
@EntityGraph(attributePaths = "writer", type = EntityGraph.EntityGraphType.LOAD)
@Query("select n from Note n where n.num=:num")
Optional<Note> getWithWriter(Long num);
// email 유저가 작성한 Note List로 출력
@EntityGraph(attributePaths = {"writer"}, type = EntityGraph.EntityGraphType.LOAD)
@Query("select n from Note n where n.writer.email=:email")
List<Note> getList(String email);
}
Note DTO, Service
dto, service 디렉토리 생성 후, 하위에 NoteDTO, NoteService, NoteServiceImpl을 생성해준다.
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class NoteDTO {
private Long num;
private String title;
private String content;
private String writerEmail;
private LocalDateTime regDate, modDate;
}
public interface NoteService {
Long register(NoteDTO noteDTO);
NoteDTO get(Long num);
void modify(NoteDTO noteDTO);
void remove(Long num);
List<NoteDTO> getAllWithWriter(String writerEmail);
default Note dtoToEntity(NoteDTO noteDTO) {
Note note = Note.builder()
.num(noteDTO.getNum())
.title(noteDTO.getTitle())
.content(noteDTO.getContent())
.writer(ClubMember.builder().email(noteDTO.getWriterEmail()).build())
.build();
return note;
}
default NoteDTO entityToDTO(Note note) {
NoteDTO noteDTO = NoteDTO.builder()
.num(note.getNum())
.title(note.getTitle())
.content(note.getContent())
.writerEmail(note.getWriter().getEmail())
.regDate(note.getRegDate())
.modDate(note.getModDate())
.build();
return noteDTO;
}
}
@Service
@Log4j2
@RequiredArgsConstructor
public class NoteServiceImpl implements NoteService {
private final NoteRepository noteRepository;
@Override
public Long register(NoteDTO noteDTO) {
Note note = dtoToEntity(noteDTO);
log.info("===========================");
log.info(note);
noteRepository.save(note);
return note.getNum();
}
@Override
public NoteDTO get(Long num) {
Optional<Note> result = noteRepository.getWithWriter(num);
if (result.isPresent()) {
return entityToDTO(result.get());
}
return null;
}
@Override
public void modify(NoteDTO noteDTO) {
Long num = noteDTO.getNum();
Optional<Note> result = noteRepository.findById(num);
if (result.isPresent()) {
Note note = result.get();
note.changeTitle(noteDTO.getTitle());
note.changeContent(noteDTO.getContent());
noteRepository.save(note);
}
}
@Override
public void remove(Long num) {
if (noteRepository.findById(num).isPresent()) {
noteRepository.deleteById(num);
}
}
@Override
public List<NoteDTO> getAllWithWriter(String writerEmail) {
List<Note> noteList = noteRepository.getList(writerEmail);
return noteList.stream().map(note -> entityToDTO(note)).collect(Collectors.toList());
}
}
Note Controller
controller 디렉토리 하위에 NoteController 클래스를 생성해준다.
@RestController
@Log4j2
@RequestMapping("/notes/")
@RequiredArgsConstructor
public class NoteController {
private final NoteService noteService;
@PostMapping(value = "")
public ResponseEntity<Long> register(@RequestBody NoteDTO noteDTO) {
log.info("--------------register-----------------");
log.info(noteDTO);
Long num = noteService.register(noteDTO);
return new ResponseEntity<>(num, HttpStatus.OK);
}
}
Post 방식으로 Note를 작성하는 register 메소드를 생성하고, @RequestBody를 통해 JSON 데이터를 받아서 NoteDTO로 변환할 수 있도록 처리한다. 다만 Postman을 사용하는거면 @ReqeustBody를 지우고 실행해야 오류 없이 실행이 된다.
현재 별다른 프론트 없이 확인해야하므로, POSTMAN을 사용하여 테스트해보았다.