-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: 공유보드 조회, 공유 보관함 사진 상세조회 , 공유 URL 생성 API #60
base: develop
Are you sure you want to change the base?
Changes from 23 commits
b3341c7
6516d03
5b0b6db
89fbe8c
4cc6d3d
091335f
4feadb5
1f25555
78fdaa8
72ce070
28f23de
55d3be7
2044485
f2862a6
41344c8
03a0c75
0495449
d81572f
ae231f1
d45907a
8f228f9
cad9ee6
9140ddf
d85766b
7e9400b
dbf472f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.ddd.moodof.adapter.infrastructure.security.encrypt; | ||
|
||
import org.springframework.stereotype.Component; | ||
import java.security.MessageDigest; | ||
|
||
@Component | ||
public class EncryptUtil { | ||
|
||
public static String encryptSHA256(String msg){ | ||
try{ | ||
MessageDigest digest = MessageDigest.getInstance("SHA-256"); | ||
byte[] hash = digest.digest(msg.getBytes("UTF-8")); | ||
StringBuffer hexString = new StringBuffer(); | ||
|
||
for (byte b : hash) { | ||
String hex = Integer.toHexString(0xff & b); | ||
if (hex.length() == 1) hexString.append('0'); | ||
hexString.append(hex); | ||
} | ||
|
||
return hexString.toString(); | ||
} catch(Exception ex){ | ||
throw new RuntimeException(ex); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package com.ddd.moodof.adapter.presentation; | ||
|
||
import com.ddd.moodof.adapter.presentation.api.PublicBoardAPI; | ||
import com.ddd.moodof.application.BoardPhotoService; | ||
import com.ddd.moodof.application.StoragePhotoService; | ||
import com.ddd.moodof.application.dto.BoardPhotoDTO; | ||
import com.ddd.moodof.application.dto.StoragePhotoDTO; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import java.util.List; | ||
|
||
@RequiredArgsConstructor | ||
@RequestMapping(PublicBoardController.API_PUBLIC_BOARDS) | ||
@RestController | ||
public class PublicBoardController implements PublicBoardAPI { | ||
|
||
public static final String API_PUBLIC_BOARDS = "/api/public/boards"; | ||
|
||
private final StoragePhotoService storagePhotoService; | ||
|
||
private final BoardPhotoService boardPhotoService; | ||
|
||
@Override | ||
@GetMapping("/{sharedKey}") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 말씀들어보니 Pathvariable은 id로 처리하고 sharedKey로 검색을 한다는것과 같은 의미이므로 RequestParam도 괜찮아 보이네요 :) |
||
public ResponseEntity<List<BoardPhotoDTO.BoardPhotoResponse>> findAllByBoard(@PathVariable String sharedKey) { | ||
List<BoardPhotoDTO.BoardPhotoResponse> responses = boardPhotoService.findAllBySharedKey(sharedKey); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BoardPhoto List 뿐만아니라, Board 정보도 필요하지 않을까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 네 맞습니다. 그부분은 아직 기획상 명확하지 않아서 일단 포토리스트들만 가져오는로직으로 개발을 진행하였습니다 :) 기획에 따라 |
||
return ResponseEntity.ok(responses); | ||
} | ||
|
||
@Override | ||
@GetMapping("/{sharedKey}/detail/{id}") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 API는 어떤 상황에서 사용될 것이라 생각하신 건가요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 네 맞습니다. 공유보드에서 사진 상세조회를 한 경우입니다.
위에서 말씀해주신것들을 들어보니 |
||
public ResponseEntity<StoragePhotoDTO.StoragePhotoDetailResponse> getSharedBoardDetail( | ||
@PathVariable String sharedKey, | ||
@PathVariable Long id, | ||
@RequestParam(required = false, value = "tagIds") List<Long> tagIds){ | ||
StoragePhotoDTO.StoragePhotoDetailResponse response = storagePhotoService.findSharedBoardDetail(sharedKey, id, tagIds); | ||
return ResponseEntity.ok(response); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.ddd.moodof.adapter.presentation; | ||
|
||
import java.lang.annotation.*; | ||
|
||
@Target(ElementType.PARAMETER) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Documented | ||
public @interface SharedBoardId { | ||
String value() default ""; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.ddd.moodof.adapter.presentation.api; | ||
import com.ddd.moodof.application.dto.BoardPhotoDTO; | ||
import com.ddd.moodof.application.dto.StoragePhotoDTO; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
|
||
import java.util.List; | ||
|
||
public interface PublicBoardAPI { | ||
@GetMapping("/{sharedKey}") | ||
ResponseEntity<List<BoardPhotoDTO.BoardPhotoResponse>> findAllByBoard(@PathVariable String sharedKey); | ||
|
||
@GetMapping("/{sharedKey}/detail/{id}") | ||
ResponseEntity<StoragePhotoDTO.StoragePhotoDetailResponse> getSharedBoardDetail(@PathVariable String sharedKey, @PathVariable Long id, @RequestParam(required = false, value = "tagIds") List<Long> tagIds); | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,34 @@ | ||
package com.ddd.moodof.application; | ||
|
||
import com.ddd.moodof.adapter.infrastructure.security.encrypt.EncryptUtil; | ||
import com.ddd.moodof.application.dto.BoardDTO; | ||
import com.ddd.moodof.application.verifier.BoardVerifier; | ||
import com.ddd.moodof.domain.model.board.Board; | ||
import com.ddd.moodof.domain.model.board.BoardRepository; | ||
import com.ddd.moodof.domain.model.board.BoardSequenceUpdater; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.server.ServletServerHttpRequest; | ||
import org.springframework.stereotype.Service; | ||
|
||
import org.springframework.web.util.UriComponents; | ||
import org.springframework.web.util.UriComponentsBuilder; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.transaction.Transactional; | ||
|
||
@RequiredArgsConstructor | ||
@Service | ||
public class BoardService { | ||
|
||
public static final int MAX_BOARD_IN_CATEGORY_COUNT = 10; | ||
|
||
private final BoardRepository boardRepository; | ||
|
||
private final BoardVerifier boardVerifier; | ||
|
||
private final BoardSequenceUpdater boardSequenceUpdater; | ||
|
||
public static final String LOCALHOST = "localhost"; | ||
|
||
|
||
@Transactional | ||
public BoardDTO.BoardResponse create(Long userId, BoardDTO.CreateBoard request) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. create 동작중, repository save 호출이 2번 일어나고 있는데, 한번으로 줄일 수 있을것 같습니다 🙂 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 더티체킹을 생각못하고 두개의 save를 사용하여서 바로 수정하였습니다 :) 현재 로직은
변경 로직
로직으로 하나의 save로 처리하였습니다! |
||
if (boardRepository.countByCategoryId(request.getCategoryId()) >= MAX_BOARD_IN_CATEGORY_COUNT) { | ||
|
@@ -27,13 +37,19 @@ public BoardDTO.BoardResponse create(Long userId, BoardDTO.CreateBoard request) | |
|
||
Board board = boardVerifier.toEntity(request.getPreviousBoardId(), request.getCategoryId(), request.getName(), userId); | ||
Board saved = boardRepository.save(board); | ||
|
||
encryptByBoardId(userId, saved); | ||
boardRepository.findByUserIdAndPreviousBoardIdAndIdNot(userId, request.getPreviousBoardId(), saved.getId()) | ||
.ifPresent(it -> it.changePreviousBoardId(saved.getId(), userId)); | ||
|
||
return BoardDTO.BoardResponse.from(saved); | ||
} | ||
|
||
public void encryptByBoardId(Long userId, Board saved) { | ||
String sharedKey = EncryptUtil.encryptSHA256(Long.toString(saved.getId())); | ||
saved.updateSharedkey(sharedKey, userId); | ||
boardRepository.save(saved); | ||
} | ||
|
||
public BoardDTO.BoardResponse changeName(Long userId, Long id, BoardDTO.ChangeBoardName request) { | ||
Board board = boardRepository.findById(id) | ||
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 보드입니다. id = " + id)); | ||
|
@@ -58,4 +74,12 @@ public void delete(Long userId, Long id) { | |
} | ||
boardRepository.deleteById(id); | ||
} | ||
|
||
public BoardDTO.BoardSharedResponse getSharedURI(Long userId, Long id) { | ||
Board board = boardRepository.findByIdAndUserId(id, userId) | ||
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 Board, id = " + id)); | ||
String sharedKey = board.getSharedKey(); | ||
return BoardDTO.BoardSharedResponse.from(id, sharedKey); | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
현재 GET
/boards/{id}
가 공유키 조회로만 사용되고 있는데, 저 주소는 보드 상세 조회라고 생각할 수 있을것 같아요. 보드 정보가 있어야할 것 같고 (title 등), 해당 보드에 존재하는 BoardPhoto 리스트를 응답해야할 것 같은데 어떻게 생각하시나요?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
현재 말씀해주신부분은 사용자가 공유 URI를 누르면 생성된 sharedKey값을 가져와서 해당 sharedKey 데이터를 반환해주는 로직입니다.
@GetMapping("/sharedKey/{id}")
로 변경하여 해당 sharedKey를 조회하는 로직은 어떨까요?@GetMapping("/{sharedKey}")
이 부분이 (지금은 변경된 `@GetMapping /api/public/boards?sharedKey={sharedKey}) 보드에 대한 전체 포토리스트를 가져오는 부분입니다. 밑에 말씀해주신데로 기획 정책상 어떤정보를 보여줄 것인지에 따라 변경될 소지가 있어보입니다.