İçeriğe atla
M. Fehmi ToktayYazılım ve Shopify geliştiricisi

Teknik yaklaşım

Nasıl yazıyorum

Aşağıdakiler tercih değil, sahada bir kere kaybedip öğrenilmiş kurallar. Hepsi bir hataya mal olmuş; bu yüzden istisnasız uygulanıyor.

İlkeler

API sürümü koda gömülü kalmaz

Shopify API'si dönemsel sürümler yayınlıyor ve her sürüm sınırlı süre destekleniyor. Uygulama bir sürüme kilitlenir, yükseltme planlı yapılır. Sürüm adı kodun içine dağılmışsa bir gün sessizce kırılır — tek yerden yönetilir.

Hız limiti baştan hesaba katılır

Admin GraphQL API sorgu maliyeti hesaplayıp bütçeye göre sınırlıyor. Toplu işlerde sayfa sayfa gezmek yerine toplu işlem uçları kullanılır; sınıra yaklaşıldığında geri çekilme ve yeniden deneme mantığı kurulur.

Her webhook doğrulanır, her işlem idempotent yazılır

Gelen isteğin imzası uygulama gizli anahtarıyla doğrulanmadan hiçbir şey işlenmez. Aynı olay birden çok kez gelebilir; ikinci işlem bir şey değiştirmemeli.

Kapsam dar istenir

İstenen her erişim kapsamının kullanıldığı yer gösterilebilmeli. Geniş kapsam hem incelemede geri döner hem mağaza sahibini tedirgin eder. Yeni kapsam gerektiğinde yeniden yetkilendirme istenir.

Toplu iş loglanır ve geri alınabilir

İş gruplar hâlinde yürür, her adım satır satır log dosyasına yazılır, yarıda kalırsa kaldığı yerden devam eder. Değişen alanların eski değerleri kimlikleriyle saklanır.

Doğrulama kaynağın kendisinden yapılır

Başarı çıktısına güvenilmez: yazılan değişiklik geri çekilip aranır. Sayfa önbelleği kaynakla aynı değildir; doğrulama panelden ya da API'den yapılır, tarayıcıdan değil.

Silmeden önce yönlendirme kurulur

Koleksiyon, sayfa ya da ürün silinecekse önce 301 kurulur, sonra silinir, sonra yönlendirmenin çalıştığı doğrulanır. Sıra bu değilse adres bir süre 404 verir.

Ölçüm CSS okuyarak değil, tarayıcıdan yapılır

Hangi kuralın kazandığı özgüllük yarışıyla belirlenir; kaynağa bakarak tahmin etmek yanıltır. Konum ve boyut değerleri çalışan sayfadan okunur.

Webhook imzası doğrulanmadan hiçbir şey işlenmez

webhook.js js
const gelen = req.get('X-Shopify-Hmac-Sha256') || '';
const hesaplanan = crypto
  .createHmac('sha256', process.env.SHOPIFY_API_SECRET)
  .update(hamGovde, 'utf8')
  .digest('base64');

const a = Buffer.from(hesaplanan, 'base64');
const b = Buffer.from(gelen, 'base64');

// uzunluk farkliysa timingSafeEqual firlatir, once onu ele
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
  return res.status(401).send();
}

İmza doğrulaması olmayan bir webhook ucu, herkesin veri yazabildiği açık bir kapıdır.

Boş render eden blok bırakmamak

hediye-kutu.liquid liquid
{%- comment -%}
  Isaret ettigi kayit yoksa blok hic basilmaz.
  Bos render eden blok aylarca fark edilmez.
{%- endcomment -%}

{%- assign hediye = all_products[section.settings.hediye_handle] -%}

{%- if hediye != blank and hediye.available -%}
  <div class="hediye" data-esik="{{ section.settings.esik }}">
    <p>{{ section.settings.mesaj }}</p>
  </div>
{%- endif -%}

Bir mağazada silinmiş bir ürüne işaret eden hediye bloğu aylarca sessizce boş basmıştı. Koşul olmadan yazılan her referanslı blok aynı riski taşır.

Shopify tarafında çalıştığım yüzeyler

Admin GraphQL APIürün, varyant, sipariş, metafield okuma ve yazma
Bulk Operationsbinlerce kayıtlık iş; sonuç JSONL olarak indirilir
Webhooksolay yakalama, HMAC doğrulama, idempotent işleme
OAuth · Billing APIkurulum akışı, kapsam yönetimi, abonelik ücretlendirmesi
App Bridge · Polarisyönetim paneli içinde açılan gömülü arayüz
Liquid · Online Store 2.0bölüm ve blok yazımı, tema editöründen yönetim
Storefront · Ajax APIsepet işlemleri, tema içi dinamik davranış
Metafield · Metaobjectürün künyesi ve yapılandırılmış veri
URL Redirectgeçişlerde yönlendirme haritası
Theme CLIyayınlanmamış temada geliştirme, önizleme, canlıya alma

Mevcut kurulumunuz bu ölçütleri karşılıyor mu?

Bakıp ne gördüğümü yazayım — mağazanın adresi yeterli.