μ΄ λΈλ‘κ·Έλ λ€μ΄λ² λΈλ‘κ·Έλ ν°μ€ν 리 λ±μ μλΉμ€ μμ΄ μ΄μλκ³ μλ€. κΈμ 첨λΆλλ μ΄λ―Έμ§λ€μ μν λ³λμ ν΄λΌμ°λ μλΉμ€ λν μ¬μ©μ€μ΄μ§ μλ€. λΈλ‘κ·Έμμ 보μ¬μ§λ λͺ¨λ μ΄λ―Έμ§λ PostgreSQL DBμ μ μ₯λκ³ , μ΄λ―Έμ§ μ‘°ν μμ²μ΄ μ€λ©΄ μλ²κ° DBμ μ μ₯λ μ΄λ―Έμ§ μ΄μ§ μ 보λ₯Ό λΆλ¬μμ μ¬μ©μμκ² λ³΄μ¬μ£Όκ³ μλ€.
λκΈ°
μ²μ λΈλ‘κ·Έλ₯Ό μμ±ν λΉμμλ μ΄λ―Έμ§ μ λ‘λ κΈ°λ₯μ΄ μμλ€. μ΄ μ΄λ―Έμ§ μ λ‘λ κΈ°λ₯μ΄ μλ κ² λλ¬Έμ κΈμ μΈ λ μμ¬μ΄ μν©μ΄ λ§μμ‘κ³ , μ΄μ λ μ λ° κ΅¬νν΄λκΈ°λ‘ κ²°μ νλ€.
μ΄ λΈλ‘κ·Έμ κΈ°μ μ€νμ μλμ κ°λ€.
- Rust lang - νλ‘κ·Έλλ° μΈμ΄
- axum - Rust κΈ°λ° μΉ νλ μμν¬
- AWS Lambda - μ»΄ν¨ν μΈνλΌμ€νΈλμ³
- PostgreSQL - DB
- SvelteKit - Svelte κΈ°λ° μΉ νλ μμν¬
- Cloudflare Pages - λ¬΄λ£ μΉ νΈμ€ν μλΉμ€
- Supabase - BaaS & λ¬΄λ£ PostgreSQL νΈμ€ν μλΉμ€
λλ μ΄ κΈ°μ μ€νμ λ³ν¨ μμ΄ μ μ§νκ³ μΆμλ€. 무μΈκ° μλΉμ€λ₯Ό λνκΈ°λ μ«μλ€. μΌλ¨ μλν΄λ΄€λ€.
λ©μΈ μμ΄λμ΄: DBμ μ΄λ―Έμ§λ₯Ό μ μ₯νμ
DBλ λ°μ΄ν°λ₯Ό μ€λ«λμ μ μ₯νλ μν μ νλ€. μ€λ¬΄μμλ DBμ μμΉκ°μ΄λ μ΄λ©μΌ μ 보μ κ°μ μ«μ, ν μ€νΈ μ 보λ₯Ό μ μ₯νκ³€ νλ€.
λ³΄ν΅ μ΄λ―Έμ§ νμΌμ DBκ° μλ λ€λ₯Έ κ³³μ μ μ₯λλ€. μλ₯Ό λ€λ©΄ NASλ ν΄λΌμ°λ μ€ν 리μ§μ μ μ₯λκ³€ νλ€. κ΄λ¦¬μ μ©μ΄μ±κ³Ό λ°μ΄ν° μ±κ²©μ λ°λ₯Έ λΆλ¦¬ λλ¬Έμ΄λ€.
κ·Έλ°λ° λλ, μ«μλ ν μ€νΈλ μ΄λ―Έμ§λ κ²°κ΅ 0κ³Ό 1λ‘ μ΄λ£¨μ΄μ§ μ΄μ§ λ°μ΄ν°λΌκ³ μκ°νλ€. κ·Έλμ κ·Έλ₯ DBμ μ λΆ λ³΄κ΄ν΄λ³΄κΈ°λ‘ νλ€.
κΈ°μ μ μΌλ‘ μ΄ν΄λ³΄λ, μ§κΈ μ¬μ©μ€μΈ DBμΈ PostgreSQLμμ μ΄μ§ μ 보 μ μ₯μ μ§μνλ€λ μ¬μ€μ νμΈνλ€. μ΄κ² λλ€λ©΄ μ΄λ―Έμ§ μ μ₯μ΄λ λ λμκ°μ μΌλ° νμΌ μ μ₯λ κ°λ₯ν΄μ§λ€.
ν μ΄λΈ μ€κ³
νμΌμ μ μ₯νκΈ° μν ν μ΄λΈμ λ€μκ³Ό κ°μ΄ μ€κ³νλ€.
CREATE TABLE public.post_attachment ( id UUID NOT NULL, content BYTEA NOT NULL, written_by_id INTEGER NOT NULL, file_extension VARCHAR(20) NOT NULL DEFAULT '', mimetype VARCHAR(255) NOT NULL, PRIMARY KEY (id) );
- id: μΈν°λ·μμ νμΌμ μ κ·ΌνκΈ° μν URL. UUID νμμ΄λ©°, URLμ λ€μκ³Ό κ°μ΄ ν λΉλλ€.
https://blog.atj.sh/post-attachments/v/0194e521-339c-7e10-b205-a2a9416fdb97
- content: νμΌμ μ΄μ§ μ 보.
- written_by_id: νμΌμ μ λ‘λν μ¬λμ ID.
- file_extension: νμΌμ νμ₯μ. νμΌμ΄ μ λ‘λλ λ νμΌμ μ΄λ¦μμ κ°μ Έμ DBμ μ μ₯νλ€. νμΌμ μλ μ΄λ¦μ μ μ₯λμ§ μκ³ λμ νμ₯μλ§ μ μ₯λλ€.
- mimetype: νμΌμ mimetype. νμΌμ΄ μ
λ‘λλ λ
Blob.type()
λ©μλλ₯Ό ν΅ν΄ κ°μ Έμμ Έμ DBμ μ μ₯λλ€.
μ λ‘λ μλ리μ€
λ΄κ° κΈμ μ°λ©° μ΄λ―Έμ§λ₯Ό 첨λΆν λ μλ²μμ μ΄λ£¨μ΄μ§λ μμ μ΄λ€.
μ΄λ―Έμ§ μμΆμ κ²½μ°μλ μλ CloudFlare Pages μλ²λ¨μμ μ²λ¦¬λλλ‘ νλ €κ³ νλλ°, μ΄λ―Έμ§ μμΆμ ν΅μ¬μ μΌλ‘ νμν Canvas APIκ° μ§μλμ§ μμμ κ΄λκ³ , AWS Lambdaμμ μ²λ¦¬νκΈ°μλ νμ© μμ² ν¬κΈ°κ° 6MB μμ€μ΄λΌμ μμ²μ΄ κ±°λΆλλ μν©μ΄ λ°μν κ²μΌλ‘ μμνλ€.
λ°λΌμ λ€νΈμν¬ μμ²μ νκΈ° μ μ λΈλΌμ°μ μμμ μ΄λ―Έμ§ μμΆμ 미리 μ§ννλλ‘ κ΅¬ννλ€. κ²°λ‘ μ μΌλ‘λ λ€νΈμν¬ νΈλν½μ΄ μ μ½λκ³ DBμ μ μ₯λλ λ°μ΄ν°μ ν¬κΈ° λν μμμ‘λ€.
μμΆ μκ³ λ¦¬μ¦μ WebPλ‘ μμΆνλ λ°©λ²μ μ¬μ©νλλ°, 12MB μ΄λ―Έμ§λ₯Ό 100KB μ λμ ν¬κΈ°λ‘ μμΆν μ λλ‘ ν¨μ¨μ΄ μ’μλ€.
μ‘°ν μλ리μ€
λ°©λ¬Έμκ° μ΄λ―Έμ§λ₯Ό λ³Ό λ μλ²μμ μ΄λ£¨μ΄μ§λ μμ μ΄λ€.
CloudFlare Pagesμμ μ체μ μΌλ‘ μ§μλλ Cache APIλ₯Ό μ μ©νλ€. λλΆμ DB μ‘°νλ‘ μΈν λΆνκ° μ‘°κΈμ΄λλ§ μ€μ΄λ€μλ€. λν λΈλΌμ°μ μμ μμμ μΊμ±ν μ μλλ‘ Cache-Control ν€λλ₯Ό μ μ©νλ€.
μ΄λ―Έμ§ νμΌμ μ 곡ν λ λΈλΌμ°μ μμ μμ°μ€λ½κ² μ 곡λ μ μλλ‘, μ΄λ―Έμ§μ νμμ HTTP μλ΅ ν€λμ μ ννκ² κΈ°μ
νλ μμ
μ΄ νμνλ€. μ΄λ―Έμ§κ° μλ²μμ μ‘°νλ λ μ΄λ―Έμ§μ λ©νλ°μ΄ν°κ° HTTP μλ΅ ν€λμ μ λ΄κ²¨μ μ λ¬λλλ‘ κ΅¬ννμλ€.
κ°μΈμ μΌλ‘λ μ΄ μμ
μ νλ©΄μ HTTP Mimetypeκ³Ό μ΄λ―Έμ§ νμ₯μμ μ°¨μ΄λ₯Ό μ’ λ λͺ
ννκ² μ μ μμλ€.
κ²°λ‘ : ꡬνμ μ±κ³΅νμ§λ§ κ°μ μ μ¬μ§λ μμ
μ΄ κΈμμ μ¬μ©λ μ΄λ―Έμ§λ€μ λͺ¨λ μ λ‘μ§μ ν΅ν΄ DBλ‘λΆν° μ‘°νλμ΄ λΈλΌμ°μ μ λ λλ§λ κ²μ΄λ€. μ΄λ―Έμ§λ€μ΄ μ 보μΈλ€λ©΄ ꡬνμ΄ μμ μ μΌλ‘ μλ£λμλ€λ λ»μΌ κ²μ΄λ€. λ§μ½ μ΄λ―Έμ§κ° μ 보μΈλ€λ©΄, μ€κ°μμ λ―Έμ² λ°κ²¬ λͺ»ν λ²κ·Έκ° μμ΄ λΈλΌμ°μ κΉμ§ μ΄λ―Έμ§κ° λλ¬νμ§ λͺ»ν κ²μΌλ‘ 보면 λλ€.
HTTP μΊμ±μ μ μ©νκΈ΄ νμ§λ§ μλ²½ν νμ νμ§ λͺ»ν΄μ μΌλΆλΆλ§ ꡬννλ€. κΈ°νκ° λλ©΄ λ μμ νκ² κ΅¬ννκ³ μΆλ€.
1MB ν¬κΈ°λ³΄λ€ μμ μ΄λ―Έμ§ μ 곡μ μ±κ³΅νμ§λ§, κ·Έλ³΄λ€ ν° μ΄λ―Έμ§λ λμ©λ νμΌ μ 곡μ μμμ μ€λͺ ν λ°μ κ°μ΄ μ¬λ¬ μ ν λλ¬Έμ νλ€λ€. μ¬μ§μ΄ 10MB μ λμ νμΌ μ 곡λ μ§κΈμ λΆκ°λ₯ν μν©μ΄λ€. μ΄λ―Έμ§μ κ²½μ°μλ WebP μμΆμ΄ μλ ν¨μ¨μ μ΄λΌ λΆνΈν μ μ΄ μλ μν©μ΄μ§λ§, λ€λ₯Έ νμΌμ κ²½μ°μλ μ©λ μ νμ΄ ν¬κ² λ€κ°μ¬ μ λ°μ μλ€.
κΈ°μ μ€νμ μ μ§νλ λμμ λ ν° νμΌμ μλΉνκΈ° μν λ°©λ²μ μ°κ΅¬ν΄λ΄μΌκ² λ€.
μμ€μ½λ
μ΄ λΈλ‘κ·Έμ μμ€μ½λλ μ€νμμ€μ΄λ€. λ΄ GitHubμμ νμΈ κ°λ₯νλ€.
μ΄λ² κΈ°λ₯μ΄ μΆκ°λ μ»€λ° λ΄μμ λ€μ λ§ν¬μμ νμΈ κ°λ₯νλ€. atjsh/rust-blog - 89958c...ad708e
κ΅μ₯ν λ§μ‘±
κ±°μ 2λ¬κ° 미룬 μμ μΈλ° ν루λ§μ ꡬνμ λλλ€. λλμ΄ λλ΄μ μμ΄ νλ ¨νλ€.