TIL

크롤링용 API 제공을 위한 API ROUTE 트러블 슈팅 기록 (Nextjs)

API를 제공하는 Nextjs 기능.
백엔드에서 별도 API를 만들 필요 없이, 기존 API를 조합해서 프론트에서 새로운 API를 제공할 수 있다는 장점이 있어
개발수행사 측에서 크롤링 업체에 제공하는 API를 API Route로 만들었다.(급하게..)


이슈 상황
다만 기존 api를 사용하는 것이기 때문에 api에 필요한 uuid 발급절차가 필요하고 최초 진입시 401 에러 발생은 불가피하나, 모든 호출 시 401 에러로 떨어지는 현상이 있었다. 
네트워크 상 304 error
로컬 확인 시 
API resolved without sending a response for /api/data, this may result in stalled requests.
해당 에러가 찍혀있는 것을 확인하였다. 
 
모든 api 호출 시 401 에러 이슈 원인
서버사이드로 백엔드 API 호출 시 uuid가 유효하지 않으므로 -> ERROR로 떨어지는데
이때 customInterceptorAxiosError로 잡아 uuid를 발급하고 uuid를 쿠키값에 넣어주는 작업이 이루어진다.
이 작업을 위해 api route에서 사용하고자 하는 api가 쿠키값(안에 있는 uuid 등)을 확인하고 제어하기 위해 getServerSideContext를 필수적으로 받게 되어있었다. getServerSideContext 안에 있는 req.cookie를 사용하기 위함으로 보인다.

*아래 내용 참고*

Context parameter

The context parameter is an object containing the following keys:

NameDescription
params If this page uses a dynamic route, params contains the route parameters. If the page name is [id].js, then params will look like { id: ... }.
req The HTTP IncomingMessage object, with an additional cookies prop, which is an object with string keys mapping to string values of cookies.
res The HTTP response object.
query An object representing the query string, including dynamic route parameters.
preview (Deprecated for draftMode) preview is true if the page is in the Preview Mode and false otherwise.
previewData (Deprecated for draftMode) The preview data set by setPreviewData.
draftMode draftMode is true if the page is in the Draft Mode and false otherwise.
resolvedUrl A normalized version of the request URL that strips the _next/data prefix for client transitions and includes original query values.
locale Contains the active locale (if enabled).
locales Contains all supported locales (if enabled).
defaultLocale Contains the configured default locale (if enabled).

 

API Route의 경우 서버사이드이긴 하지만 getServerSideProps를 사용하지 않기 때문에 getServerSideContext type을 넣을 수 없다. 다만 customInterCeptorAxiosRequest 소스 확인을 해보니
cosnt {req} = _context as GetServerSidePropsContext;
 
이런 식으로 코드가 짜여있어, 트릭이지만 호출 시 NextApiRequest를 오브젝트로 감싸서 {req : req}로 넣어줬다.
getServerSideContext type 대신 범용적인 type이필요할듯 하지만
회원 쪽은 담당하고 있지 않기 때문에 일단 이렇게 마무리.
 

 

이 외에도)
API resolved without sending a response for ~, this may result in stalled requests.

Node.js 쪽은 잘 몰라서 이해를 잘 못했었는데

숱한 구글링 끝에 결국 이유는 비동기처리에 대한 이슈였고 해당 에러는 개발에서 실수한 몇 가지가 그 이유였다. 
일단 해당 에러는 304(Not Modified)과 함께 날 수 밖에 없는 에러로 보인다.
 
Nextjs에서 최종으로 req에 대한 res를 처리를 해줘야하는데외부(백엔드) api를 호출하는 사이 (혹은 비동기 작업 사이에) 사용자 요청이 처리가 끝나버리는 상태인 것이다.따라서 실제 api를 호출하지 않고 클라이언트에서 캐시된 자원을 사용하는 상태인 304로 가 되어버린다. 의도적으로 304를 사용하는 것이 아니라 오류 상황이므로 수정을 해주었다.
 
원인은
1. asyn 핸들러에서 안에서 요청을 처리할 때 await을 붙여주지 않고 있었다... 럴루럴수 이럴수.. 
2. res를 반환할 때 json으로 보냄