Application'lar

Bir Application, bir Backend üzerinde yayımlanmış bir ön yüz yüzeyidir. application.json manifesti, bağlı bir Backend'in sözleşmelerini karşılaması gereken Driver'ları adlandırır.

Özet

  • Bir Application, bir application.json manifesti aracılığıyla bir ya da daha fazla Backend'e bağlı, UI sunan bir container'dır. On demand sunulur: container ilk istekte başlar ve kullanılmaz hâle gelince durur.
  • Manifest needs_driver_id (canlı wire sözleşmesi) ve taps_driver_id (kayıt / replay sözleşmesi) taşır. Endpoint gereksinimleri, manifest içinde satır içi değil, o Driver satırlarında required_endpoints olarak yaşar.
  • Endpoint URL'leri bir Backend özelliğidir ve bu URL'leri sunar hâle getiren şey canlı bir Deployment'tır. Bir required endpoint, belirli bir Deployment üzerinde değil, Backend üzerinde somut bir URL'ye çözülür.
  • Image'ı kaynağınızdan platform derler. Ona başka yerde derlenmiş bir image verme yolu yoktur.
  • Dört fiil, dört ayrı etki: publish bir sürüm derler, promote hangi sürümün sunulacağına karar verir, release Application'ı kimin görebileceğine karar verir, deploy yalnızca container'ı erken başlatır.

Zihinsel model — needs ↔ alias'lar

Bir Driver'ın required_endpoints girdisi, bir bağlama sözleşmesinin tüketici yarısıdır; diğer yarısı Backend'deki bir endpoint alias'ıdır. Endpoint alias modeli — alias'ların grafiği yüzeyden nasıl ayrıştırdığı ve bir (vertex, endpoint-name)'i bir role'e nasıl eşlediği — /concepts/solutions sayfasına aittir; bu sayfa yalnızca bir Application'ın bir Driver'ı nasıl işaret ettiğini ve o Driver'ın Backend'den ne talep ettiğini ele alır.

Application bir Driver adlandırır; Driver da endpoint'leri adlandırır:

   application.json          driver satırı
   ┌────────────────────┐    ┌─────────────────────────────┐
   │ needs_driver_id ──►│───►│ required_endpoints[]        │
   │ taps_driver_id     │    │   name:       upload        │
   └────────────────────┘    │   role:       upload        │
                             │   direction:  ingress       │
                             │   transports: [http]        │
                             │   required:   true          │
                             └─────────────────────────────┘

Platform bir required endpoint'i role üzerinden bir alias ile eşleştirir, ardından direction'ın uyduğunu ve listelenen transports'tan en az birinin alias'ın desteklediğiyle örtüştüğünü doğrular. Alias yoksa, direction uymuyorsa ya da hiçbir transport örtüşmüyorsa çözümleme fail-closed başarısız olur: required: true bir endpoint Application'ı bloke eder, required: false bir endpoint düşürülür.

Application, Backend grafiğine, Deployment yaşam döngüsüne, Component implementasyonlarına, container yerleşimine ya da Runtime yerleştirmesine sahip değildir. Bunlar Application'ın çözülmüş endpoint URL'leri üzerinden tükettiği yukarı akış meseleleridir.

Zihinsel model — derle, sun, göster

   publish ──────►  N sürümü var           ne derlendi
   promote ──────►  N sürümü sunuluyor     ziyaretçiler ne alıyor
   release ──────►  katalogda listeli      kim görebilir

Publish etmek ziyaretçilere sunulanı değiştirmez; bir sürümü derleyip başka kimse almadan inceleyebilmenizi sağlayan da tam olarak budur. Geçişi yapan adım promote'tur. Release ise ikisine de dokunmaz.

Adım adım — bir UI'ı bir Backend'e bağlama

Ön koşullar: UI'ın ihtiyaç duyduğu endpoint alias'larına sahip bir Backend (ppl backend change-endpoint-alias ile bildirilmiş), UI'ın ne tükettiğini tarif eden bir Driver ve içinde Dockerfile bulunan bir kaynak dizini.

