μ ν΅μ μΈ μλ²μ¬μ΄λ λ λλ§(SSR) λ°©μμΌλ‘ μΉ μ ν리μΌμ΄μ μ ꡬμΆνκ±°λ, λ€λ₯Έ λ§λ‘ νμ΄νΌλ―Έλμ΄ κΈ°λ° μ ν리μΌμ΄μ (HDA)μ ꡬμΆνλ κ²μ Reactμ κ°μ μ±κΈ νμ΄μ§ μ ν리μΌμ΄μ (SPA) νλ μμν¬λ₯Ό μ¬μ©νμ¬ μΉ μ ν리μΌμ΄μ μ κ°λ°νλ κ²κ³Ό λΉκ΅νμ λ μ¬κ³ λ°©μμ μ νμ΄ νμν©λλ€.
SPA κ°λ° λ°©μμ μ΅μν μνλ‘ μ΄ κ°λ° μ€νμΌμ μ κ·Όνλ©΄, μ΄ νΉμ μν€ν μ² μ νμ λ§μ μ₯μ μ λμΉκ³ μ’μ νκ² λ κ°λ₯μ±μ΄ ν½λλ€.
μ΄λ¬ν μ κ·Ό λ°©μμ κ°μ μ μ΅λν νμ©νκ³ μ½μ μ μ΅μνν μ μλλ‘ μ¬κ³ λ°©μμ μννκ² μ ννλ λ° λμμ΄ λλ 10κ°μ§ νμ μκ°ν©λλ€:
νμ΄νΌλ―Έλμ΄ κΈ°λ° μ κ·Ό λ°©μμ ν° μ₯μ μ μΉ μ ν리μΌμ΄μ μ ꡬμΆν λ μλ²μ¬μ΄λ νκ²½μ΄ ν¨μ¬ λ μ€μν΄μ§λ€λ κ²μ λλ€. JSONλ§ μμ±νλ κ²μ΄ μλλΌ, λ°±μλλ μΉ μ ν리μΌμ΄μ μ μ¬μ©μ κ²½νμμ μ€μν κ΅¬μ± μμκ° λ©λλ€.
μ΄ λλ¬Έμ μλ²μ¬μ΄λμμ μ 곡νλ κΈ°λ₯μ κΉμ΄ νꡬνλ κ²μ΄ μ€μν©λλ€. λ§μ μ€λλ μΉ νλ μμν¬λ HTMLμ μμ±νλ λ° μμ΄ λ§€μ° κΉμ κΈ°λ₯μ μ 곡ν©λλ€. μλ₯Ό λ€μ΄, μλ²μ¬μ΄λ μΊμ±κ³Ό κ°μ κΈ°λ₯μ λΉ λ₯΄κ³ λ°μμ΄ μ’μ μΉ μ ν리μΌμ΄μ κ³Ό λλ¦° μ¬μ©μ κ²½νμ μ°¨μ΄λ₯Ό λ§λ€ μ μμ΅λλ€.
μ¬μ© κ°λ₯ν λͺ¨λ λꡬλ₯Ό λ°°μ°λ λ° μκ°μ ν¬μνμμμ€.
μΌλ°μ μΈ κ·μΉμ μ ν리μΌμ΄μ μ μλ΅ μκ°μ΄ 100ms μ΄νκ° λλλ‘ νλ κ²μ΄λ©°, μ±μν μλ²μ¬μ΄λ νλ μμν¬λ μ΄λ₯Ό λ¬μ±νλ λ° λμμ΄ λλ λꡬλ₯Ό μ 곡ν©λλ€.
μλ²μ¬μ΄λ νκ²½μ μ½λλ₯Ό μ μ ν ꡬμ±νλ λ§€μ° μ±μν λ©μ»€λμ¦μ μ 곡ν©λλ€. λλΆλΆμ νκ²½μμλ λͺ¨λΈ/λ·°/컨νΈλ‘€λ¬(MVC) ν¨ν΄μ΄ μ κ°λ°λμ΄ μμΌλ©°, λͺ¨λ, ν¨ν€μ§ λ±μ λꡬλ μ½λλ₯Ό μ‘°μ§ννλ λ° νμν λ°©λ²μ μ 곡ν©λλ€.
SPAμ μ¬μ©μ μΈν°νμ΄μ€κ° μΌλ°μ μΌλ‘ μ»΄ν¬λνΈ λ₯Ό ν΅ν΄ ꡬμ±λλ λ°λ©΄, νμ΄νΌλ―Έλμ΄ κΈ°λ° μ ν리μΌμ΄μ μ μΌλ°μ μΌλ‘ ν νλ¦Ώ ν¬ν¨ μ ν΅ν΄ ꡬμ±λ©λλ€. μλ²μ¬μ΄λ ν νλ¦Ώμ μ ν리μΌμ΄μ μ HTML λ λλ§ μꡬμ λ°λΌ λΆλ¦¬λμ΄ νμμ λ°λΌ μλ‘ ν¬ν¨λ©λλ€. μ΄λ μ»΄ν¬λνΈ κΈ°λ° μ ν리μΌμ΄μ μμ μ°Ύμ μ μλ κ²λ³΄λ€ λ μ κ³ λ λ©μ΄λ¦¬μ§ νμΌλ‘ μ΄μ΄μ§λ κ²½ν₯μ΄ μμ΅λλ€.
λ λ€λ₯Έ μ μ©ν κΈ°μ λ‘λ ν νλ¦Ώ νλκ·Έλ¨ΌνΈλ₯Ό λ€ μ μμ΅λλ€. μ΄λ₯Ό ν΅ν΄ ν νλ¦Ώ νμΌμ μΌλΆλ§ λ λλ§ν μ μμΌλ©°, μ΄λ μλ²μ¬μ΄λ μ ν리μΌμ΄μ μ νμν ν νλ¦Ώ νμΌμ μλ₯Ό λμ± μ€μ¬μ€λλ€.
JSON APIμ λ¬λ¦¬, νμ΄νΌλ―Έλμ΄ κΈ°λ° μ ν리μΌμ΄μ μ μν΄ μμ±ν νμ΄νΌλ―Έλμ΄ APIλ μ ν리μΌμ΄μ μ UI μꡬ μ¬νμ νΉνλ μλν¬μΈνΈλ₯Ό ν¬ν¨ν΄μΌ ν©λλ€.
νμ΄νΌλ―Έλμ΄ APIλ μΌλ° λͺ©μ μ ν΄λΌμ΄μΈνΈκ° μλΉνλλ‘ μ€κ³λμ§ μμκΈ° λλ¬Έμ, μ΄λ₯Ό μΌλ°ννλ €λ μλ°μ λ΄λ €λκ³ μ ν리μΌμ΄μ μ νμν μ½ν μΈ λ₯Ό ꡬ체μ μΌλ‘ μμ±ν μ μμ΅λλ€. μλν¬μΈνΈλ λλ©μΈ λͺ¨λΈμ λν μΌλ°μ μΈ λ°μ΄ν° μ κ·Ό λͺ¨λΈμ μν κ²μ΄ μλλΌ, μ ν리μΌμ΄μ μ UI/UX μꡬ μ¬νμ μ§μνλλ‘ μ΅μ νλμ΄μΌ ν©λλ€.
κ΄λ ¨λ νμΌλ‘, νμ΄νΌλ―Έλμ΄ κΈ°λ° APIλ₯Ό μ¬μ©νλ κ²½μ°, JSON API κΈ°λ° SPAλ₯Ό μμ±ν λ κ°λ ₯ν κΆμ₯λμ§ μλ λ°©μμΌλ‘ APIλ₯Ό μ κ·Ήμ μΌλ‘ 리ν©ν λ§ν μ μμ΅λλ€. νμ΄νΌλ―Έλμ΄ κΈ°λ° μ ν리μΌμ΄μ μ μ ν리μΌμ΄μ μνμ μμ§μΌλ‘μμ νμ΄νΌλ―Έλμ΄(HATEOAS)λ₯Ό μ¬μ©νκΈ° λλ¬Έμ, μ ν리μΌμ΄μ μ΄ κ°λ°λκ³ μ¬μ© μ¬λ‘κ° λ³κ²½λ¨μ λ°λΌ APIμ λͺ¨μμ λ³κ²½νλ κ²μ΄ κ°λ₯νλ©°, μ€μ λ‘ κΆμ₯λ©λλ€.
νμ΄νΌλ―Έλμ΄ μ κ·Ό λ°©μμ ν° μ₯μ μ APIλ₯Ό λ²μ κ΄λ¦¬νκ±°λ λ¬Έμνν νμ μμ΄ μκ°μ΄ μ§λ¨μ λ°λΌ μλ‘μ΄ μꡬ μ¬νμ λ§κ² μμ ν μ¬κ΅¬μ±ν μ μλ€λ κ²μ λλ€.
SPA μ κ·Ό λ°©μμ μ¬μ©νμ¬ μ ν리μΌμ΄μ μ ꡬμΆν λ, λ°μ΄ν° μ€ν μ΄λ μΌλ°μ μΌλ‘ JSON API λ€μ μμΉν©λλ€. μ΄λ¬ν κ°μ μ μΈ μ κ·Ό λ°©μμ νλ‘ νΈμλ κ°λ°μκ° λ°μ΄ν° μ€ν μ΄μμ μ¬μ©ν μ μλ λꡬλ₯Ό μ΅λν νμ©νλ κ²μ λ°©ν΄νλ κ²½μ°κ° λ§μ΅λλ€. GraphQLμ μ΄ λ¬Έμ λ₯Ό ν΄κ²°νλ λ° λμμ΄ λ μ μμ§λ§, λ§μ κ°λ°μκ° μ μ΄ν΄νμ§ λͺ»νλ 보μ κ΄λ ¨ λ¬Έμ κ° λ°μν μ μμ΅λλ€.
λ°λ©΄, μλ²μ¬μ΄λμμ HTMLμ μμ±ν λ, κ·Έ HTMLμ μμ±νλ κ°λ°μλ λ°μ΄ν° μ€ν μ΄μ λν μμ ν μ κ·Ό κΆνμ κ°μ§λ©°, μλ₯Ό λ€μ΄ SQL μ€ν μ΄μμ μ‘°μΈ λ° μ§κ³ ν¨μμ κ°μ κΈ°λ₯μ νμ©ν μ μμ΅λλ€.
μ΄λ HTMLμ μμ±νλ κ°λ°μμκ² ν¨μ¬ λ λ§μ ννλ ₯μ μ 곡ν©λλ€. νμ΄νΌλ―Έλμ΄ APIλ₯Ό UI μꡬ μ¬νμ λ§κ² ꡬ쑰νν μ μκΈ° λλ¬Έμ κ° μλν¬μΈνΈλ₯Ό μ‘°μ νμ¬ λ°μ΄ν° μ€ν μ΄ μμ²μ κ°λ₯ν ν μ κ² ν μ μμ΅λλ€.
μΌλ°μ μΈ κ·μΉμΌλ‘λ λͺ¨λ μμ²μ΄ μΈ λ² μ΄νμ λ°μ΄ν° μ€ν μ΄ μ κ·Όμ λͺ©νλ‘ ν΄μΌ νλ€λ κ²μ λλ€.
λͺ¨λ¬ μ°½μ μ€λλ λ§μ μΉ μ ν리μΌμ΄μ μμ κ±°μ νμ€μ²λΌ μΈκΈ°λ₯Ό λκ³ μμ΅λλ€.
λΆννλ, λͺ¨λ¬ μ°½μ μΉμ λ§μ μΈνλΌμ μ μ΄μΈλ¦¬μ§ μμΌλ©°, ν΄λΌμ΄μΈνΈ μΈ‘ μνλ₯Ό λμ νμ¬ νμ΄νΌλ―Έλμ΄ κΈ°λ° μ κ·Ό λ°©μκ³Ό κΉ¨λνκ² ν΅ν©νκΈ° μ΄λ €μΈ μ μμ΅λλ€(λΆκ°λ₯νμ§λ μμ§λ§).
λͺ¨λ¬ λμ μΈλΌμΈ νΈμ§κ³Ό κ°μ λμμ κ³ λ €ν΄λ³΄μΈμ.
HDA μ κ·Ό λ°©μμ μ²μ μ νλ λ§μ SPA κ°λ°μλ€μ΄ νμ¬μ SPA μ ν리μΌμ΄μ μ μ ννκ² νμ΄νΌλ―Έλμ΄λ₯Ό μ¬μ©νμ¬ κ΅¬ννλ κ²μ μμν©λλ€. htmx λ° κΈ°ν νμ΄νΌλ―Έλμ΄ μ§ν₯ λΌμ΄λΈλ¬λ¦¬λ νμ΄νΌλ―Έλμ΄ κΈ°λ° μ ν리μΌμ΄μ κ³Ό SPA κ°μ μνΈμμ© κ²©μ°¨λ₯Ό μλΉν μ€μ΄μ§λ§, κ·Έ 격차λ μ¬μ ν μ‘΄μ¬ν©λλ€.
μΉμ REST-ful λ€νΈμν¬ μν€ν μ²μ κ΄λ ¨νμ¬ Roy Fieldingμ΄ λ§νλ―μ΄,
κ·Έλ¬λ κ· μΌν μΈν°νμ΄μ€λ μ 보λ₯Ό μ ν리μΌμ΄μ μ νμμ λ§κ² ꡬ체νλ ννκ° μλ νμ€νλ ννλ‘ μ μ‘νκΈ° λλ¬Έμ ν¨μ¨μ±μ΄ μ νλλ€.
νΉμ UXμ λν΄ μ½κ° λ ν¨μ¨μ μ΄κ³ λ μνΈμμ©μ μΈ μ루μ μ λ°μλ€μ΄λ κ²μ μΉ μ ν리μΌμ΄μ μ ꡬμΆν λ 볡μ‘μ±μ ν¬κ² μ€μΌ μ μμ΅λλ€.
μλ²½μ΄ μ μ μ μ΄ λμ§ μλλ‘ νμΈμ.
μΉ μ ν리μΌμ΄μ μ κ°λ°νλ€ λ³΄λ©΄ νμ΄νΌλ―Έλμ΄ μ κ·Ό λ°©μλ§μΌλ‘λ λΆμ‘±ν μν©μ΄ λ°μν μ μμ΅λλ€.
κ·Έλ¬ν μν©μ μ’μ μλ‘, νλͺ©μ λͺ©λ‘μ μ¬μ λ ¬νλ κΈ°λ₯μ λ€ μ μμ΅λλ€. μ΄λ₯Ό βμμβ νμ΄νΌλ―Έλμ΄ λ°©μμΌλ‘ ꡬννλ €λ©΄ μμλ νμ΄νλ₯Ό ν΄λ¦νκ±°λ νλͺ© μμ μμ λ²νΈ λλ‘λ€μ΄μ λ°°μΉν μ μμ΅λλ€. (λΆλλ½κ²λ μ λ μ΄ λ κ°μ§λ₯Ό λ€ λ§λ€μ΄ λ³Έ μ μ΄ μμ΅λλ€!)
νμ§λ§ μ΄λ¬ν κ²½νμ μ¬λλ€μ΄ κΈ°λνλ κ²μ λΉν΄ λ§€μ° λΆνΈν©λλ€. μ¬λλ€μ΄ κΈ°λνλ κ²μ λλκ·Έ μ€ λλ‘μ λλ€.
μ΄λ¬ν κ²½μ°, βμνΈμμ© μ¬(Island of Interactivity)βμΌλ‘ νλ°νΈμλ μ€μ¬μ μ κ·Ό λ°©μμ μ¬μ©νλ κ²μ μ ν λ¬Έμ λμ§ μμ΅λλ€.
SortableJS μμ μ κ³ λ €ν΄λ³΄μΈμ. μ¬κΈ°μμλ λλκ·Έ μ€ λλ‘μ νμ©νλ 볡μ‘ν μνΈμμ© μμμ΄ μμΌλ©°, μ΄λ μ΄λ²€νΈλ₯Ό ν΅ν΄ htmx λ° λ λμ νμ΄νΌλ―Έλμ΄ κΈ°λ° μ ν리μΌμ΄μ κ³Ό ν΅ν©λ©λλ€.
μ΄κ²μ HDA λ΄μμ λ νλΆν UXλ₯Ό μΊ‘μννλ νλ₯ν λ°©λ²μ λλ€.
μ€ν¬λ¦½ν μ μΉ μν€ν μ²μ λͺ μμ μΈ μΌλΆμ΄λ©°, νμ΄νΌλ―Έλμ΄ μ κ·Ό λ°©μμ μ±νν κ°λ°μλ€μ μ΄λ₯Ό μ¬μ©νλ κ²μ λλ €μν΄μλ μ λ©λλ€. λ¬Όλ‘ μ€ν¬λ¦½ν μλ μ¬λ¬ κ°μ§ λ°©μμ΄ μμ΅λλ€.
κ°λ₯ν ν, νμ΄νΌλ―Έλμ΄ μΉνμ μΈ μ€ν¬λ¦½ν λ°©μμ μ¬μ©νμ¬ νμ΄νΌλ―Έλμ΄ κ΅νμ μλ²μ μμ€ν μν λ³κ²½μ μν μ£Όμ ν΅μ λ©μ»€λμ¦μΌλ‘ μ μ§ν΄μΌ ν©λλ€.
alpine.jsμ hyperscriptμ κ°μ λꡬλ₯Ό μ¬μ©νμ¬ μΈλΌμΈ μ€νμΌ μ€ν¬λ¦½ν μ νμν΄λ³΄λ κ²λ μ’μ΅λλ€. μ΄λ¬ν μ κ·Ό λ°©μμ μ€ν¬λ¦½ν μ νμ΄νΌλ―Έλμ΄(HTML) μ체μ μ§μ€μν€λ©°, μμ±ν μ μλ μ½λμ μμ λ―Ένμ μΈ μ νμ λΆκ³Όν©λλ€.
λ§μ§λ§μΌλ‘, νμ΄νΌλ―Έλμ΄ μ¬μ©μ λν΄ κ΅μ‘°μ μ΄μ§ μλλ‘ νμΈμ. κ²°κ΅, νμ΄νΌλ―Έλμ΄λ κ³ μ ν κ°μ κ³Ό μ½μ μ κ°μ§ λ λ€λ₯Έ κΈ°μ μΌ λΏμ λλ€. νΉμ μ±μ μΌλΆλ μ 체 μ±μ΄ νμ΄νΌλ―Έλμ΄κ° μ 곡ν μ μλ κ²λ³΄λ€ λ μνΈμμ©μ μΈ κΈ°λ₯μ μꡬνλ€λ©΄, κ·Έμ μ ν©ν κΈ°μ μ μ ννμΈμ.
λ¨, νμ΄νΌλ―Έλμ΄κ° ν μ μλ κ²μ μ μ΄ν΄νκ³ μμ΄μΌ, informed developerλ‘μ κ·Έ κ²°μ μ λ΄λ¦΄ μ μμ΅λλ€.
μ΄ νλ€μ΄ νμ΄νΌλ―Έλμ΄μ μλ²μ¬μ΄λ λ λλ§μ λ³΄λ€ ν¨κ³Όμ μ΄κ³ μννκ² λκ΅¬λ‘ νμ©νλ λ° λμμ΄ λκΈ°λ₯Ό λ°λλλ€. νμ΄νΌλ―Έλμ΄λ μλ²½ν ν΄λΌμ΄μΈνΈ-μλ² μν€ν μ²λ μλλ©°, λͺ νν νΈλ μ΄λμ€νκ° μ‘΄μ¬νμ§λ§, λ§μ μΉ μ ν리μΌμ΄μ (μ€λλ λλΆλΆμ μΉ κ°λ°μλ€μ΄ μμνλ κ²λ³΄λ€ ν¨μ¬ λ λ§μ κ²½μ°)μ λ§€μ° ν¨κ³Όμ μΌ μ μμΌλ©°, κ·Έ κ²½μ° ν¨μ¬ κ°λ¨ν μ 체 κ°λ° κ²½νμ μ 곡ν©λλ€.