ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Javascript Date타입 대신 date, time, date-time을 다루기
    Nest.js/class-transformer 2024. 7. 7. 15:02
    728x90

     

     

     

    이전에 작성한 글을 참고 하면 좋다.

     

     

    createdAt, updatedAt 의 date-time 형식 

    createdAt나 updatedAt 칼럼을 database에서 가져와서 일련의 데이터 가공 작업을 하고 api response할때 ISO 8601 포맷으로 리턴을 해주어야 한다.

     

    꽤나 오랜시간 고민을 많이 했다. repository에서 createdAt나 updatedAt 관련된 프로퍼티를 return 하는 방법을 고민 해보았다가 이것은 꽤나 많은 수정을 거쳐야 될것 같아서 아닌것 같았다.
    필요한 기능은 다음과 같다.

     

    1. database에서 select 해서 가져왔을때는 js-joda 타입으로 손쉽게 불변 date 객체를 다루어서 제공하는 메서드로 date를 자유롭게 가공 해야 된다.
    2. return 하는 순간에는 ISO 8601 포맷의 string으로 리턴 해야된다.

     

    애플리케이션 내에서는 js-joda 타입으로 유지되고 있다가 마지막에 response를 return 할때 변경이 이루어져야 되는데 생각 해보니 해당 부분을 해결 하기 위해서 responseDto 부분을 이용하면 좋을것 같았다.

     

    plainToInstance를 이용하여 responseDto의 인스턴스화 하기

    /**
     * @summary 특정 그룹의 그룹 이벤트 가져오기
     *
     * @tag groups
     * @param groupEventId 그룹 이벤트 아이디
     * @author YangGwangSeong <soaw83@gmail.com>
     * @returns void
     */
    @GetGroupEventByGroupEventIdSwagger()
    @UseGuards(GroupMemberShipGuard, IsMineGroupEventGaurd)
    @Get('/:groupId/group-events/:groupEventId')
    async getGroupEventByGroupEventId(
        @Param(
            'groupEventId',
            new ParseUUIDPipe({ exceptionFactory: parseUUIDPipeMessage }),
        )
        groupEventId: string,
    ) {
        const event = await this.groupEventsService.findOneGroupEvent(groupEventId);
    
        const result = plainToInstance(GroupEventItemResDto, event);
        console.log(result instanceof GroupEventItemResDto);
        console.log(result.eventGroup instanceof GroupProfileResDto);
    
        return result;
    }
    특정한 그룹 이벤트를 가져오는 api인데 event는 GroupEventItemResDto라고 추론 되게 명시적으로 선언 했지만 실제 GroupEventItemResDto의 인스턴스는 아니고 GroupEventEntity의 인스턴스이다. TypeOrm에서 find하게 되면 해당하는 entity클래스를 반환 해주기 때문이다. 그렇게 받아 온것을 아무래도 Dto로 인스턴스화 하는 코드는 controller에서 작성하는게 맞다.

     

    plainToInstance를 사용할때 만약에 중첩 객체인경우 plainToInstance는 중첩객체까지 인스턴스화 못해준다. 그럴 경우에 @Type 데코레이터를 써주자

     

    export class GroupEventItemResDto extends PickType(GroupEventEntity, [
    	'id',
    	'eventType',
    	'eventCoverImage',
    	'eventName',
    	'eventDescription',
    	'eventStartDate',
    	'eventStartTime',
    	'eventEndDate',
    	'eventEndTime',
    	'eventGroupId',
    	'eventOrganizerId',
    	'createdAt',
    ] as const) {
    	@ApiProperty({
    		nullable: false,
    	})
    	@Type(() => GroupProfileResDto)
    	eventGroup!: GroupProfileResDto;
    
    	@ApiProperty({
    		nullable: false,
    	})
    	@Type(() => MemberSearchResDto)
    	eventOrganizer!: MemberSearchResDto;
    }

     

     

    console.log(result instanceof GroupEventItemResDto);
    console.log(result.eventGroup instanceof GroupProfileResDto);

     

    true
    true
    결과가 정상적으로 나오는것을 알 수 있다!
    responseDto의 인스턴스화를 한 이유는 createdAt나 updateAt 칼럼을 response 할때 @Transform 데코레이터를 사용하기 위해서다.

     

     

    date(YYYY-mm-dd)형식

     

    - 작성예정

    time 시간형식

    - 작성 예정

     

     

    결론

    결론적으로
    1. 비지니스 로직을 수행 할때는 js-joda을 이용하여 날짜 시간과 관련된 데이터를 js-joda의 불변객체를 이용하여 다룬다.
    2. db에 저장 할때는 Javascript Date 객체로 변환하여 저장한다.
    3. response 할때는 response-dto와 @Transformer 데코레이터를 이용하여 원하는 형태로 return 한다. (ISO 8601) 

     

    Reference

    - (https://js-joda.github.io/js-joda/manual/LocalDate.html#get-values-from--code-localdate--code-)

    - (https://js-joda.github.io/js-joda/manual/LocalTime.html#get-values-from--code-localtime--code-)

    - (https://js-joda.github.io/js-joda/manual/LocalDateTime.html#get-values-from--code-localdatetime--code-)

    728x90
Designed by Tistory.