πŸƒ‍♂️ DEVLOG

[DEVLOG] μš°λ‹Ήνƒ•νƒ• 제발λͺ¨λ°œ v2 개발기 - νƒˆλͺ¨ 진단 API μˆ˜μ •ν•˜κΈ° (2) κ³΅ν†΅ν•„λ“œκ°€ λ§Žμ€ DTO λ§Œλ“€κΈ°

개발자 HOON 2022. 12. 16. 14:17

 

🏝 0. μ§€λ‚œ κΈ€

 

[DEVLOG] μš°λ‹Ήνƒ•νƒ• 제발λͺ¨λ°œ v2 개발기 - νƒˆλͺ¨ 진단 API μˆ˜μ •ν•˜κΈ° (1) λ³€μˆ˜ μž‘λͺ…, Optional, Enum ν™œμš©

🏝 0. μ„œλ‘  μ‘Έμ—…μž‘ν’ˆμœΌλ‘œ νƒˆλͺ¨ 진단 μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μΈ '제발λͺ¨λ°œ'을 κ°œλ°œν•˜κ³ , 'ν•΄λ‹Ή ν”Œλž«νΌμ„ μžμ‹ μ˜ νšŒμ‚¬μ— 이전해 μ‚¬μš©ν•˜κ³  μ‹Άλ‹€'λΌλŠ” μ–΄λŠ κ΅μˆ˜λ‹˜μ„ λ§Œλ‚˜ AWS μƒνƒœκ³„μ—μ„œ 사내 μ„œλ²„ μ»΄ν“¨ν„°λ‘œ

hoons-dev.tistory.com

μ§€λ‚œ κΈ€μ—μ„œ Optional의 ν™œμš©κ³Ό Enum의 ν™œμš©μ˜ˆμ‹œλ₯Ό λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

 


 

πŸ€” 1. μ§€λ‚œ μ½”λ“œμ—μ„œμ˜ μ•½κ°„μ˜ μž¬μˆ˜μ •

 

μ§€λ‚œ μ½”λ“œ 쀑, 진단 파트의 μƒνƒœλ₯Ό λ‚˜νƒ€λ‚΄λŠ” Enum의 μ½”λ“œμž…λ‹ˆλ‹€.

@Getter
@AllArgsConstructor
public enum JBMBDiagnosisStateIdentifier {

    OPEN(1, "진단 μ‹œμž‘", true),
    SURVEY(2, "섀문쑰사 진행", true),
    UPLOAD(3, "이미지 μ—…λ‘œλ“œ", true),
    DIAGNOSE(4, "진단 쀑", true),
    DONE(5, "진단 μ™„λ£Œ",false),
    ERROR(6, "μ—λŸ¬ λ°œμƒ", false),
    SHUTDOWN(7, "진단 쀑단", false);

    private int stateCode;
    private String stateDescription;
    private boolean interruptible;
    
    public static boolean isShutDownAble(JBMBDiagnosisStateIdentifier diagnosisState){
    	return diagnosisState.isInterruptible;
    }

}

 

μ•„λž˜μ˜ static으둜 μƒμ„±ν•œ λ©”μ„œλ“œμ˜ ν•„μš”μ„±μ΄ μ—†λ‹€λŠ” 것을 κΉ¨λ‹¬μ•˜μŠ΅λ‹ˆλ‹€. 정적 νŒ©ν† λ¦¬ λ©”μ„œλ“œλ‘œ μƒˆλ‘œμš΄ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜λŠ” 것도 μ•„λ‹ˆκ³ , 이미 enum 객체에 interruptibleμ΄λΌλŠ” ν•„λ“œκ°€ μžˆλŠ”λ° λ‹€μ‹œ ν•œ 번 κ°œλ°œν•œ 꼴이 λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

κ·Έλž˜μ„œ, ν•΄λ‹Ή λ©”μ„œλ“œλ₯Ό μ‚­μ œν•˜κ³  interruptible의 이름을 shutDownAble둜 λ³€κ²½ν–ˆμŠ΅λ‹ˆλ‹€.

 

@Getter
@AllArgsConstructor
public enum JBMBDiagnosisStateIdentifier {

