-
Notifications
You must be signed in to change notification settings - Fork 41
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
홈 화면에서 쓰이는 article api를 연동합니다. #93
Conversation
export const queryKeys = { | ||
articles: (params: ArticlesQueryParamsType) => ["articles", params] as const, | ||
}; |
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.
휴먼 에러가 잦기 때문에 상수로 queryKey를 관리해주고자 합니다
|
||
export const ArticleAuthorSchema = z.object({ | ||
username: z.string(), | ||
bio: z.nullable(z.string()), |
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.
api 명세에는 string이라고 되어있지만 실제 코드는 null로 내려오기때문에 nullable로 수정해줍니다.
const queryClient = getQueryClient(); | ||
|
||
await queryClient.prefetchQuery( | ||
queryKeys.articles({ | ||
offset: DEFAULT_ARTICLES_OFFSET, | ||
limit: DEFAULT_ARTICLES_LIMIT, | ||
}), | ||
() => | ||
http.get({ | ||
url: `/articles?offset=${DEFAULT_ARTICLES_OFFSET}&limit=${DEFAULT_ARTICLES_LIMIT}`, | ||
schema: ArticlesResponseSchema, | ||
}) | ||
); | ||
|
||
const dehydrateState = dehydrate(queryClient); | ||
|
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.
rsc에서 prefeching 하는 로직입니다.
차후 개발할 컴포넌트에서는 해당 rsc에서 prefetching 한 캐시를 끌어다가 바로 보여줍니다.
export const httpErrorHandler = (e: unknown, statusCode?: number): never => { | ||
switch (statusCode) { | ||
case 400: | ||
throw new Error(HTTP_ERRORS.BAD_REQUEST); | ||
case 401: | ||
throw new Error(HTTP_ERRORS.UNAUTHORIZED); | ||
case 403: | ||
throw new Error(HTTP_ERRORS.FORBIDDEN); | ||
case 404: | ||
throw new Error(HTTP_ERRORS.NOT_FOUND); | ||
case 500: | ||
throw new Error(HTTP_ERRORS.INTERNAL_SERVER_ERROR); | ||
default: | ||
if (e instanceof ZodError) { | ||
throw new Error(`유효성 검사 오류`); | ||
} else { | ||
throw new Error(`HTTP 오류`); | ||
} | ||
} | ||
}; |
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.
데이터 통신때 쓰이는 공통 에러 핸들러 입니다.
zodError를 통해 스키마가 변경되거나 다른 점을 파악합니다.
fetch는 직접 promise error 를 던지지 않기 때문에 tanstack query에서 사용할 수 있도록 에러를 직접 던져줍니다.
https://tanstack.com/query/v4/docs/react/guides/query-functions
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.
전 단순히 fetch 내에서 res.ok 를 활용했었는데 하나 배웠습니다!
if (accessToken) { | ||
headers.Authorization = `Bearer ${accessToken}`; | ||
} |
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.
아직 로그인을 구현하지 않아서 차후 jwt로 수정해볼 예정입니다.
📌 이슈 링크
📖 작업 배경
🛠️ 구현 내용
💡 참고사항
🖼️ 스크린샷
💡 리뷰 노트
에러 위임에 대해 공통 데이터 페칭 함수를 만들며 고민해볼 수 있었어요. 저는 tanstack query 를 사용하기 때문에 useQuery로부터 반환한 error property를 가장 가까운 컴포넌트의 Error boundary가 위임하여 전파되지 않도록 구성해보기로 결정했습니다.
일단 이렇게 하는게 가장 좋다고 생각한 이유는 오류 때문에 다른 부분에 영향을 받지 않는걸 중요하게 생각했습니다. 예전에 회사에서 아주 작은 컴포넌트에서 null값을 접근해서 웹 페이지 하나가 안나온 끔찍한 일이 있었습니다 하하 ㅎ
이를 위해 Fetch 함수에서 스스로 에러를 던져 tanstack query에서 에러를 감지할 수 있도록 공통 로직을 추가해주었습니다. 이렇게 고민하며 개발하니 좋긴한데 회사를 두개 다니는거 같군요