fotcamp / tech-blog

Fotcamp Tech Blog
https://blog.fin-hub.co.kr/
1 stars 0 forks source link

feat: 조회수 기능 추가 #15

Closed hyun907 closed 1 month ago

hyun907 commented 1 month ago

📝 PR 유형

📝 PR 설명

notion DB에 views 프로퍼티 추가하여 조회수 기능 구현

관련된 이슈 넘버

✅ 작업 목록

MR하기 전에 확인해주세요

📚 논의사항

  1. Properties 타입을 따로 정의한 이유: 타입 확장
export interface PageProperties {
  views: {
    id: string;
    type: "number";
    number: number | null;
  };
}

이렇게 따로 타입을 정의한 이유는 추후 다른 properties 추가할 때도 타입 확장하는 방향으로 가면 좋지 않을까 해서 만들었습니다. 예를 들어, 여기서 기존 MultiSelectOption 인터페이스 (role의 mutiselect) 도 독립적인 타입으로 구분하지 말고 PageProperties 안에

interface PageProperties {
  views: { id: string; type: "number"; number: number | null };
  role: {
    id: string;
    type: "multi_select";
    multi_select: Array<{ id: string; name: string; color: string }>;
  };
}

이런 형식으로 다시 정의해주면 가독성도 좋고 재사용하기 쉬울 것 같습니다. 노션 페이지에서 받아오는 응답이 복잡하고 많기는 해도 한 번 이렇게 정리하면 안전성이 올라갈 것 같고, view를 추가한 것처럼 다른 properties 추가할 때도 타입 확장하는 방향으로 가면 좋을 것 같아서 정의했습니다.

만약 하게 된다면, 이 작업은 나중에 브랜치 다시 파서 작업하도록 하겠습니다! 제가 혼자 생각한 부분인데 더 좋은 의견 있으시면 공유 부탁드리겠습니다!!

  1. as unknwon 단언 방식
    const properties = page.properties as PageProperties;

    처음에는 이렇게 바로 PageProperties로 단언했는데, 오류가 발생하였습니다.

Conversion of type 'Record<string, { type: "number"; number: number | null; id: string; } | { type: "url"; url: string | null; id: string; } | { type: "select"; select: PartialSelectResponse | null; id: string; } | ... 19 more ... | { ...; }>' to type 'PageProperties' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. Property 'views' is missing in type 'Record<string, { type: "number"; number: number | null; id: string; } | { type: "url"; url: string | null; id: string; } | { type: "select"; select: PartialSelectResponse | null; id: string; } | ... 19 more ... | { ...; }>' but required in type 'PageProperties'.

Record<string, ...> 타입과 PageProperties 타입 간의 호환성을 명확하게 보장할 수 없기 때문에 발생하는 것 같습니다. (아마 노션 properties가 여러 속성을 포함하고 있을 수 있어서 노션 API에서 Record<string, ...>으로 정의한 것 같습니다.) 그래서 먼저 properties를 unknown으로 캐스팅한 후 PageProperties로 변환하도록 했는데, 이렇게 되면 unknown은 결국 모든 타입의 전체집합이라 어느 상황에서나 단언이 가능하기 때문에 그냥 강제로 타입 변환하는 것 외에 의미가 없는 코드 같아서 질문드립니다. 더 좋은 방법이 있을까요?

  1. 로딩 시간 페이지가 렌더링될 때마다 서버에서 조회수를 직접 업데이트하니 서버에서 처리되는 지연 시간이 조금 있는 것 같습니다. 해결 방법으로 승덕님이 답변 주신것처럼,
  1. Batch 처리를 통해 서버 요청을 최소화하기
  2. 클라이언트에서 로컬 상태 변경을 즉각 반영, 서버 요청은 비동기 요청 처리하기

이렇게 코드 수정하면 될 것 같습니다.

📚 ETC

image

새로고침 후 조회수 반영

https://github.com/user-attachments/assets/186a0409-b8e7-46a3-84a4-970cf831bfbe