Skip to content
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: 마이페이지 마크업 #14

Merged
merged 7 commits into from
Jul 31, 2024
Merged

Feat: 마이페이지 마크업 #14

merged 7 commits into from
Jul 31, 2024

Conversation

moong23
Copy link
Contributor

@moong23 moong23 commented Jul 29, 2024

Why need this PR❓

마이페이지 마크업
https://inspomailclub.atlassian.net/jira/software/projects/INSPO/boards/1/timeline?selectedIssue=INSPO-46

Changes ✌️

  • 마이페이지 마크업

Screenshoot 🌅 (optional)

/mypage
image
/mypage/subscribe
image

Copy link
Contributor Author

@moong23 moong23 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

약간의 설명이 필요한 부분이 있다고 판단되어 리뷰 남겨놓았습니다!

<span className='py-2'>
<SubscribeButton isSubscribed={brand.subscribed} />
</span>
<DomainListItem domainData={domain} isSubscribed={domain.isSubscribed} />
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 중복되는 UI 로직이 있어서 DomainListItem으로 뺐습니다

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인해보고 싶어서 서버 켜봤는데 오류뜨는지라... ㅜ 확인이 쉽지않네요 ㅎㅎ..
나중에 다시 확인해보겠습니당

src/app/main/TodayTab/RecommendArea.tsx Show resolved Hide resolved
Comment on lines +7 to +10
//TODO: 추후 로그인 로직 완성 후 주석 교체
const userData: UserDataType = await getUserData();
// const userData = cookies().get('userData');

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UserDataCard에서 유저의 정보(이름, 이메일, 태그 유형, 프로필사진)를 받아오기 위해

  1. API 호출을 해야하는가
  2. 저장소에서 가져와야하는가

에서 2번을 선택했는데, next의 SSR특성상 localStorage에는 접근할 수 없어서
유저 정보를 로그인하면 쿠키에 저장하고, 필요한 곳에서 쿠키를 꺼내어 쓰는거로 설계를 했는데요,
혹시 이해가 안가는 부분이나, 더 나은 방법이 있다면 말씀주세요!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

한번에 코멘트 남길게요!

src/components/Domain/DomainListItem.tsx Outdated Show resolved Hide resolved
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네이밍을 DomainListTap에서 AlternateListTap으로 변경했는데요,
ListTap이 /main에서는 n개의 ListItem을 가지고, 나머지에서는 1개를 가지는 공통점이 있어서
부모에서 props를 통해 tapNametapCount를 내려주는것으로 설계를 변경했습니다

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분도 제대로 확인은 못했는데, 나중에 다시 확인해보고 답변드리겠습니다!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Next.js공식 문서를 보고 middleware를 사용하여 protected route를 구현하려 합니다.
현재 로그인 로직의 설계가 어떻게 될지 트래킹을 하고 있지 않아서, 주석을 통해 간단한 설명을 적어놓긴했으나,
조금 더 자세히 설명드리기 위해 리뷰 남겨놓아요!

마이페이지 마크업을 하면서 최소 로직에 대한 구현도 같이 했는데, 위의 src/app/mypage/UserDataCard.tsx 파일의 comment에서 설명했듯, 쿠키를 통한 userData 보관 및 사용을 하도록 설계했습니다.
이를 위해 로그인이 끝나면 next/servercookies를 통해 쿠키에 user의 profile데이터를 삽입해주시면 됩니다.

이후, 어떠한 이유에 의해 (테스트/ 버그 등등...) 로그아웃을 누르지 않았지만 쿠키가 삭제되는 경우,
middleware를 통해 cookie의 값을 확인하고 만약 없다면,

  1. accessToken이 있다면 다시 로그인을 시도합니다.
  2. 1이 없거나, 로그인에 실패하는 경우 로그아웃 로직을 실행하고, 메인페이지로 쫓아냅니다
    의 로직을 실행합니다.

또한, 가장 아래의 config는 matcher에 해당하는 파일에 대해서 middleware를 실행하게 되는데,
현재 테스트상으로는 MSW와 충돌하지는 않지만, MSW가 api를 가로채갈 때 middleware가 실행되는것을 5번줄을 통해 확인할 수 있었습니다.
그래서 matcher에 MSW 파일을 제거해야하나 싶었지만, 이후 api를 보낼 때 쿠키값을 확인하고자 한다면 이를 활용할 수도 있을 것 같아서 남겨놓긴했습니다.
만약 해당 기능이 필요없다고 판단되시면 matcher에 msw파일 경로도 추가해주시면 될 것 같습니다!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분도 한번에 댓글 남길게요!

