ํ”ผ๋“œ๋กœ ๋Œ์•„๊ฐ€๊ธฐ
Don't Let Bad Networks Kill Your App: Building Offline-First in Flutter & Laravel ๐Ÿ“ฑ
Dev.toDev.to
Frontend

Local-First DB์™€ UUID ๊ธฐ๋ฐ˜ ๋™๊ธฐํ™”๋กœ ๋„คํŠธ์›Œํฌ ์ œ์•ฝ ํ•ด๊ฒฐ

Don't Let Bad Networks Kill Your App: Building Offline-First in Flutter & Laravel ๐Ÿ“ฑ

Prajapati Paresh2026๋…„ 4์›” 13์ผ3๋ถ„intermediate

Context

๋ถˆ์•ˆ์ •ํ•œ ๋„คํŠธ์›Œํฌ ํ™˜๊ฒฝ์˜ AgriTech ํ•„๋“œ ์‚ฌ์šฉ์ž๋ฅผ ์œ„ํ•œ ์„œ๋น„์Šค ์ œ๊ณต ํ•„์š”์„ฑ ๋Œ€๋‘. ๊ธฐ์กด HTTP ์š”์ฒญ ๊ธฐ๋ฐ˜ ์•„ํ‚คํ…์ฒ˜์˜ ๋„คํŠธ์›Œํฌ ์˜์กด์„ฑ์œผ๋กœ ์ธํ•œ ์•ฑ ํ”„๋ฆฌ์ง• ๋ฐ ๋ฐ์ดํ„ฐ ์†์‹ค ๊ฐ€๋Šฅ์„ฑ ํ•ด๊ฒฐ ํ•„์š”.

Technical Solution

  • sqflite ๋„์ž…์„ ํ†ตํ•œ Local Database ์ค‘์‹ฌ์˜ Source of Truth ์„ค๊ณ„๋กœ ๋„คํŠธ์›Œํฌ ์ƒํƒœ์™€ ๋ฌด๊ด€ํ•œ ์ฆ‰๊ฐ์ ์ธ UI ์‘๋‹ต์„ฑ ํ™•๋ณด
  • sync_status ํ”Œ๋ž˜๊ทธ๋ฅผ ํ™œ์šฉํ•œ ๋ฐ์ดํ„ฐ ์ƒํƒœ ๊ด€๋ฆฌ ๋ฐ Background Worker ๊ธฐ๋ฐ˜์˜ ๋ฐฐ์น˜ ๋™๊ธฐํ™” ๋ฉ”์ปค๋‹ˆ์ฆ˜ ๊ตฌ์ถ•
  • ID ์ถฉ๋Œ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•œ Client-side UUID ์ƒ์„ฑ ์ „๋žต ์ฑ„ํƒ์œผ๋กœ Server-side Auto-increment ์˜์กด์„ฑ ์ œ๊ฑฐ
  • Last Write Wins ์ „๋žต๊ณผ updated_at ํƒ€์ž„์Šคํƒฌํ”„๋ฅผ ๊ฒฐํ•ฉํ•œ Laravel ๋ฐฑ์—”๋“œ ์ถฉ๋Œ ํ•ด๊ฒฐ ๋กœ์ง ๊ตฌํ˜„
  • DB::transaction์„ ํ†ตํ•œ ๋ฐฐ์น˜ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ๋กœ ์›์ž์„ฑ ๋ณด์žฅ ๋ฐ API ํ˜ธ์ถœ ํšŸ์ˆ˜ ์ตœ์ ํ™”

- Client-side์—์„œ UUID๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์„œ๋ฒ„ ๋™๊ธฐํ™” ์‹œ Key ์ถฉ๋Œ ๊ฐ€๋Šฅ์„ฑ ์ฐจ๋‹จ - Local DB์— sync_status ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋™๊ธฐํ™” ๋Œ€์ƒ ๋ ˆ์ฝ”๋“œ๋ฅผ ๋ช…ํ™•ํžˆ ๊ตฌ๋ถ„ - ๋‹จ์ˆœ API ํ˜ธ์ถœ ๊ตฌ์กฐ์—์„œ Local-first Write ํ›„ Background Sync ๊ตฌ์กฐ๋กœ์˜ ์ „ํ™˜ ๊ฒ€ํ†  - ๋ฐ์ดํ„ฐ ์ถฉ๋Œ ํ•ด๊ฒฐ์„ ์œ„ํ•œ Last Write Wins ๋˜๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ๋งž์ถคํ˜• ๋จธ์ง€ ์ „๋žต ์ˆ˜๋ฆฝ

์›๋ฌธ ์ฝ๊ธฐ