    OPEN(1, "진단 μ‹œμž‘", true),
    SURVEY(2, "섀문쑰사 진행", true),
    UPLOAD(3, "이미지 μ—…λ‘œλ“œ", true),
    DIAGNOSE(4, "진단 쀑", true),
    DONE(5, "진단 μ™„λ£Œ",false),
    ERROR(6, "μ—λŸ¬ λ°œμƒ", false),
    SHUTDOWN(7, "진단 쀑단", false);

    private int stateCode;
    private String stateDescription;
    private boolean shutDownAble;

}

 

또, shutDownAble을 톡해 필터링을 ν•˜λŠ” λ‘œμ§λ„ 일뢀 μˆ˜μ •ν–ˆμŠ΅λ‹ˆλ‹€.

// κΈ°μ‘΄ μ½”λ“œ
.filter(diagnosisInfo -> JBMBDiagnosisStateIdentifier
	.isShutDownAble(diagnosisInfo.getDiagnosisState()))
// λ³€κ²½ μ½”λ“œ
.filter(diagnosisInfo -> Optional.ofNullable(diagnosisInfo)
	.map(JBMBDiagnosisInfoEntity::getDiagnosisState)
	.map(JBMBDiagnosisStateIdentifier::isShutDownAble)
	.orElse(false))

 

기쑴에 μƒμ„±ν–ˆλ˜ λΆˆν•„μš”ν•œ λ©”μ„œλ“œλ₯Ό μ‚­μ œν•˜κ³ , NPE λ°œμƒμ„ μ €μ§€ν•˜κΈ° μœ„ν•΄ Optional을 μ‚¬μš©ν•œ ꡬ문으둜 λ³€κ²½ν–ˆμŠ΅λ‹ˆλ‹€.

뒀에 μƒνƒœ λ³€κ²½ ν›„ save ν•˜λŠ” 둜직이 있기 λ•Œλ¬Έμ—, Optional λ‚΄λΆ€κ°€ λΉ„μ–΄μžˆλ‹€λ©΄ false 처리λ₯Ό ν•΄ save λ˜λŠ” 뢀뢄에 닿지 μ•Šλ„λ‘ λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€.

 


 

πŸ€” 2. 응닡에 κ³΅ν†΅ν•„λ“œκ°€ λ§Žλ‹€! : DTO μ •μ˜

 

기쑴의 responseDTO듀을 보면, 항상 λ‚΄λΆ€ 둜직의 성곡/μ‹€νŒ¨ μ—¬λΆ€λ₯Ό ν™•μΈν•˜κΈ° μœ„ν•΄ resultCodeλ₯Ό λͺ…μ‹œν–ˆμŠ΅λ‹ˆλ‹€.

μ΄λŸ¬ν•œ resultCodeλŠ” μ–΄λ– ν•œ 응닡이라도 λͺ¨λ‘ ν‘œκΈ°κ°€ λ˜μ–΄μžˆμ—ˆκ³ , ν•΄λ‹Ή resultCodeκ°€ μ–΄λ–€ 의미λ₯Ό λ‚˜νƒ€λ‚΄λŠ”μ§€, resultMessage도 κ³΅ν†΅μ μœΌλ‘œ ν•„μš”ν–ˆμŠ΅λ‹ˆλ‹€.

 

κ·Έ 외에도 error μ—¬λΆ€, error λ©”μ‹œμ§€, errorκ°€ λ°œμƒν•œ μ›μ²œ, 응닡 λ°œμƒ μ‹œκ°„ λ“±λ“± λ‹€μ–‘ν•œ μš”μ†Œλ₯Ό κ³΅ν†΅ν•„λ“œλ‘œ λ¬Άμ–΄μ„œ 보내고 μ‹Άμ—ˆμŠ΅λ‹ˆλ‹€.

κ³΅ν†΅ν•„λ“œλ‘œ λ¬Άμ–΄μ„œ 보낼 수 μžˆλŠ” 방법은, μ œλ„€λ¦­ / 상속 / ꡬ성 쀑 ν•˜λ‚˜λ₯Ό μ„ νƒν•˜λŠ” λ°©λ²•μž…λ‹ˆλ‹€.