Copy link
Contributor

@dladncks1217 dladncks1217 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@moong23 빠르게 마크업 작업 해주셨군요! 감사합니다👍👍

코멘트에 남겨주셨던 부분 중, 인증인가 관련한 부분에 대해 답변을 조금 길게 남길 것 같습니다.
우선 현재 서버사이드렌더를 하여 구독 관리나 프로필 UI를 띄워주고 있는데, 이 부분에서 조금 의문이 드는게 몇가지 있습니다.

1

첫 번째로, 근본적으로 이 부분을 SSR로 가져가야 하는가? 라는 의문이 들더라구요.
우선 이 페이지는 사용자가 이미 로그인을 한 뒤, 개인정보가 들어가는 페이지인지라, SEO를 고려할 이유가 없습니다.
그럼 우리가 SSR을 사용하여 얻을 수 있는 장점은 초기 fetch 시에 렌더가 되는 시간을 단축할 수 있다는 점이 가장 크지 않을까 싶습니다.

문제는 우리 백엔드가 지메일API를 쓰고 있다는 점입니다.
스크린샷 2024-07-30 오후 3 56 06
대충 플로우는 이렇게 될텐데, 백엔드에서도 지메일쪽 API를 거쳐서 데이터를 받아와야 하기에 결코 가벼운 작업이 아닙니다.
이렇게 되면 api응답시간이 길어질 확률이 높은데, 지금같이 SSR을 유지하게 되면 API응답 속도 자체가 느려 사용자가 아예 빈 페이지를 보는 시간이 늘어나지 않을까 하는 생각이 들더라구요.

이렇게 될거라면 차라리 클라이언트 컴포넌트로 변경해서 Suspense 묶고 로딩스피너를 띄워주는게 더 UX적으로 괜찮지 않을까? 하는 생각이 들었습니다.

프로필 가져오는 부분도 Suspense로 묶어서 같이요!
이 부분에 대해서는 어떻게 생각하시는지 궁금합니다!

2

둘째로, 유저의 정보를 받아오는 부분에 대해서도 조금 맘에 걸리는 부분이 있습니다.
실제로 저장소에 저장하여 가져오는 로직을 작성한 이유가 http트랜잭션을 한번 줄이기 위해서가 아닐까 싶습니다.
그런데 이 부분은 백엔드측에서도 user테이블에서 데이터를 가져올테니 join이 있을 수 없는 select작업일테고, 비용보다는 데이터의 무결성이 조금 더 중요하지 않을까 하는 생각이 들었습니다. (밑에서 다시 이야기했습니다)

만약 그럼에도 서버측에서 유저데이터를 받아서 저장하고 싶다면, next자체 fetch를 사용하는 방법도 있을 것 같습니다!

3

아니면 이건 저도 안해보긴 했는데, streaming HTML이라고, 페이지 단위가 아닌 컴포넌트 단위로 SSR요청을 할 수 있는게 있는 것 같더라구요.
서버 컴포넌트에 데이터 페칭이 없는 애를 먼저 만들고, 그 서버 컴포넌트 안에 suspense가 걸려있도록
하며, suspense 안에는 데이터를 페칭하는 서버 컴포넌트를 각각 주입하는 방식으로 하는 것 같더라구요!
폴백에는 로딩스피너 넣구요 ㅎㅎ

꼭 이게 좋다는건 아니니 가볍게 한번 보시면 좋을 것 같아 관련 링크 하나 남겨봅니다..! (저도 안해봤습니다 ㅋㅋ)
React 18: Streaming HTML and Selective Hydration 부분입니다
reactwg/react-18#37

4

인증인가 방식 세션방식으로 확정됐습니다..!
토큰 안할것같아용

<span className='py-2'>
<SubscribeButton isSubscribed={brand.subscribed} />
</span>
<DomainListItem domainData={domain} isSubscribed={domain.isSubscribed} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인해보고 싶어서 서버 켜봤는데 오류뜨는지라... ㅜ 확인이 쉽지않네요 ㅎㅎ..
나중에 다시 확인해보겠습니당

Comment on lines +7 to +10
//TODO: 추후 로그인 로직 완성 후 주석 교체
const userData: UserDataType = await getUserData();
// const userData = cookies().get('userData');

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

