Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Eklentileri çağırma

Bu sayfa, bir eklentinin komut ve sorgularını HTTP ile nasıl çağıracağınızı anlatır: başlıklar, sürüm denetimi, tekrar güvenliği, sonuç sorgusu ve hata zarfı. SDK kullanıyorsanız çoğunu SDK sizin yerinize yapar; yine de ne olduğunu bilmek hata ayıklamayı kolaylaştırır.

Not

Eklentiler için ortak bir /openapi.json yoktur; eklentinin kendi şema belgesi (artifact) GET /v1/plugins/{plugin_id}/schema ucundan alınır. Kullanabileceğiniz işlemlerin listesi oradadır (bağlamalar).

Uçlar

Yöntem ve yolAmaç
POST /v1/plugins/{plugin_id}/commands/{message_type}Komutu çalıştırır
GET /v1/plugins/{plugin_id}/commands/{message_type}/resultKomutun sonucunu idempotency anahtarıyla sorgular
GET /v1/plugins/{plugin_id}/queries/{message_type}Sorguyu çalıştırır (parametreler sorgu dizesinde)
POST /v1/plugins/{plugin_id}/queries/{message_type}Sorguyu çalıştırır (parametreler gövdede)
GET /v1/plugins/{plugin_id}/schemaEklentinin şema belgesini verir

{plugin_id} eklenti kimliğidir (ör. package-ride). {message_type} işlemin istek mesaj türüdür (ör. package-ride.progression-missions.login-bonus.input); işlemin adı (claimLoginBonus) değildir. Tam yol ve mesaj türü şema belgesindeki her işlemin path ve requestMessageType alanında yazar. Hangi yöntemin (GET ya da POST) kullanılacağını da işlemin method alanı söyler: bazı sunucu sorguları POST ile çağrılır.

Kimlik

ÇağıranGönderilecek
Oyuncu (çerez)Cookie (__Secure-crx.session) + x-crx-env: <ortam uuid>; değiştirici (POST) isteklerde ayrıca x-csrf-token + __Secure-crx.csrf çerezi
Oyuncu (Bearer)Authorization: Bearer <oturum jetonu> + x-crx-env: <ortam uuid>. Eklenti ucu değiştirici isteklerde Bearer ile de CSRF çiftini (__Secure-crx.csrf çerezi + x-csrf-token) ister; çerezsiz istemci çifti GET /v1/auth/csrf ile alıp kendisi taşır (oturumlar ve CSRF)
SunucuAuthorization: Bearer crx_live_<önek>_<gizli> (sunucu anahtarı). x-crx-env gönderirseniz anahtarın ortamıyla aynı olmalı, aksi halde 401. CSRF ve Origin denetimi uygulanmaz
Herkese açık sorguYalnız x-crx-env; yalnız GET ve yalnız şema belgesinde access: public olan sorgular

crx_ ile başlayan ama sunucu türünde olmayan (istemci) anahtar 401 unauthorized alır. Oyuncu isteklerinde Origin başlığı varsa ortamın izinli kökenlerinden biri olmalıdır (tarayıcı kendisi ekler); aksi halde 403 forbidden. Değiştirici bir çağrı başarılı olduğunda yanıt yeni CSRF çiftini (Set-Cookie ve x-csrf-token başlığı) döndürür; bir sonraki değiştirici istekte bunu kullanın.

Komut çağırma

POST /v1/plugins/package-ride/commands/package-ride.progression-missions.login-bonus.input HTTP/1.1
Host: oyun.example.com
Origin: https://oyun.example.com
Cookie: __Secure-crx.session=<oturum>; __Secure-crx.csrf=<csrf-çerezi>
x-crx-env: 0192a3b4-0000-7000-8000-000000000001
x-csrf-token: <csrf-jetonu>
x-crx-schema-version: 1
Idempotency-Key: 5d1f2c88-4f0b-4c8f-9f1e-9a3f6b0c1d22
If-Match: "3"
Content-Type: application/json

{"expectedVersion":"3"}
HTTP/1.1 200 OK
Content-Type: application/json
x-crx-message-type: package-ride.progression-missions.login-bonus.output
x-crx-schema-version: 1