또 λ§Žμ€ DTO 클래슀 파일이 μƒκΈ°λŠ” 것을 λ³΄μ™„ν•˜κΈ° μœ„ν•œ λ°©λ²•μœΌλ‘œλŠ” μ΄λ„ˆν΄λž˜μŠ€λ₯Ό μ‚¬μš©ν•˜λŠ” 방법이 μžˆμŠ΅λ‹ˆλ‹€.

 

μ΅œμ’…μ μœΌλ‘œ μ œκ°€ μ„ νƒν•œ 방법은, μ œλ„€λ¦­μ„ μ‚¬μš©ν•˜λ©΄μ„œ 내뢀에 λ“€μ–΄κ°ˆ DTOλŠ” μ΄λ„ˆν΄λž˜μŠ€ 내뢀에 static으둜 μƒμ„±ν•˜λŠ” 방법을 μ„ νƒν–ˆμŠ΅λ‹ˆλ‹€.

- κ³΅ν†΅ν•„λ“œκ°€ μˆ¨κ²¨μ§„ 상속과 κ΅¬μ„±λ³΄λ‹€λŠ” κ°•λ ₯ν•˜κ²Œ νƒ€μž…μ„ λͺ…μ‹œν•  수 있고, νƒ€μž…μ„ λ³΄λŠ” κ²ƒλ§ŒμœΌλ‘œλ„ 관계λ₯Ό 확인할 수 μžˆλŠ” μ œλ„€λ¦­μ„ 선택
- μ‘λ‹΅λ§ˆλ‹€ μ„œλ‘œ λ‹€λ₯Έ DTOλ₯Ό μƒμ„±ν•˜λŠ” 것은 필연적, DTO 클래슀 파일이 ν”„λ‘œμ νŠΈ 폴더에 κ³Όν•˜κ²Œ λ§Žμ•„μ§€λŠ” 것을 막기 μœ„ν•΄ μ΄λ„ˆν΄λž˜μŠ€λ₯Ό μ‚¬μš©.
- κ³΅ν†΅ν•„λ“œμ™€ 같은 depth에 κ°œλ³„ DTO ν•„λ“œλ₯Ό ν™•μž₯ν•˜λŠ” 것이 μ•„λ‹ˆλΌ, responseBodyκΉŒμ§€ 곡톡 ν•„λ“œκ³ , ν•œ 단계 더 κΉŠμ€ depth에 κ°œλ³„DTOλ₯Ό λ„£κ³  μ‹ΆμŒ.

+ λ‹€λ₯Έ λ°©λ²•μœΌλ‘œ λ§Œλ“œλŠ” 것에 λŒ€ν•΄μ„œλ„ κ³ λ €ν•œ 흔적은 λ‹€λ₯Έ κΈ€μ—μ„œ μž‘μ„±ν•˜λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

@Builder
@Getter
public class JBMBResponseObject<T>{

    /* Http Status */
    /* μ‚­μ œ ν•„μš”, 이미 ResponseEntity에 있음. */
    private final Integer statusCode;

    /* μš”μ²­μ˜ λΉ„μ¦ˆλ‹ˆμŠ€ 둜직 처리 μ½”λ“œ */
    private final Integer resultCode;

    /* μš”μ²­ 처리 μ½”λ“œμ˜ λ©”μ‹œμ§€ */
    private final String resultMessage;

    /* λΉ„μ¦ˆλ‹ˆμŠ€ 둜직 처리 쀑, μ—λŸ¬ μ—¬λΆ€ */
    private final Boolean hasError;

    /* μ—λŸ¬ λ©”μ‹œμ§€, μ—†λ‹€λ©΄ None */
    private final String errorMessage;

    /* μ—λŸ¬ 근원지, μ—†λ‹€λ©΄ None */
    private final String errorSource;

    /* 응닡 μ‹œμ  */
    private final String responseAt;

    /* μš”μ²­ μ‹œ μ ‘κ·Όν•œ API의 URL */
    private final String requestURL;

    /* μš”μ²­ κ²°κ³Ό */
    private final T responseBody;

}
public class DiagnosisDTO {

    @Data
    @Builder
    @AllArgsConstructor
    public static class ResponseForInitDiagnosis {
        private Long diagnosisID;
    }
    
