개발자
next에서 발표한 예시를 보니까 서버 함수를 한 파일에 선언해놓고 client 컴포넌트에서 import해서 호출 하던데 어떻게 client 컴포넌트안에서 서버 함수 호출을 할 수 있는건가요? 서버 함수 원리가 뭐에요?
답변 3
인기 답변
한줄요약 : 컴파일할 때 api endpoint가 자동으로 생성됩니다 ============ 상세 : next.js 컴파일시에 각 서버 액션마다 고유의 라우팅 경로가 할당됩니다 길이 40의 유니크 문자열인데 예를들어 '984ed20e3a894190cd12e4db981795e43fe8c042' 입니다. 아래의 함수에 해당 유니크 문자열이 할당되었다고 가정해보죠 ``` const double = async (x) => { 'use server' return x * 2 } ``` 위의 함수를 클라측에서 호출하면 실제로는 POST 리퀘스트를 보냅니다. 이 포스트 리퀘스트의 헤더에 앞서 언급한 길이 40의 유니크 문자열이 삽입됩니다 (Next-Action : 984ed20e3a894190cd12e4db981795e43fe8c042 ) 서버에서 리퀘스트 헤더에 "Next-Action"가 있음을 발견하면 미들웨어를 거쳐 서버 액션으로 라우팅을 시도합니다. 서버측 코드는 대충 아래와 같은데 actions 객체에서 길이 40문자열을 key로 검색하여 해당되는 함수를 호출합니다. 그리고 그 리턴값을 클라에 리스폰스합니다. 헤더는 서버 내부에서 알아서 만들어줍니다
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
const actions = { '984ed20e3a894190cd12e4db981795e43fe8c042': () => Promise.resolve(/*! import() eager */).then(__webpack_require__.bind(__webpack_require__, /*! ./app/page.tsx */ "(sc_server)/./app/page.tsx")).then(mod => mod["$$ACTION_1"]), 'de2bf68228b1646b804999ab9435ff2680394844': () => Promise.resolve(/*! import() eager */).then(__webpack_require__.bind(__webpack_require__, /*! ./app/form.jsx */ "(sc_server)/./app/form.jsx")).then(mod => mod["$$ACTION_0"]), '5cdd3617cdea29460a8159ca74db3fa1ba8f1353': () => Promise.resolve(/*! import() eager */).then(__webpack_require__.bind(__webpack_require__, /*! ./app/form.jsx */ "(sc_server)/./app/form.jsx")).then(mod => mod["$$ACTION_1"]), '8002fb3231a504b1521160aa96385d1ae890ef51': () => Promise.resolve(/*! import() eager */).then(__webpack_require__.bind(__webpack_require__, /*! ./app/form.jsx */ "(sc_server)/./app/form.jsx")).then(mod => mod["$$ACTION_2"]), '3cac4756d16f027814798d0be8ceddee7f3cbad4': () => Promise.resolve(/*! import() eager */).then(__webpack_require__.bind(__webpack_require__, /*! ./app/actions.jsx */ "(sc_server)/./app/actions.jsx")).then(mod => mod["inc"]), 'adca8e71732477f600a9ce69c1bbf5899ee012f8': () => Promise.resolve(/*! import() eager */).then(__webpack_require__.bind(__webpack_require__, /*! ./app/actions.jsx */ "(sc_server)/./app/actions.jsx")).then(mod => mod["default"]), } async function endpoint(id, ...args) { const action = await actions[id]() if (action.$$with_bound === false) { return action.apply(null, args) } return action.call(null, args) }
인기 답변
안녕하세요! 위 답변이 서버 함수 생성 방식을 잘 설명해주고 계셔서 저는 참고하면 좋을법한 링크들만 첨부하겠습니다. 보안 관련 이슈, react useTransition으로 사용하는 방법, 캐싱 처리, 데이터 검증 등 여러가지 기능들과 어떻게 상호작용하는지 실험하고 있는 단계인 것 같아요. 아직 알파 단계여서 세부 구현 방식은 스테이블 릴리즈전까지 충분히 변경될 여지가 있을 것 같습니다 :) - https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions#server-actions - https://www.youtube.com/watch?v=pDtlal2-oEE - https://www.youtube.com/watch?v=9WvJDor5uvo - https://medium.com/front-end-weekly/why-next-js-server-actions-are-game-changing-20025c9a3551
손정현
엔지니어 • 2023년 05월 14일
TMI: 컴파일러 코드는 next-swc 경로에서 찾을 수 있네요! 러스트로 되어있습니다. - https://github.dev/vercel/next.js/blob/afddb6ebdade616cdd7780273be4cd28d4509890/packages/next-swc/crates/core/src/server_actions.rs
Next.js의 Server Action은 클라이언트에서 서버 쪽 함수를 호출할 수 있는 기능입니다. 이를 통해 서버 쪽 로직을 클라이언트에서 직접 실행할 수 있습니다. Server Action은 'next/serve'r 모듈에서 제공되는 'createActionHandler' 함수를 사용하여 구현됩니다. 이 함수를 통해 서버에서 실행되는 함수를 정의하고, 클라이언트에서 이를 호출할 수 있습니다. 서버 함수를 선언할 때는 'createActionHandler' 함수에 대상 함수와 해당 함수를 식별할 수 있는 이름을 매핑하는 방식으로 작성합니다. 이렇게 정의된 서버 함수는 Next.js 애플리케이션의 라우트 핸들러로서 사용됩니다. 클라이언트에서는 해당 서버 함수를 'next/link' 모듈의 'Link' 컴포넌트를 사용하여 호출할 수 있습니다. 서버 함수의 원리는 Next.js의 라우팅 시스템과 관련이 있습니다. 클라이언트가 서버 함수를 호출하면 Next.js는 서버 쪽에서 해당 함수를 실행하고, 결과를 클라이언트로 반환합니다. 이를 통해 서버와 클라이언트 간의 상호작용이 가능해지며, 서버 로직을 클라이언트에서 호출하여 처리할 수 있습니다. 서버 함수를 사용하면 클라이언트와 서버 간의 데이터 통신과 비즈니스 로직 실행을 효율적으로 처리할 수 있습니다. 그러나 서버 함수를 사용할 때는 보안과 성능 측면을 고려하여 적절한 제약과 검증 메커니즘을 구현해야 합니다. 자세한 사용 방법은 Next.js 공식 문서에서 "Server Actions" 섹션을 참조하시면 됩니다.
커리어리 AI 봇의 답변을 평가해 주세요!
지금 가입하면 모든 질문의 답변을 볼 수 있어요!
현직자들의 명쾌한 답변을 얻을 수 있어요.
이미 회원이신가요?
지금 가입하면 모든 질문의 답변을 볼 수 있어요!