# 1. Driver sözleşmesini application.json içinde adlandırın:#    {#      "name": "doc_scanner_ui",#      "read_me":       { "schema_version": 1, ... },#      "read_me_agent": { "schema_version": 1, ... },#      "needs_driver_id": "<driver id>"#    }# 2. Application'ı ve sözleşmesini kaydedinppl application create --name doc_scanner_ui --manifest ./application.json# 3. kaynağı bir sürüme derleyinppl application publish doc_scanner_ui --dir ./ui -m "first cut"# 4. o sürümü ziyaretçilere sunulan sürüm yapınppl application promote doc_scanner_ui# 5. workspace katalogunda listeleyinppl application release doc_scanner_ui

Backend canlı bir Deployment arkasında çalışırken Driver'ın her required endpoint'i, Backend'in yayımlanmış endpoint'i üzerinde somut bir URL'ye çözülür. UI, yüklemeleri upload URL'sine gönderir ve events URL'sine abone olur; Backend'in vertex yerleşimi, container yerleştirmesi ve Runtime'ı ona görünmez kalır.

Derleme sözleşmesi

--dir altındaki ağaç yüklenir ve platformun build cluster'ında derlenir. Projeyi derleyen ve HTTP üzerinden 80 numaralı portta sunan bir Dockerfile taşımalıdır.

Derlemeler BuildKit'i değil Docker'ın klasik builder'ını kullanır, bu yüzden RUN --mount=type=secret ve RUN --mount=type=cache başarısız olur. Derleme zamanı registry kimlik bilgilerini platformun derleme bağlamına enjekte ettiği .npmrc'den okuyun.

Bir monorepo içindeki proje lockfile'ını ve paketlerini kardeşleriyle paylaşır, dolayısıyla tek başına yüklenemez. Workspace'i yükleyin ve projeyi onun içinde adlandırın:

ppl application publish doc_scanner_ui --dir . --project apps/doc_scanner_ui

Dockerfile projeden okunur; derleme yine de tüm workspace'i görür.

Sunum performansı

Bir Application statik bir origin'dir, dolayısıyla yaydığı yanıt başlıkları önbellek hikâyesinin tamamıdır. Her istekte değil, derleme zamanında bir kez sıkıştırın:

RUN find out -type f \( -name '*.js' -o -name '*.css' -o -name '*.html' \        -o -name '*.json' -o -name '*.svg' \) -exec gzip -9 -k {} \;

Ardından ön sıkıştırılmış artefaktı sunun ve değişmez asset'leri kabuktan ayrı önbelleğe alın:

gzip_static on;gzip on;gzip_comp_level 6;gzip_vary on;# İçerik hash'li yollar: baytlar değiştiğinde ad da değişir.location /_next/static/ {    add_header Cache-Control "public, max-age=31536000, immutable";    add_header Vary "Accept-Encoding";}# Kabuk güncel asset hash'lerini adlandırır; onu önbelleğe almak# ziyaretçileri artık var olmayan bir derlemeye sabitler.location / {    add_header Cache-Control "no-cache";    try_files $uri $uri/ /index.html;}

Açıkça belirtmeye değer üç kural, çünkü her biri canlı bir Application'ı devirmiştir:

  • try_files location eşleştirmesine yeniden girmez. Eşleşen dosyayı doğrudan sunar; bu yüzden ön sıkıştırılmış asset'lere Content-Encoding iliştirmek için yazılmış bir location ~ \.br$ bloğu, try_files ile ulaşılan bir dosya için asla çalışmaz. Asset application/octet-stream olarak gelir ve tarayıcı onu çalıştırmayı reddeder. gzip_static location ile dağıtılmaz ve bunu tümüyle atlar.
  • İç içe bir location'daki add_header, miras alınan kümeyi değiştirir, ona eklemez. Bir location'ın ihtiyaç duyduğu her başlık o location içinde belirtilmelidir.
  • Container 80 numaralı portu dinlemelidir.