한번에 코멘트 남길게요!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분도 제대로 확인은 못했는데, 나중에 다시 확인해보고 답변드리겠습니다!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분도 한번에 댓글 남길게요!

@moong23
Copy link
Contributor Author

moong23 commented Jul 30, 2024

빠른 리뷰 고마워요~!

어제 구현하면서 next에 대한 이해가 조금은 부족한것 같아서 next.js의 공식 문서를 읽으면서 조금의 개선사항에 대해 생각이 든 부분을 남겨놓겠습니다!


1. SSR으로 가져가야 하는가

-> 해당 부분에대해서 문제점을 느끼고 현재 jira에 error 처리용과 loading 처리용 티켓을 끊어두었습니다!
말씀하신대로 Suspense로 묶고 최소한의 UI만 남긴채 데이터 부분은 SEO가 필요없으니 Suspense로 묶어서 처리하는것이 좋아보입니다!

2. 유저 데이터 fetch

-> (제가 내용을 제대로 이해한것인지 모르겠습니다ㅠㅠ) 우찬님께서 말씀하신 부분은

  1. API의 비용이 매우 작은 작업임
  2. 비용이 적어서 데이터의 무결성을 굳이 희생할 필요가 없는 작업으로 판단됨
  3. 만약, 저장을 하고싶다면 next의 fetch를 통해 cache한 후 이를 사용하는것은 어떠한가
    로 이해를 했는데요, 위와같이 이해한 바에 대해 제 생각은 아래와 같습니다!

일단은 제가 API를 호출하지 않고 저장소에 저장하여 사용해야겠다고 생각한 이유는
해당 로직이 middleware.ts에 있어서 모든 페이지를 들어가고 나올때마다 실행이 되기 때문에 API가 과도하게 호출되는것은 아닐까 하는 우려가 가장 크게 작용한 것 같습니다.

1, 2 : 비용이 매우 작은 작업이여서 무결성을 희생할 필요가 없는것에 동의합니다.
3 : next의 fetch를 통해 캐싱을 한다고 하면 저장소(cookie)에 저장하여 사용하는 것에서 cache의 validation 주기가 끝나면 새로 fetch한다는 차이점 외의 다른 점이 어떤것이 있는지 궁금합니다.
만약 유저 데이터에 대한 변경이 일어난다면, 클라이언트측에서의 조작으로 일어나게 될 것인데 (서버에서 직접 데이터를 건드리는 비정상을 제외하고)
조작이 일어날 때 next에서 제공하는 메서드인 revalidateTag를 사용하여 cache를 컨트롤하는것은 어떠할까요?
해당 작업을 통해
i) 개발자가 캐시 데이터에 대한 컨트롤을 (사이드 이펙트 없이 - 상황따라 다를지도.....) 할 수 있음
ii) userData를 가져오는 API에 대한 호출을 줄일 수 있음
의 효과가 있을 것 같다고 예상됩니다.

3. Streaming HTML

안그래도 오늘 공식문서 보면서 해당 게시글을 보고 이거 쌈@뽕 하구만 하고 생각을 했죠ㅎㅎㅎ
해보면 재밌을 것 같아요!
next의 공식문서에서는 chatgpt에서 한번에 글을 보내주는 것이 아닌, 타이핑 하듯이 보내주는 효과 (+ 느린 연산속도를 개선하는 부가효과)를 내는 방식으로 설명되어있더라구요! 해당 내용도 첨부합니다

4. Session

확인했습니다~!

@moong23
Copy link
Contributor Author

moong23 commented Jul 31, 2024

@dladncks1217 어제 깜빡하고 멘션을 안했네요 ㅎㅎ
위에 답변도 확인 부탁드리고 오늘 하루도 화이팅임니다~!!

@dladncks1217
Copy link
Contributor

@moong23 아아 리뷰 달려있었군요!
여기서 화살표 동그라미 저친구 누르면 리뷰 다시 갑니다 ㅎㅎ 저거 눌러주시면 될 것 같아요!
스크린샷 2024-07-31 오전 10 14 12

오늘 확인해보고 다시 리뷰 남길게요~!

@dladncks1217
Copy link
Contributor

dladncks1217 commented Jul 31, 2024

@moong23

  1. ~ API의 비용이 매우 작은 작업임
    비용이 적어서 데이터의 무결성을 굳이 희생할 필요가 없는 작업으로 판단됨
    만약, 저장을 하고싶다면 next의 fetch를 통해 cache한 후 이를 사용하는것은 어떠한가
    로 이해를 했는데요, 위와같이 이해한 바에 대해 제 생각은 아래와 같습니다!

