1. nesil Node.js işlevlerini 2. nesle yükseltme

1. nesil işlevleri kullanan uygulamalar, bu kılavuzdaki talimatları uygulayarak 2. nesil işlevlere geçmeyi düşünebilir. 2. nesil işlevler, daha iyi performans, daha iyi yapılandırma, daha iyi izleme ve daha fazlasını sağlamak için Cloud Run'ı kullanır.

Bu sayfadaki örneklerde, CommonJS modülleriyle (require stilinde içe aktarmalar) JavaScript kullandığınız varsayılır. Ancak aynı ilkeler, ESM (import … from stilinde içe aktarmalar) ve TypeScript ile JavaScript için de geçerlidir.

Taşıma süreci

1. nesil ve 2. nesil işlevler aynı dosyada yan yana bulunabilir. Bu sayede, hazır olduğunuzda taşıma işlemini parça parça kolayca yapabilirsiniz. İşleme devam etmeden önce her seferinde bir işlevi taşımanızı, test ve doğrulama yapmanızı öneririz.

Firebase CLI ve firebase-function sürümlerini doğrulama

En az Firebase CLI sürümü 12.00 ve firebase-functions sürümü 4.3.0 kullandığınızdan emin olun. Daha yeni sürümler hem 1. hem de 2. nesil cihazları destekleyecektir.

İçe aktarma işlemlerini güncelleme

2. nesil işlevler, firebase-functions SDK'sındaki v2 alt paketinden içe aktarılır. Bu farklı içe aktarma yolu, Firebase CLI'nin işlev kodunuzu 1. veya 2. nesil işlev olarak dağıtıp dağıtmayacağını belirlemek için ihtiyacı olan tek şeydir.

v2 alt paketi modülerdir ve yalnızca ihtiyacınız olan belirli modülü içe aktarmanızı öneririz.

Önce: 1. nesil

const functions = require("firebase-functions/v1");

Sonra: 2. nesil

// explicitly import each trigger
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

Tetikleyici tanımlarını güncelleme

2. nesil SDK, modüler içe aktarmaları tercih ettiğinden tetikleyici tanımlarını, önceki adımdaki içe aktarmalarda yapılan değişiklikleri yansıtacak şekilde güncelleyin.

Bazı tetikleyiciler için geri çağırma işlevlerine iletilen bağımsız değişkenler değişti. Bu örnekte, onDocumentCreated geri çağırma işlevinin bağımsız değişkenlerinin tek bir event nesnesinde birleştirildiğini unutmayın. Ayrıca, bazı tetikleyicilerde onRequest tetikleyicisinin cors seçeneği gibi kullanışlı yeni yapılandırma özellikleri bulunur.

Önce: 1. nesil

const functions = require("firebase-functions/v1");

exports.date = functions.https.onRequest((req, res) => {
  // ...
});

exports.uppercase = functions.firestore
  .document("my-collection/{docId}")
  .onCreate((change, context) => {
    // ...
  });

Sonra: 2. nesil

const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

exports.date = onRequest({cors: true}, (req, res) => {
  // ...
});

exports.uppercase = onDocumentCreated("my-collection/{docId}", (event) => {
  /* ... */
});

Parametre haline getirilmiş yapılandırmayı kullanma

2. nesil işlevler, kod tabanınızda yapılandırma parametrelerini bildirimsel olarak tanımlamak için daha güvenli bir arayüz sunmak amacıyla functions.config desteğini bırakıyor. Yeni params modülüyle, tüm parametreler geçerli bir değere sahip olmadığı sürece CLI dağıtımı engeller. Böylece, bir işlevin eksik yapılandırmayla dağıtılmaması sağlanır.

params alt paketine taşıma

functions.config ile ortam yapılandırması kullanıyorsanız mevcut yapılandırmanızı parametreli yapılandırmaya taşıyabilirsiniz.

Önce: 1. nesil

const functions = require("firebase-functions/v1");

exports.date = functions.https.onRequest((req, res) => {
  const date = new Date();
  const formattedDate =
date.toLocaleDateString(functions.config().dateformat);

  // ...
});

Sonra: 2. nesil

const {onRequest} = require("firebase-functions/v2/https");
const {defineString} = require("firebase-functions/params");

const dateFormat = defineString("DATE_FORMAT");

exports.date = onRequest((req, res) => {
  const date = new Date();
  const formattedDate = date.toLocaleDateString(dateFormat.value());

  // ...
});

Parametre değerlerini ayarlama

İlk dağıtımınızda Firebase CLI, parametrelerin tüm değerlerini ister ve değerleri bir dotenv dosyasına kaydeder. functions.config değerlerinizi dışa aktarmak için firebase functions:config:export komutunu çalıştırın.

Ek güvenlik için parametre türlerini ve doğrulama kurallarını da belirtebilirsiniz.

Özel durum: API anahtarları

params modülü, API anahtarları gibi hassas değerlere ayrıntılı erişim kontrolü sağlayan Cloud Secret Manager ile entegre olur. Daha fazla bilgi için gizli parametreler başlıklı makaleyi inceleyin.

Önce: 1. nesil

const functions = require("firebase-functions/v1");

exports.getQuote = functions.https.onRequest(async (req, res) => {
  const quote = await fetchMotivationalQuote(functions.config().apiKey);
  // ...
});

Sonra: 2. nesil

const {onRequest} = require("firebase-functions/v2/https");
const {defineSecret} = require("firebase-functions/params");

// Define the secret parameter
const apiKey = defineSecret("API_KEY");

exports.getQuote = onRequest(
  // make the secret available to this function
  { secrets: [apiKey] },
  async (req, res) => {
    // retrieve the value of the secret
    const quote = await fetchMotivationalQuote(apiKey.value());
    // ...
  }
);