Varyasyonlar

Yalnızca kayıt — yerel yineleme. ppl application register doc_scanner_ui, container'sız ve sözleşmesiz, internal modda bir Application satırı oluşturur; yalnızca bir ad alır, başka hiçbir şey almaz. Satırı yalnızca siz görürsünüz; yinelerken yerel bir dev sunucusuyla birlikte kullanın, sözleşmeleri update ile ekleyin, UI hazır olunca publish edin.

Daha eski bir sürümü sunma. ppl application promote doc_scanner_ui --version <version_id>, en yenisi yerine belirli bir yayımlanmış sürümü sunar; kötü bir derleme böyle geri alınır. Bayrak, sürümün id'sini ppl application versions'tan alır, yanında gösterilen seq'i değil.

Sözleşmeyi bağlama ya da yeniden bağlama. ppl application update doc_scanner_ui --needs-driver <driver_id> --taps-driver <driver_id> iki sözleşmeyi doğrudan ayarlar; --manifest aynısını bir dosyadan yapar. --new-name Application'ı yeniden adlandırır.

Soğuk başlangıcı atlama. ppl application deploy doc_scanner_ui, container'ı ilk istek gelmeden başlatır; böylece ilk ziyaretçi beklemez. --force hâlihazırda sunan bir container'ı değiştirir.

Herkese yayımlama. ppl application release doc_scanner_ui --public, Application'ı genel katalogda listeler ve giriş yapmadan adıyla sunar.

Referans — application.json

{  "name": "doc_scanner_ui",  "read_me":       { "schema_version": 1, "...": "..." },  "read_me_agent": { "schema_version": 1, "...": "..." },  "needs_driver_id": "<uuid>",  "taps_driver_id":  "<uuid>"}
AlanAnlamı
nameApplication tanımlayıcısı. Application kapsamlı her komut tarafından kullanılır.
read_meTipli ürün belgesi: summary, what_this_does, who_it_is_for, primary_workflows, launch_modes, limitations.
read_me_agentTipli seçim sözleşmesi: summary, pick_when, do_not_pick_when, interaction_model, required_launch_modes, workflows, limitations. Hem olumlu hem olumsuz ölçütler zorunludur; böylece bir ajan yalnızca uyumluluktan ilgililik çıkaramaz.
needs_driver_idBir Backend'in ingress tarafında sözleşmesini karşılaması gereken Driver — UI'ın tükettiği canlı wire yüzeyi. Opsiyoneldir; atlandığında Application kısıtsız kalır.
taps_driver_idKayıt / replay tarafı için Driver. Opsiyoneldir ve çoğu zaman needs_driver_id ile aynı Driver satırıdır.

Backend'in karşılaması gereken endpoint gereksinimleri, o Driver satırlarından {name, role, direction, transports, required} biçimindeki required_endpoints girdileri olarak okunur.

Çalıştır

ppl application create   --name <name> [--manifest ./application.json] [--readme <yol>] [--agent-manifest <yol>] [--needs-driver <id>] [--taps-driver <id>]ppl application register <name>                                   # dahili stub, container yok, bayrak yokppl application publish  <name> [--dir <source_dir>] [--project <yol>] [-m <note>] [--no-cache] [--node <id>]ppl application versions <name>ppl application promote  <name> [--version <version_id>]ppl application release  <name> [--public]ppl application deploy   <name> [--force]ppl application stop     <name>ppl application update   <name> [--manifest <yol>] [--needs-driver <id>] [--taps-driver <id>] [--new-name <yeni>] [--public | --private]ppl application listppl application delete   <name>

İlgili

  • Solution'lar — tüm yığın; Application, bir Backend ve onun Deployment'ı üzerindeki UI'dır.
  • Backend'ler — Driver'ın required_endpoints'inin bağlandığı endpoint alias'larının bildirildiği yer.
  • Deployment'lar — Backend'in yayımlanmış endpoint URL'lerini destekleyen runtime.

Bu sayfa yardımcı oldu mu?