본문 바로가기
C.W.K.
Stream
Lesson 04 of 07 · published

serde: 타입의 다리

~14 min · tauri, serde, serialization, rust

Level 0웹 관광객
0 XP0/56 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"serde는 다리 위에 서 있는 통역이야. Rust struct를 JSON으로, 다시 거꾸로 — 파싱 코드는 한 줄도 안 짜게 해줘."

derive만 붙이고 잊어버려

IPC 다리를 건너는 건 뭐든 평범한 데이터가 돼야 해. Rust에서 그 일을 맡는 크레이트가 serde야. struct나 enum에 #[derive(Serialize, Deserialize)]를 붙이면 serde가 변환 코드를 만들어줘. Serialize는 프론트엔드 나가는 길(command 반환값), Deserialize는 프론트엔드에서 들어오는 길(command 인자)을 맡아. JSON을 손으로 조립할 일은 이제 영영 없어.

struct는 양쪽으로 다녀

command는 struct를 받을 수도, 돌려줄 수도 있어. 프론트엔드가 평범한 객체를 보내면 네 Rust struct로 풀리고, command가 struct를 돌려주면 웹뷰가 받을 평범한 객체로 다시 접혀. 풍성한 데이터가 깔끔하게 건너는 방식이 이거야 — 양쪽 끝에선 타입의 모양으로 생각하고, 중간에서 오가는 포맷은 serde가 알아서 해.

필드 이름을 프론트엔드에 맞춰

Rust struct는 snake_case 필드(created_at)를 쓰는데, 네 TypeScript는 아마 camelCase(createdAt)를 원할 거야. struct에 #[serde(rename_all = "camelCase")]를 붙이면 serde가 오갈 때 필드 이름을 전부 바꿔줘. 그럼 Rust는 Rust답게 남고 프론트엔드는 기대하던 표기를 받아 — 인자 관례랑 똑같은 철학을 데이터 모양에 적용한 거야.

Code

양쪽으로 다니는 struct·rust
use serde::{Serialize, Deserialize};

// rename_all이 선로 JSON을 camelCase로 만들어 행복한 TS 프론트엔드에 맞추고,
// Rust는 관용적인 snake_case 필드를 지켜.
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct Note {
    id: u32,
    title: String,
    created_at: String,   // JS엔 `createdAt`로 도착
}

// struct 받고 struct 반환 — serde가 양방향 다 처리.
#[tauri::command]
fn save_note(draft: Note) -> Note {
    // ... 저장하고 ...
    draft  // 평범한 객체로 웹뷰에 다시 serialize
}
프론트엔드는 깔끔한 camelCase만 봐·tsx
// 맞는 TypeScript 모양 (rename_all 덕에 camelCase).
interface Note {
  id: number;
  title: string;
  createdAt: string;
}

const saved = await invoke<Note>("save_note", {
  draft: { id: 1, title: "Hi", createdAt: new Date().toISOString() },
});

External links

Exercise

여러 단어로 된 필드(created_at 같은)를 하나 이상 가진 struct를 정의하고, Serialize/Deserialize를 derive하고, #[serde(rename_all = "camelCase")]를 붙여. 그걸 돌려주는 command를 짜서 프론트엔드에서 invoke하고, 콘솔에서 필드가 camelCase로 도착하는지 확인해. 그다음 rename_all 줄을 빼고 이름이 어떻게 바뀌는지 봐 — serde의 이름 바꾸기를 눈으로 확인한 거야.
Hint
rename_all이 없으면 TS는 created_at을 받고, 있으면 createdAt을 받아. 맞는 TS 인터페이스는 camelCase로 써. 이게 두 언어를 둘 다 제 스타일대로 두는 제일 깔끔한 방법이야.

Progress

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

댓글 0

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

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