C.W.K.
Stream
Lesson 03 of 07 · published

프론트엔드에서 Rust 부르기

~13 min · tauri, invoke, frontend, ipc

Level 0웹 관광객
0 XP0/56 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"웹 쪽에서 네이티브 힘은 함수 하나야: invoke. 나머지는 뭘 넘기고 뭘 await 하느냐일 뿐."

코어에 닿는 함수 하나

invoke(@tauri-apps/api/core에서)는 웹뷰가 등록된 command를 부르는 방식이야. command 이름이랑 인자 객체를 주면, command가 반환한 걸로 resolve되는 Promise를 돌려줘. Promise니까 await하고 try/catch로 감싸 — fetch랑 똑같이. 서버랑 대화할 때 이미 가진 멘탈 모델이 그대로 옮겨가.

camelCase ↔ snake_case 다리

누구나 한 번 놀라는 관례야: Rust 파라미터는 user_id(snake_case, 관용 Rust)인데, JavaScript에선 { userId }(camelCase, 관용 JS)를 넘겨. Tauri가 자동으로 매핑해. JS에서 snake_case로 보내면 인자가 조용히 안 묶여. camelCase로 보내면 그냥 돼. 각 언어가 제 스타일을 지키게 하고, 이음매는 Tauri가 처리해.

가능하면 반환을 타이핑해

TypeScript에선 invoke가 제네릭이야: invoke<Note>('get_note', { id })는 resolve 값이 Note라고 컴파일러한테 알려줘. 근데 이건 Rust command가 진짜 그 모양을 반환할 때만 정직해 — 두 쪽 사이엔 컴파일 타임 연결이 없으니, 네가 쓰는 타입은 네가 하는 약속이야. typed-ipc 레슨이 그 약속을 깨기 어렵게 만드는 법을 보여줘.

Code

invoke: 코어로 가는 유일한 문·tsx
import { invoke } from "@tauri-apps/api/core";

// 간단한 호출 — camelCase 인자가 snake_case Rust 파라미터에 매핑.
const greeting = await invoke<string>("greet", { name: "Pippa" });

// Rust 파라미터는 `user_id`; JS는 `userId` 보냄. Tauri가 case를 다리 놓아.
const note = await invoke<Note>("get_note", { userId: 42, noteId: 7 });

// fetch랑 똑같이 다뤄: await + try/catch.
try {
  const sum = await invoke<number>("add", { a: 2, b: 3 });
  console.log(sum); // 5
} catch (err) {
  console.error("command failed:", err);
}

External links

Exercise

지난 레슨에서 쓴 add command를 프론트엔드 버튼에 엮어: 클릭하면 invoke<number>('add', { a, b }) 하고 결과를 렌더링해. 그다음 일부러 파라미터를 first_number 같은 여러 단어로 바꾸고 JS에서 first_number를 보내서 실패하는 걸 봐 — 그 실패가 어떤 문서보다 camelCase 규칙을 잘 가르쳐.
Hint
import { invoke } from '@tauri-apps/api/core'. 실패 데모는 Rust 파라미터를 first_number로 바꾸고, { firstNumber }(됨) vs { first_number }(잘못 묶임)를 보내서 관례를 느껴봐.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.