{"version":"4","rewardMinor":"250","streak":"2","day":"19300","walletBalanceMinor":"1250","claimEventId":"0192a3b4-0000-7000-8000-0000000000c1","ledgerCorrelationId":"0192a3b4-0000-7000-8000-0000000000c2"}
BaşlıkZorunluAnlam
Idempotency-Keykomutlarda evetMantıksal tekrar anahtarı; boş olamaz. Kurallar
x-crx-schema-versionevetGönderdiğiniz yükün şema sürümü (pozitif tam sayı); işlemin schemaVersion değeriyle eşleşmelidir. Sorgularda da zorunludur
If-MatchhayırBeklenen kaynak sürümü (iyimser kilit, optimistic lock). Ondalık tam sayı, tırnaklı ya da tırnaksız; * ve W/ önekli değerler 400 alır. Gerçek sürüm farklıysa 409
Content-Type: application/jsonevetGövde JSON’dur ve işlemin istek şemasına uyar

Not

Gövde alanlarındaki int64 değerler ondalık metin olarak gider ("expectedVersion":"3"), JSON sayısı olarak değil; yanıt da aynı biçimdedir. Ayrıntı: sayılar ve kodlama. int32 ve uint32 alanlar JSON sayısıdır.

Başarılı yanıtın gövdesi, işlemin yanıt şemasına uyan JSON’dur; x-crx-message-type ve x-crx-schema-version yanıt başlıkları çıktı mesajını belirtir.

Aynı anahtarla tekrar

Ağ koparsa ya da yanıtı alamazsanız aynı Idempotency-Key ve aynı gövdeyle tekrar gönderin; sunucu işlemi ikinci kez uygulamaz, kayıtlı sonucu döner.

DurumYanıt
İlk istekİşlenir, 200
Aynı anahtar, aynı gövdeKayıtlı sonuç döner
Aynı anahtar, farklı gövde422 ve idempotency_mismatch
Aynı anahtarlı istek hâlâ işleniyor409 ve idempotency_in_flight (retryable: true); biraz sonra tekrar deneyin
Kayıt süresi doldu (işlemin receiptRetentionSeconds değeri, örnekte 86 400 sn)410 ve idempotency_expired

Yeni bir anahtar üretmek yeni bir işlem demektir; belirsiz sonuçlu bir komutu yeni anahtarla yeniden göndermeyin.

Sonuç sorgusu

Yanıtı hiç alamadığınız bir komutun sonucunu, tekrar göndermeden öğrenin:

GET /v1/plugins/package-ride/commands/package-ride.progression-missions.login-bonus.input/result?idempotency_key=5d1f2c88-4f0b-4c8f-9f1e-9a3f6b0c1d22&output_message_type=package-ride.progression-missions.login-bonus.output&output_schema_version=1 HTTP/1.1
x-crx-env: 0192a3b4-0000-7000-8000-000000000001
Cookie: __Secure-crx.session=<oturum>

Üç sorgu parametresi de zorunludur: idempotency_key, output_message_type ve output_schema_version. Yol, işlemin resultPath alanıyla aynıdır.

YanıtAnlamNe yapmalı
200 + gövdeKomut kesinleşmişti; gövde çıktıdırSonucu kullanın
202 (boş gövde)Henüz işleniyorKısa süre sonra tekrar sorgulayın
404Bu anahtarla kayıt yok: komut hiç uygulanmamışYalnız bu durumda aynı anahtar ve gövdeyle komutu gönderebilirsiniz
422 + reasonKomut işlendi ve iş kuralı tarafından reddedildiGönderme; reason makine kodudur
410Kayıt süresi dolduSonuç bilinmiyor; durumu sorguyla yeniden okuyun

Sorgu çağırma

GET ile parametreler sorgu dizesinde gider. Her değer önce JSON olarak ayrıştırılır; olmazsa metin sayılır; null değeri null olur. Aynı parametreyi iki kez vermek 400 alır.

GET /v1/plugins/package-ride/queries/package-ride.delivery-trip.active.input HTTP/1.1
x-crx-env: 0192a3b4-0000-7000-8000-000000000001
x-crx-schema-version: 1
Cookie: __Secure-crx.session=<oturum>

POST ile aynı alanlar JSON gövdesinde gider. Karmaşık ya da uzun girdiler için POST uygundur; hangi yöntemin geçerli olduğunu işlemin method alanından okuyun. Herkese açık sorgu örneği:

GET /v1/plugins/package-ride/queries/package-ride.world-catalog.get.input HTTP/1.1
x-crx-env: 0192a3b4-0000-7000-8000-000000000001
x-crx-schema-version: 1

Şema ucu

GET /v1/plugins/{plugin_id}/schema eklentinin şema belgesini (JSON) verir (Cache-Control: no-store). Oyuncu oturumu ya da sunucu anahtarı gerekir. Eklenti ortamınız için etkin değilse ya da grant sürümü uyuşmuyorsa 404’tür. Belgenin alanlarını ve schemaSha256 değerinin kullanımını bağlamalar sayfasında bulursunuz.