    ... μƒλž΅

    @Getter
    @Builder
    public static class RequestForInitDiagnosis {
        private String userID;
        private Boolean isThermal;
    }

    ... μƒλž΅
}

 

μ œλ„€λ¦­ νƒ€μž…μœΌλ‘œ μ •μ˜λœ JBMBResponseObject<T>λ₯Ό λ΄…μ‹œλ‹€.

ν•΄λ‹Ή λΆ€λΆ„μ—λŠ” λͺ¨λ‘ κ³΅ν†΅μ μœΌλ‘œ κ°€μ§€λŠ” ν•„λ“œμ— λŒ€ν•΄ λ‹€ λͺ…μ‹œν•  수 μžˆμŠ΅λ‹ˆλ‹€.

또 responseBodyκΉŒμ§€ κ³΅ν†΅μœΌλ‘œ κ°–κ³ , κ·Έ 내뢀에 λ“€μ–΄κ°€λŠ” κ°œλ³„μ μΈ κ°’λ“€λ§Œ ν•œ 단계 더 κΉŠμ€ depth에 ν‘œν˜„ν•  수 μžˆμœΌλ―€λ‘œ μ œκ°€ μ›ν•˜λ˜ κΌ΄κ³Ό λ™μΌν•©λ‹ˆλ‹€.

 

μ œλ„€λ¦­ νƒ€μž…μ—λŠ” μ–΄λ– ν•œ Custom DTO도 λ‹€ λ“€μ–΄κ°ˆ 수 있기 λ•Œλ¬Έμ— μ•žμœΌλ‘œ λ‹€λ₯Έ λ„λ©”μΈμ—μ„œ λ‹€λ₯Έ DTOλ₯Ό λ§Œλ“€λ”λΌλ„ μ—¬μ „νžˆ μž¬ν™œμš©ν•΄μ„œ μ‚¬μš©ν•  수 μžˆμ„ κ²ƒμž…λ‹ˆλ‹€.

 

응닡 별 DTOλŠ” μ΄λ„ˆν΄λž˜μŠ€λ‘œ λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€. static 클래슀둜 λ§Œλ“€μ–΄μ„œ DiagnosisDTO μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ§€ μ•Šμ•„λ„ 접근이 κ°€λŠ₯ν•˜λ„λ‘ λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€.

 

μ΄λ„ˆν΄λž˜μŠ€λ‘œ λ§Œλ“€μ—ˆκΈ° λ•Œλ¬Έμ— 도메인 λ³„λ‘œ 묢을 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. 진단 μ΄ˆκΈ°ν™” 응닡, μ„€λ¬Έ 쑰사 응닡, 이미지 제좜 응닡 λ“± ν”„λ‘œμ νŠΈ 폴더 내에 μ—¬λŸ¬ 파일이 μƒκΈ°λŠ” 것을 μ™„ν™”ν•˜κ³  내뢀에 λ„£μ–΄ 관리할 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

 

μ΅œμ’…μ μœΌλ‘œ return λ˜λŠ” νƒ€μž…μ˜ μ˜ˆμ‹œλ₯Ό 보면,

public ResponseEntity<JBMBResponseObject<DiagnosisDTO.ResponseForInitDiagnosis>> forInitDiagnosis
    (final JBMBRequestObject<DiagnosisDTO.RequestForInitDiagnosis> requestForInitDiagnosis) {
    	... μƒλž΅
    }

 

ResponseEntityκΉŒμ§€ λ”ν•΄μ§€λ‹ˆ κΈΈμ΄λŠ” ꡉμž₯히 κΈΈμ–΄μ‘Œμ§€λ§Œ, μ–΄λ–€ νƒ€μž…μ„ λ¦¬ν„΄ν•˜λŠ”μ§€ λ‚΄λΆ€λ₯Ό 잘 λ³΄μ—¬μ€λ‹ˆλ‹€.

1) ResponseEntity : status와 header와 bodyλ₯Ό ν¬ν•¨ν•œ 응닡 객체
2) JBMBResponseObject : JBMBμ—μ„œ λ§Œλ“  곡톡 응닡 객체
3) DiagnosisDTO.ResponseForInitDiagnosis : 진단 DTO μ€‘μ—μ„œ 진단 μ΄ˆκΈ°ν™”μ— κ΄€ν•œ 응닡

 

 

