Elm loyihalarida men kuzatgan umumiy tendentsiya shundaki, Elm sizni oddiy echimlarga yo'naltiradi. Men buni Elmga yangi bo'lgan odamlar uchun ham to'g'ri deb topdim. Men yangi loyiha uchun Elmni qabul qilish orqali korporativ muhitda jamoaga murabbiylik qilardim. Ular AngularJS bilan oldingi loyihani qurgan va u bilan haqiqatan ham kurashgan. To'g'rirog'i, ular bu bilan kurashmagan. Ramka ular o'ylab topgan har qanday yechimni qabul qiladi. Ular Elm bilan ishlashni boshlaganlarida, "modelimdagi kirish maydonidan ma'lumotlarni qanday saqlashim" ni aniqlash uchun ularga biroz ko'proq vaqt kerak bo'lishi mumkin edi. Ammo Elm ularga vaqtinchalik xakerlardan foydalanishga ruxsat bermaganligi sababli, ularning yondashuvi butunlay boshqacha edi. Global o'zgaruvchidan foydalanadigan yoki DOMni o'zgartiradigan StackOverflow kodini nusxa ko'chirish o'rniga, "hozircha ishlashi uchun" Elm ularni hech qanday buzg'unchilikka tayanmasdan yechim topishga majbur qildi. Natijada, bir necha oy o'tgach, ular o'zgartirish qo'rqinchli bo'lgan beqaror kod bazasiga qarshi kurashish o'rniga, ular juda ishonchli kod bilan ishladilar. Ular osongina va qo'rqmasdan o'zgarishlar qilishlari mumkin edi. Farqi kechayu kunduz edi.

Men yaqinda xuddi shunday tajribaga ega bo'ldim, bu Elm sizni qanday qilib soddalikka yo'naltirishini ko'rsatadi. Men turdagi xavfsiz GraphQL so'rovlari uchun Elm paketining muallifiman, dillonkearns/elm-graphql (batafsil ma'lumot olish uchun “mening yaqinda bo'lib o'tgan Elm Conf suhbatim”ga qarang). Men bir nechta turli foydalanuvchilardan bir xil xususiyat so'rovini olishni boshladim. Bu o'rinli so'rov edi, lekin u kelganda men texnik muammolarni va uni qo'llab-quvvatlash uchun qayta loyihalash qanchalik muhimligini tushuntirib berardim.

Qiyinchilik: noyob kalitlar

GraphQL so'rovlari JSON javoblarini oladi, javoblar so'rov bilan bir xil "shaklga" ega. Shunday qilib, bu so'rov:

{
  currentUser {
    avatar
  }
}

JSONni shunday qaytaradi:

{
  "currentUser": {
    "avatar": "https://avatar.com/user.jpg"
  }
}

Yagona ogohlantirish shundaki, agar siz bir xil nomdagi bir nechta maydonlarni turli argumentlarga ega bo'lishni so'rasangiz, GraphQL-ga ushbu ma'lumotlarni qaysi kalitga qaytarish kerakligini aniq aytish uchun maydon taxalluslarini berishingiz kerak.

{
  currentUser {
    avatar(size: 12)
    avatar(size: 48)
  }
}
# ERROR - Field 'avatar' has an argument conflict: is size 12 or 48?

Yuqoridagi so‘rov noaniq bo‘lgani uchun xatolikka olib keladi.

dillonkearns/elm-graphql GraphQL soʻrovlarini yaratish va seriyadan chiqarishning past darajadagi tafsilotlarini koʻrib chiqadi, shunda 1) siz murakkab kutubxona oʻrniga yuqori darajadagi Elm tili xususiyatlaridan foydalanishingiz mumkin va 2) siz yaratgan har qanday soʻrov haqiqiyligini kafolatlaydi. Shunday qilib, kutubxonaga bu kabi noaniq va noto'g'ri so'rovlarni yaratmaslik uchun yo'l kerak.

Asl yechim

Zarur bo'lganda maydonlarga taxallus berilishini ta'minlash uchun oldingi algoritmim hisoblagichni oshirish va har bir maydon taxallus uchun bu raqamdan foydalanish edi.

Ushbu yondashuvdan foydalanib, mening kutubxonam quyidagi kabi so'rovni yaratadi:

{
  currentUser {
    avatar(size: 12)
    avatar2: avatar(size: 48)  # this alias tells GraphQL to return this data under the key "avatar2"
  }
}

Bu juda yaxshi ishladi. Ammo siz yuqoridagi kabi kichik va o'rta avatarlarni ushlagan holda Tanlash to'plamini yaratganingizda, u o'sha paytda bilgan narsasi asosida mos keladigan "Json Dekoder" ni yaratishi kerak edi (Json Dekoderlari Elm qanday qilib JSONni Elm ma'lumotlariga terilgan holda seriyadan chiqaradi) . Shunday qilib, men ikkita Tanlov to'plamini birlashtirish uchun APIni ochib bera olmadim, chunki u avatar2 taxallusidan ma'lumotlarni olish uchun dekoderni yaratgan bo'lar edi. Ammo agar biz o'rta va to'liq o'lchamli avatarni o'z ichiga olgan boshqa maydonlar to'plamiga birlashtirsak, ularning Json dekoderlari avatar3 va avatar4 ostida qidirish kerak bo'lganda, avatar va avatar2 deb nomlangan maydondan ma'lumotlarni olishga harakat qiladi. Men so'nggi daqiqada deserializers (Json Decoders) ni yaratish uchun kodni qayta loyihalash orqali bu muammoni hal qila olaman, ammo bu men buni kechiktirishim uchun maxsus ma'lumotlar strukturasini yaratishni anglatadi. Bu men xato kiritishim mumkin bo'lgan juda ko'p murakkablik va muvaffaqiyatsizlik nuqtalarini qo'shadi.