Hata zarfı

Eklenti uçları JSON hata zarfı döner (çekirdek REST uçlarının düz metin hatalarından farklı olarak; karşılaştırma için hatalar):

{"code":"conflict","message":"version conflict: expected 3, actual 5","retryable":false,"requestId":"0192a3b4-0000-7000-8000-0000000000d1"}

Yanıtta ayrıca x-request-id başlığı bulunur; destek talebinde bu kimliği iletin.

codeHTTPretryableNe zaman
unauthorized401hayırOturum/anahtar yok, geçersiz, istemci anahtarı ya da ortam uyuşmazlığı
forbidden403hayırCSRF ya da Origin reddi; eklenti etkin değil ya da sürüm uyuşmuyor; yasaklı hesap (message: account banned)
module_disabled404hayırplugins modülü kapalı (module alanı modül adını taşır)
not_found404hayırBilinmeyen eklenti ya da mesaj türü; kayıt yok
invalid_argument400hayırEksik/bozuk başlık, bilinmeyen şema sürümü, şemaya uymayan yük, kopya sorgu parametresi
conflict409hayırIf-Match sürümü gerçekle uyuşmuyor
idempotency_in_flight409evetAynı anahtarlı istek hâlâ işleniyor
idempotency_mismatch422hayırAynı anahtar, farklı gövde
unprocessable422hayırİş kuralı reddi; reason alanı makine kodunu taşır
idempotency_expired410hayırKayıt süresi doldu
rate_limited429evetOran sınırı; Retry-After: 60 (hız sınırları)
tenant_unavailable503evetOrtamın yerleşimi geçici kullanılamıyor; Retry-After: 30
internal500evetSunucu hatası

reason alanı yalnız iş kuralı reddinde (unprocessable) bulunur (ör. street_reset_too_early) ve eklentiye özgüdür; anlamı eklentinin belgesindedir. Sürüm uyuşmazlığında (conflict) mesaj beklenen ve gerçek sürümü içerir: durumu yeniden okuyup yeni sürümle tekrar deneyin.

Uyarı

Eklenti uçlarında yasaklı hesap account_banned koduyla gelmez: 403 ve code: "forbidden", message: "account banned" döner. account_banned kodu oyuncu kimlik uçlarına (giriş, kayıt) aittir (hatalar). İstemciniz bu iki durumu ayırt edecekse mesaja değil oturum durumuna bakın.

Örnek: komutu belirsiz sonuca karşı güvenle çağırmak

Aşağıdaki TypeScript örneği, SDK bağlamasıyla komutu hazırlar (tek Idempotency-Key üretilir), gönderir; sonuç belirsizse yeni komut üretmeden sonucu sorgular ve yalnız notFound yanıtında aynı anahtarla yeniden gönderir. demo-game eklentisi bu örnek için hazırlanmış bir kurgudur: gerçek eklentinizde işlem adlarını ve alanları kendi şema belgenizden alırsınız (bağlamalar).

import { CrxError, ErrorKind, type PlayerClient } from "@ferdiunal/open-play-ts";
import { DemoGameBinding } from "./generated/demo-game.js";

/**
 * Günlük hediyeyi alır. `prepare` tek `Idempotency-Key` üretir; ağ hatasında sonuç belirsizse yeni komut üretilmez:
 * önce sonuç sorgulanır, yalnız "kayıt yok" yanıtında AYNI anahtarla yeniden gönderilir.
 */
export async function claimDailyGift(client: PlayerClient, expectedVersion: bigint): Promise<bigint> {
  const demo = client.plugin(DemoGameBinding);
  const command = await demo.commands.claimDailyGift.prepare({ giftKey: "daily" }, { expectedVersion });
  try {
    const output = await command.send();
    return output.walletBalanceMinor; // int64 alanlar bigint gelir
  } catch (error) {
    if (!(error instanceof CrxError) || error.kind !== ErrorKind.UnknownOutcome) throw error;
    const outcome = await command.lookup();
    if (outcome.status === "committed") return outcome.result.walletBalanceMinor;
    if (outcome.status === "notFound") return (await command.resume()).walletBalanceMinor; // aynı anahtar, aynı gövde
    throw error; // pending, rejected ya da expired: kör tekrar yok
  }
}

/** Salt-okunur sorgu: tekrar güvenlidir, anahtar gerekmez. */
export async function hasClaimedToday(client: PlayerClient): Promise<boolean> {
  const demo = client.plugin(DemoGameBinding);
  const status = await demo.queries.getGiftStatus({ includeHistory: false });
  return status.claimedToday;
}

Sıradaki adım