아직 ν•  일이 더 λ‚¨μ•˜μŠ΅λ‹ˆλ‹€.

ν•΄λ‹Ή DTOλ₯Ό μƒμ„±ν•˜κ³  λ‚˜μ„œ, 응닡을 생성할 λ•Œ λΉŒλ” νŒ¨ν„΄μ„ μ‚¬μš©ν•œ μ˜ˆμ‹œμž…λ‹ˆλ‹€.

 return ResponseEntity.ok()
	.contentType(MediaType.APPLICATION_JSON)
	.body(JBMBResponseObject.<T>builder()
		.statusCode(...)
		.resultCode(...)
		.resultMessage(...)
		.hasError(...)
		.errorMessage(...)
		.errorSource(...)
		.requestURL(...)
		.responseAt(...)
		.responseBody(...)
		.build()
);

μ΄λŸ¬ν•œ 응닡을 μƒμ„±ν•˜λŠ” 것은 λͺ¨λ“  μ„œλΉ„μŠ€μ˜ λ©”μ†Œλ“œμ—μ„œ 적어도 ν•˜λ‚˜μ”© 생성될 κ²ƒμž…λ‹ˆλ‹€.

κ²½μš°μ— 따라 λ‹€λ₯Έ 응닡을 ν‘œν˜„ν•΄μ•Ό ν•˜λ―€λ‘œ νŠΉμ • μ„œλΉ„μŠ€μ˜ ν•œ λ©”μ†Œλ“œμ—μ„œ μ—¬λŸ¬λ²ˆ λ“±μž₯ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

μ„œλΉ„μŠ€μ˜ μ‘λ‹΅λ§ˆλ‹€ '성곡'κ³Ό 'μ‹€νŒ¨'λŠ” 무쑰건 μžˆμŠ΅λ‹ˆλ‹€. 또 'μœ νš¨ν•˜μ§€ μ•Šμ€ μš”μ²­'도 있죠.

 

이럴 λ•Œλ§ˆλ‹€ 맀번 μƒμ„±ν•˜λŠ” 것은 μ½”λ“œ 길이가 κΈΈμ–΄μ§ˆ μˆ˜λ„ 있고, λΆˆνŽΈν•©λ‹ˆλ‹€.

λ”°λΌμ„œ μž¬ν™œμš©μ„±μ΄ 높은 응닡을 μƒμ„±ν•˜λŠ” responseCreatorλ₯Ό λ§Œλ“€μ–΄λ³΄κΈ°λ‘œ ν–ˆμŠ΅λ‹ˆλ‹€.

 

λ‹€μŒ μ‹œκ°„μ—λŠ” Enumκ³Ό μ œλ„€λ¦­, μΈν„°νŽ˜μ΄μŠ€μ™€ 정적 νŒ©ν† λ¦¬ λ©”μ†Œλ“œ 등을 톡해 responseCreatorλ₯Ό λ§Œλ“€μ—ˆλ˜ λ‚΄μš©μ„ 적어보도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

 

[DEVLOG] μš°λ‹Ήνƒ•νƒ• 제발λͺ¨λ°œ v2 개발기 - νƒˆλͺ¨ 진단 API μˆ˜μ •ν•˜κΈ° (3) DTO에 λ”°λ₯Έ 응닡 생성 클래슀 만

😎 0. 이전 κΈ€ [DEVLOG] μš°λ‹Ήνƒ•νƒ• 제발λͺ¨λ°œ v2 개발기 - νƒˆλͺ¨ 진단 API μˆ˜μ •ν•˜κΈ° (1) λ³€μˆ˜ μž‘λͺ…, Optional, Enum ν™œμš© 🏝 0. μ„œλ‘  μ‘Έμ—…μž‘ν’ˆμœΌλ‘œ νƒˆλͺ¨ 진단 μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μΈ '제발λͺ¨λ°œ'을 κ°œλ°œν•˜κ³ , 'ν•΄λ‹Ή ν”Œ

hoons-dev.tistory.com