Oddiy yondashuvni qidiring

Men ushbu qayta dizaynni amalga oshirish g'oyasidan juda qo'rqdim. Albatta, buni amalga oshirish mumkin edi, lekin bunday oddiy muammoni hal qilish uchun juda ko'p murakkablikni kiritish to'g'ri emas edi. Men kutubxonaning dizayni haqida, ham ommaga mo'ljallangan API, ham uni past darajada amalga oshirish nuqtai nazaridan o'ylab ko'rmoqchi edim. Bu men Elmda tez-tez qiladigan narsadir. Agar men bu muammoni TypeScript kabi boshqa tilda hal qilsam, maydonlar ma'lum bir nom bilan necha marta yaratilganligini hisoblash uchun global holatni qo'shish oson bo'lar edi. Ushbu yondashuv bilan bog'liq o'tmishdagi tajribaga ko'ra, bu xato hisobotlari, noto'g'ri musbat va negativ testlar va boshqa odamlar kodga tegishi va bu g'alati xatti-harakat qaerdan kelib chiqqanligini yoki uni to'g'ri saqlash uchun nima qilishlari kerakligini tushunmasliklariga olib keladi. Bu yashirin holat bilan bog'liq muammo. Bu muammolarni tezda hal qilish uchun juda qulay. Ammo uzoq muddatda siz haqiqiy xarajatni his qila boshlaysiz. Holat haqiqatdan ham kodni o‘ylab ko‘rish va o‘zgartirishni qiyinlashtiradigan narsa va kodni o‘qish/o‘zgartirish biz kodlash soatlarining ko‘p qismini sarflaydigan narsadir. Shunday qilib, agar biz davlatni minimallashtira olsak, bu juda katta g'alaba!

Men bu muammoni hal qilish uchun Elm ilovamda qandaydir holat yaratgan bo'lardim, lekin bu aniq bo'lishi kerak va shuning uchun u boshqa tillarga qaraganda zerikarliroq. Albatta, Elm ilovasida sizga davlat kerak bo'lgan ko'plab joylar mavjud, ammo siz qancha shtatga ega ekanligingizga va uning aniqligi tufayli qancha joy bu holatga bog'liqligiga ko'proq moslashasiz. Oxir oqibat, men buni juda yaxshi kelishuv deb topdim, chunki siz "biror narsani tezda ishga tushirishni" xohlaganingizda qanchalik asabiylashsa bo'ladi. Davomlilik haqida gap ketganda, bu aniq yondashuv qisqa muddatda ham to'laydi.

Eng oddiy yechim

Oxir-oqibat men xesh-ga asoslangan maydon taxalluslaridan foydalanish g'oyasiga keldim:

{
  currentUser {
    avatarABC: avatar(size: 12)
    avatarXYZ: avatar(size: 48)
  }
}

Maydon argumentlari asosida noyob xeshni yaratish orqali (tasavvur qiling-a, ABC (size: 12) ning xesh ifodasi), sizga noaniq so'rovlardan qochish kafolatlanadi. Va atrofdagi so'rovda qaysi maydonlar ishlatilishini bilishingiz shart emas! Bu yechim ancha oson va xatoga yo'l qo'ymaydi, chunki uning taxallusni aniqlash uchun sizga faqat ma'lum bir maydon kerak bo'ladi. Birodaru opa-singillarini ko'rish yoki keyinchalik u ko'proq aka-ukalar paydo bo'ladimi, deb tashvishlanishning hojati yo'q. Yakuniy amalga oshirish tafsilotlari haqida ko'proq "Ushbu Github soni" da o'qishingiz mumkin.

Pastki chiziq

Xo'sh, nima uchun bu juda muhim? Men tilda, ramkada, kodlash texnikasida va hokazolarda izlayotgan asosiy fazilatlardan biri bu uning soddalikka moyilligidir. Misol uchun, agar til yoki ramka bilan qayta ishlash zerikarli yoki xatoga moyil bo'lsa, siz buni kamroq qilasiz. Agar u Elmdagi kabi o'q o'tkazmaydigan va oson bo'lsa, kod yanada barqaror bo'lishga moyil bo'ladi. Vaqt o'tishi bilan, Elm kod bazalari minimal holatga ega bo'lishga intiladi. Va kamroq holat kamroq harakatlanuvchi qismlar, arzonroq o'zgarishlar va kamroq xatolarni anglatadi.

Men "bepul intro Elm suhbatlari" ni taklif qilaman. Agar sizning jamoangiz Elm haqida ko'proq bilishni xohlasa, menga xabar qoldiring! Yoki oddiyroq yechimga yo'naltiruvchi til yoki tizim bilan o'xshash tajribaga ega bo'lsangiz, sharhlaringizni baham ko'ring.