Çalışma zamanı seçeneklerini ayarlama

Çalışma zamanı seçeneklerinin yapılandırılması 1. ve 2. nesil arasında değişti. 2. nesil, tüm işlevler için seçenekleri ayarlama konusunda yeni bir özellik de ekliyor.

Önce: 1. nesil

const functions = require("firebase-functions/v1");

exports.date = functions
  .runWith({
    // Keep 5 instances warm for this latency-critical function
    minInstances: 5,
  })
  // locate function closest to users
  .region("asia-northeast1")
  .https.onRequest((req, res) => {
    // ...
  });

exports.uppercase = functions
  // locate function closest to users and database
  .region("asia-northeast1")
  .firestore.document("my-collection/{docId}")
  .onCreate((change, context) => {
    // ...
  });

Sonra: 2. nesil

const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
const {setGlobalOptions} = require("firebase-functions/v2");

// locate all functions closest to users
setGlobalOptions({ region: "asia-northeast1" });

exports.date = onRequest({
    // Keep 5 instances warm for this latency-critical function
    minInstances: 5,
  }, (req, res) => {
  // ...
});

exports.uppercase = onDocumentCreated("my-collection/{docId}", (event) => {
  /* ... */
});

Eşzamanlılığı kullanma

2. nesil işlevlerin önemli bir avantajı, tek bir işlev örneğinin aynı anda birden fazla isteğe hizmet verebilmesidir. Bu, son kullanıcıların yaşadığı baştan başlatma sayısını önemli ölçüde azaltabilir. Varsayılan olarak eşzamanlılık 80'e ayarlanır ancak 1 ila 1.000 arasında herhangi bir değere ayarlayabilirsiniz:

const {onRequest} = require("firebase-functions/v2/https");

exports.date = onRequest({
    // set concurrency value
    concurrency: 500
  },
  (req, res) => {
    // ...
});

Eşzamanlılık ayarını yapma, performansı artırabilir ve işlevlerin maliyetini düşürebilir. Eşzamanlı isteklere izin ver bölümünde eşzamanlılık hakkında daha fazla bilgi edinin.

Genel değişken kullanımını denetleme

Eşzamanlılık göz önünde bulundurulmadan yazılan 1. nesil işlevler, her istekte ayarlanan ve okunan global değişkenler kullanabilir. Eşzamanlılık etkinleştirildiğinde ve tek bir örnek aynı anda birden fazla isteği işlemeye başladığında, eşzamanlı istekler genel değişkenleri aynı anda ayarlamaya ve okumaya başladığından bu durum işlevinizde hatalara neden olabilir.

Yükseltme sırasında işlevinizin CPU'sunu gcf_gen1 olarak ayarlayabilir ve 1. nesil davranışını geri yüklemek için concurrency değerini 1 olarak ayarlayabilirsiniz:

const {onRequest} = require("firebase-functions/v2/https");

exports.date = onRequest({
    // TEMPORARY FIX: remove concurrency
    cpu: "gcf_gen1",
    concurrency: 1
  },
  (req, res) => {
    // ...
});

Ancak bu, 2. nesil işlevlerin performans avantajlarını ortadan kaldırdığı için uzun vadeli bir çözüm olarak önerilmez. Bunun yerine, işlevlerinizdeki global değişkenlerin kullanımını denetleyin ve hazır olduğunuzda bu geçici ayarları kaldırın.

Trafiği yeni 2. nesil işlevlere taşıma

Bir işlevin bölgesini veya tetikleyici türünü değiştirirken olduğu gibi, 2. nesil işleve yeni bir ad vermeniz ve trafiği yavaş yavaş bu işlevin üzerine geçirmeniz gerekir.

Aynı ada sahip bir işlevi 1. nesilden 2. nesile yükseltmek ve firebase deploy çalıştırmak mümkün değildir. Bu durumda şu hata mesajı gösterilir:

Upgrading from GCFv1 to GCFv2 is not yet supported. Please delete your old function or wait for this feature to be ready.

Bu adımları uygulamadan önce, değişikliğin yapıldığı sırada işlevinizin hem yeni hem de eski sürümü aynı anda çalışacağından işlevinizin idempotent olduğundan emin olun. Örneğin, Firestore'daki yazma etkinliklerine yanıt veren 1. nesil bir işleviniz varsa bu etkinliklere yanıt olarak iki kez yazma işleminin (bir kez 1. nesil işlev, bir kez de 2. nesil işlev tarafından) uygulamanızı tutarlı bir durumda bıraktığından emin olun.

  1. İşlev kodunuzda işlevi yeniden adlandırın. Örneğin, resizeImage dosyasını resizeImageSecondGen olarak yeniden adlandırın.
  2. İşlevi dağıtın. Böylece hem orijinal 1. nesil işlev hem de 2. nesil işlev çalışır.
    1. Çağrılabilir, görev sırası ve HTTP tetikleyicileri söz konusu olduğunda, istemci kodunu 2. nesil işlevin adıyla veya URL'siyle güncelleyerek tüm istemcileri 2. nesil işlevine yönlendirmeye başlayın.
    2. Arka plan tetikleyicileriyle hem 1. nesil hem de 2. nesil işlevler, dağıtıldıktan sonra her etkinliğe anında yanıt verir.
  3. Tüm trafik taşındıktan sonra firebase CLI'nin firebase functions:delete komutunu kullanarak 1. nesil işlevi silin.
    1. İsteğe bağlı olarak, 2. nesil işlevi 1. nesil işlevin adıyla eşleşecek şekilde yeniden adlandırın.