사실 어찌되었든 백엔드측에서도 DB트랜잭션이 발생한느거고, 백과 클라이언트 사이에서도 http트랜잭션이 발생하는거라 비용이 엄청 작고 그런건 아니긴 합니다 ㅎㅎ...
그러나 동작이 한단계 추가되면서 복잡도가 올라가는 것 같다고 해야할까요?

어제 조금 급하게 리뷰하느라 말이 앞뒤가 조금 다르게 느껴지기도 하는데요, 결론적으로는 백이랑 한번 더 통신하는것과 쿠키사용을 종합적으로 비교했을때
트랜잭션 한번을 일으키는 비용보다 쿠키로 관리하여 올라가는 복잡성을 관리해야 하는 비용이 더 크다고 느껴졌어요.
지금 저희 서비스 상태가 트랜잭션 한번 더 일어난다고 부하가 엄청나게 일어나는 상황도 아니니까요! 장기적으로 봤을 때도 사용자가 상상 이상으로 어마어마하게 늘지 않는 이상 서비스 부하를 일으킬 동작은 아니라서요.

복잡도도 복잡도지만 이 한번을 줄이기 위해 쿠키에 데이터를 저장해서 관리한다는게 어색하게 느껴졌습니다...🥹
어차피 캐싱을 하는 이상 무결성은 깨지긴 합니다만, next fetch를 이용하면 캐시를 이용해 저희가 직접 핸들링해서 코드의 복잡도를 늘릴 일은 줄어드니까요! 그래서 한번 이런건 어떤지 물어봤던겁니다 ㅎㅎ

꼭 캐시나 쿠키같은 무언가 직접 핸들링해야하는 명확한 이유가 있다거나, 그런거 없이 할 수 있는 더 편한 방법이 있을까요!?
있다면 그 방법도 좋을 것 같습니다 🙂


  1. ~ 안그래도 오늘 공식문서 보면서 해당 게시글을 보고 이거 쌈@뽕 하구만 하고 생각을 했죠ㅎㅎㅎ
    해보면 재밌을 것 같아요!

Streaming HTML의 경우 1번에 드렸던 답변과 이어지는거로, 이런방법도 있을 것 같다고 쓰긴 한건데 저도 한번도 안해보긴 했습니다 ㅋㅋㅋㅋ
리소스남는다면 한번 시도해보는것도 좋을것같아요👍👍


우선 마크업은 머지하고, 코드 자체는 차차 계속 개선해가는걸로 하시죠!
인증인가는 이번pr에서는 제외하고, 다른 PR로 묶어서 진행하는게 어떨까요?
아무래도 핵심 로직중 하나이다보니 한명이 맡아서 진행해도 다른 한명이 팔로업이 필요할 것 같아요.
주말에 어차피 만날테니 백엔드도 포함해서 같이 페어로 작업 진행하는것도 좋지 않을까 싶어 여쭤봅니다 ㅎㅎ

@moong23
Copy link
Contributor Author

moong23 commented Jul 31, 2024

@dladncks1217

복잡도도 복잡도지만 이 한번을 줄이기 위해 쿠키에 데이터를 저장해서 관리한다는게 어색하게 느껴졌습니다...🥹
어차피 캐싱을 하는 이상 무결성은 깨지긴 합니다만, next fetch를 이용하면 캐시를 이용해 저희가 직접 핸들링해서 코드의 복잡도를 늘릴 일은 줄어드니까요! 그래서 한번 이런건 어떤지 물어봤던겁니다 ㅎㅎ

쿠키와 API 둘의 장점을 모두 수용할 수 있는 것이 next의 fetch사용이라고 생각되네요! fetch를 사용하고, cache control을 하는것이 현재 생각나는 방안중에는 최선의 방법으로 생각되네요!

로직을 fetch로 바꾼다고 해도 인증인가 구현하고나면 매우 높은 확률로 해당 Fetch 로직도 변경되야할것같아서
우선 머지 하고 인증인가 구현 이후에 middleware.ts의 로직 수정하도록 하겠습니다!
approve 주시면 머지 바로 진행할게요!

Copy link
Contributor

@dladncks1217 dladncks1217 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다 👍

@moong23 moong23 merged commit a43425b into dev Jul 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants