Aracılığıyla paylaş


Azure Functions Node.js geliştirici kılavuzu

Bu kılavuz, JavaScript veya TypeScript kullanarak Azure Functions geliştirmeye giriş niteliğindedir. Makalede, Azure Functions geliştirici kılavuzunu okuduğunuz varsayılır.

Önemli

Bu makalenin içeriği, bu sayfanın en üstündeki seçicide Node.js programlama modeli seçiminize göre değişir. Seçtiğiniz sürüm, uygulamanızda kullandığınız npm paketinin sürümüyle @azure/functions eşleşmelidir. package.json listenizde bu paket yoksa, varsayılan değer v3'tür. Geçiş kılavuzunda v3 ve v4 arasındaki farklar hakkında daha fazla bilgi edinin.

Node.js geliştirici olarak aşağıdaki makalelerden biriyle de ilgilenebilirsiniz:

Başlamaya Hazırlık Kavramlar Rehberli öğrenme

Dikkat edilmesi gereken noktalar

  • Node.js programlama modeli Azure Functions çalışma zamanıyla karıştırılmamalıdır:
    • Programlama modeli: Kodunuzu nasıl yazdığınızı tanımlar ve JavaScript ve TypeScript'e özgüdür.
    • Runtime: Azure Functions temel davranışını tanımlar ve tüm dillerde paylaşılır.
  • Programlama modelinin sürümü kesinlikle npm paketinin sürümüne @azure/functions bağlıdır. Çalışma zamanından bağımsız olarak sürümlenmiştir. Hem çalışma zamanı hem de programlama modeli en son ana sürümü olarak 4 sayısını kullanır, ancak bu bir tesadüftür.
  • Aynı işlev uygulamasında v3 ve v4 programlama modellerini karıştıramazsınız. Uygulamanıza bir v4 işlevi kaydettiğiniz anda, function.json dosyalarında kayıtlı tüm v3 işlevleri yoksayılır.

Desteklenen sürümler

Aşağıdaki tabloda, Node.js programlama modelinin her sürümüyle birlikte desteklenen Azure Functions çalışma zamanı ve Node.jssürümleri gösterilmektedir.

Programlama Modeli Sürümü Destek Düzeyi İşlevler Çalışma Zamanı Sürümü Node.js Sürümü Açıklama
4.x Georgia 4.25+ 22.x 20.x, 18.x Esnek bir dosya yapısını ve tetikleyicilere ve bağlamalara yönelik kod odaklı yaklaşımı destekler.
3.x Georgia 4.x 20.x, 18.x, 16.x, 14.x "function.json" dosyasında bildirilen tetikleyicileriniz ve bağlamalarınızla belirli bir dosya yapısı gerektirir
2.x yok 3.x 14.x, 12.x, 10.x 13 Aralık 2022 tarihinde destek sonuna ulaşıldı. Daha fazla bilgi için bkz . İşlev sürümleri .
1.x yok 2.x 10.x, 8.x 13 Aralık 2022 tarihinde destek sonuna ulaşıldı. Daha fazla bilgi için bkz . İşlev sürümleri .

Klasör yapısı

JavaScript projesi için gerekli klasör yapısı aşağıdaki örneğe benzer:

<project_root>/
 | - .vscode/
 | - node_modules/
 | - myFirstFunction/
 | | - index.js
 | | - function.json
 | - mySecondFunction/
 | | - index.js
 | | - function.json
 | - .funcignore
 | - host.json
 | - local.settings.json
 | - package.json

<project_root> ana proje klasörü aşağıdaki dosyaları içerebilir:

  • .vscode/: (İsteğe bağlı) Depolanan Visual Studio Code yapılandırmasını içerir. Daha fazla bilgi için bkz. Visual Studio Code settings.
  • myFirstFunction/function.json: İşlevin tetikleyicisi, girişleri ve çıkışları için yapılandırmayı içerir. dizininin adı işlevinizin adını belirler.
  • myFirstFunction/index.js: İşlev kodunuzu depolar. Bu varsayılan dosya yolunu değiştirmek için scriptFile kullanma konusuna bakınız.
  • .funcignore: (İsteğe bağlı) Azure yayımlanmaması gereken dosyaları bildirir. Bu dosya genellikle düzenleyici ayarınızı yoksaymak için .vscode/, test senaryolarını yoksaymak için test/ ve yerel uygulama ayarlarının yayımlanmasını önlemek için local.settings.json içerir.
  • host.json: İşlev uygulaması örneğindeki tüm işlevleri etkileyen yapılandırma seçeneklerini içerir. Bu dosya Azure yayımlanır. Yerel olarak çalıştırılırken tüm seçenekler desteklenmez. Daha fazla bilgi edinmek için bkz . host.json.
  • local.settings.json: Yerel olarak çalışırken uygulama ayarlarını ve bağlantı dizesi depolamak için kullanılır. Bu dosya Azure yayımlanmaz. Daha fazla bilgi için bkz . local.settings.file.
  • package.json: Paket bağımlılıklarının listesi, ana giriş noktası ve betikler gibi yapılandırma seçeneklerini içerir.

JavaScript projesi için önerilen klasör yapısı aşağıdaki örneğe benzer:

<project_root>/
 | - .vscode/
 | - node_modules/
 | - src/
 | | - functions/
 | | | - myFirstFunction.js
 | | | - mySecondFunction.js
 | - test/
 | | - functions/
 | | | - myFirstFunction.test.js
 | | | - mySecondFunction.test.js
 | - .funcignore
 | - host.json
 | - local.settings.json
 | - package.json

<project_root> ana proje klasörü aşağıdaki dosyaları içerebilir:

  • .vscode/: (İsteğe bağlı) Depolanan Visual Studio Code yapılandırmasını içerir. Daha fazla bilgi için bkz. Visual Studio Code settings.
  • src/functions/: Tüm işlevler ve bunların ilgili tetikleyicileri ve bağlamaları için varsayılan konum.
  • test/: (İsteğe bağlı) İşlev uygulamanızın test çalışmalarını içerir.
  • .funcignore: (İsteğe bağlı) Azure yayımlanmaması gereken dosyaları bildirir. Bu dosya genellikle düzenleyici ayarınızı yoksaymak için .vscode/, test senaryolarını yoksaymak için test/ ve yerel uygulama ayarlarının yayımlanmasını önlemek için local.settings.json içerir.
  • host.json: İşlev uygulaması örneğindeki tüm işlevleri etkileyen yapılandırma seçeneklerini içerir. Bu dosya Azure yayımlanır. Yerel olarak çalıştırılırken tüm seçenekler desteklenmez. Daha fazla bilgi edinmek için bkz . host.json.
  • local.settings.json: Yerel olarak çalışırken uygulama ayarlarını ve bağlantı dizesi depolamak için kullanılır. Bu dosya Azure yayımlanmaz. Daha fazla bilgi için bkz . local.settings.file.
  • package.json: Paket bağımlılıklarının listesi, ana giriş noktası ve betikler gibi yapılandırma seçeneklerini içerir.

İşlev kaydetme

v3 modeli, iki dosya varlığına göre bir işlev kaydeder. İlk olarak, uygulamanızın kökünden bir düzey aşağıda bir klasörde bulunan bir dosyaya ihtiyacınız vardır function.json . İkincisi, işlevinizi dışarı aktaran bir JavaScript dosyası gerekir. Varsayılan olarak, model, index.js ile aynı klasördeki function.json dosyasını arar. TypeScript kullanıyorsanız, derlenmiş JavaScript dosyasını işaret etmek için içindeki scriptFile özelliğini kullanmanız function.json gerekir. İşlevinizin dosya konumunu veya dışarı aktarma adını özelleştirmek için bkz . İşlevinizin giriş noktasını yapılandırma.

Dışarı aktardığınız işlev her zaman v3 modelinde olarak async function bildirilmelidir. Zaman uyumlu bir işlevi dışarı aktarabilirsiniz, ancak ardından işlevinizin tamamlandığını ve kullanım dışı bırakıldığını ve önerilmediğini belirten bir çağrı context.done() göndermeniz gerekir.

İşlevinize ilk bağımsız değişken olarak bir çağrı context ve kalan bağımsız değişkenler olarak girişleriniz kabul edilir.

Aşağıdaki örnek, tetiklendiğini günlüğe kaydeden ve Hello, world! ile yanıt veren basit bir işlevdir.

{
  "bindings": [
    {
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "authLevel": "anonymous",
      "methods": ["get", "post"]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    }
  ]
}
module.exports = async function (context, request) {
  context.log("Http function was triggered.");
  context.res = { body: "Hello, world!" };
};

Programlama modeli, işlevlerinizi main içindeki package.json alanına göre yükler. Glob deseni mainkullanarak alanı tek bir dosyaya veya birden çok dosyaya ayarlayabilirsiniz. Aşağıdaki tabloda alan için örnek değerler gösterilmektedir main :

Örnek Açıklama
src/index.js İşlevleri tek bir kök dosyadan kaydedin.
src/functions/*.js Her işlevi kendi dosyasından tanımlayın.
src/{index.js,functions/*.js} Her işlevi kendi dosyasından kaydettiğiniz, ancak genel uygulama düzeyindeki kod için yine de bir kök dosyaya sahip olduğunuz bir yöntem.

Bir işlevi kaydetmek için, npm modülünden app nesnesini içeri aktarmanız @azure/functions ve tetikleyici türünüzle ilgili yöntemi çağırmanız gerekir. İlk bağımsız değişken, bir işlevi kaydederken işlev adıdır. İkinci bağımsız değişken, tetikleyiciniz, işleyiciniz ve diğer giriş veya çıkışlar için yapılandırmayı belirten bir options nesnedir. Tetikleyici yapılandırmasının gerekli olmadığı bazı durumlarda, işleyiciyi nesne options yerine doğrudan ikinci bağımsız değişken olarak geçirebilirsiniz.

Bir işlev, main dosyanızdaki package.json alanına bağlı olarak (doğrudan veya dolaylı olarak) yüklendiği sürece projenizdeki herhangi bir dosyadan kaydedilebilir. Yürütmeler başladıktan sonra işlevleri kaydedemediğiniz için işlevin genel kapsamda kaydedilmesi gerekir.

Aşağıdaki örnek, tetiklendiğini günlüğe kaydeden ve Hello, world! ile yanıt veren basit bir işlevdir.

const { app } = require("@azure/functions");

app.http("helloWorld1", {
  methods: ["POST", "GET"],
  handler: async (request, context) => {
    context.log("Http function was triggered.");
    return { body: "Hello, world!" };
  },
});

Girişler ve çıkışlar

İşlevinizin tetikleyici olarak adlandırılan tam olarak bir birincil girişe sahip olması gerekir. ayrıca ikincil girişlere ve/veya çıkışlara da sahip olabilir. Girişler ve çıkışlar function.json dosyalarınızda yapılandırılır ve bağlamalar olarak da adlandırılır.

Girişler

Girişler, direction olarak ayarlanmış in bağlamalardır. Tetikleyici ile ikincil giriş arasındaki temel fark, tetikleyici için değerin type ile bitmesidir Trigger; örneğin, tür blobTrigger vs tür blob. İşlevlerin çoğu yalnızca tetikleyici kullanır ve çok fazla ikincil giriş türü desteklenmez.

Girişlere çeşitli yollarla erişilebilir:

  • [Önerilen] İşlevinize geçirilen bağımsız değişkenler: Bağımsız değişkenleri function.json tanımlandığı sırayla kullanın. name içindeki function.json tanımlanan özelliğin bağımsız değişkeninizin adıyla eşleşmesi gerekmez, ancak kod düzeni açısından bunu öneririz.

    module.exports = async function (context, myTrigger, myInput, myOtherInput) { ... };
    

  • özellikleri context.bindingsolarak: içinde nametanımlanan özelliğiyle function.json eşleşen anahtarı kullanın.

    module.exports = async function (context) {
      context.log("This is myTrigger: " + context.bindings.myTrigger);
      context.log("This is myInput: " + context.bindings.myInput);
      context.log("This is myOtherInput: " + context.bindings.myOtherInput);
    };
    

Çıkışlar

Çıkışlar, direction olarak ayarlanmış bağlamalar olup, çeşitli yollarla ayarlanabilir:

  • [Tek çıkış için önerilir] Değeri doğrudan döndür: Zaman uyumsuz bir işlev kullanıyorsanız, değeri doğrudan döndürebilirsiniz. Aşağıdaki örnekte olduğu gibi, name içinde $return çıkış bağlamasının function.json özelliğini değiştirmelisiniz.

    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    }
    
    module.exports = async function (context, request) {
      return {
        body: "Hello, world!",
      };
    };
    

  • [Birden çok çıkış için önerilir] Tüm çıkışları içeren bir nesne döndür: Zaman uyumsuz bir işlev kullanıyorsanız, içindeki function.jsonher bağlamanın adıyla eşleşen bir özelliğe sahip bir nesne döndürebilirsiniz. Aşağıdaki örnekte "httpResponse" ve "queueOutput" adlı çıkış bağlamaları gerçekleştirilir:

    {
        "name": "httpResponse",
        "type": "http",
        "direction": "out"
    },
    {
        "name": "queueOutput",
        "type": "queue",
        "direction": "out",
        "queueName": "helloworldqueue",
        "connection": "storage_APPSETTING"
    }
    
    module.exports = async function (context, request) {
      let message = "Hello, world!";
      return {
        httpResponse: {
          body: message,
        },
        queueOutput: message,
      };
    };
    

  • üzerindeki context.bindingsdeğerleri ayarlayın: Zaman uyumsuz bir işlev kullanmıyorsanız veya önceki seçenekleri kullanmak istemiyorsanız, değerleri doğrudan üzerinde context.bindingsayarlayabilirsiniz; burada anahtar bağlamanın adıyla eşleşir. Aşağıdaki örnekte "httpResponse" ve "queueOutput" adlı çıkış bağlamaları gerçekleştirilir:

    {
        "name": "httpResponse",
        "type": "http",
        "direction": "out"
    },
    {
        "name": "queueOutput",
        "type": "queue",
        "direction": "out",
        "queueName": "helloworldqueue",
        "connection": "storage_APPSETTING"
    }
    
    module.exports = async function (context, request) {
      let message = "Hello, world!";
      context.bindings.httpResponse = {
        body: message,
      };
      context.bindings.queueOutput = message;
    };
    

Bağlamalar veri türü

Girişinizin türünü değiştirmek için giriş bağlaması üzerinde özelliğini kullanabilirsiniz dataType . Ancak, yaklaşımın bazı sınırlamaları vardır:

  • Node.js'da yalnızca string ve binary desteklenir (stream desteklenmez)
  • HTTP girişleri için dataType özelliği yoksayılır. Bunun yerine, request nesnesindeki özellikleri kullanarak gövdeyi istediğiniz biçimde alın. Daha fazla bilgi için bkz . HTTP isteği.

Aşağıdaki depolama kuyruğu tetikleyicisi örneğinde, varsayılan türü myQueueItem bir string şeklindedir, ancak dataTypebinary olarak ayarlarsanız türü Node.js Buffer olarak değişir.

{
  "name": "myQueueItem",
  "type": "queueTrigger",
  "direction": "in",
  "queueName": "helloworldqueue",
  "connection": "storage_APPSETTING",
  "dataType": "binary"
}
const { Buffer } = require("node:buffer");

module.exports = async function (context, myQueueItem) {
  if (typeof myQueueItem === "string") {
    context.log("myQueueItem is a string");
  } else if (Buffer.isBuffer(myQueueItem)) {
    context.log("myQueueItem is a buffer");
  }
};

İşlevinizin tetikleyici olarak adlandırılan tam olarak bir birincil girişe sahip olması gerekir. ayrıca ikincil girişlere, dönüş çıkışı olarak adlandırılan birincil çıkışa ve/veya ikincil çıkışlara da sahip olabilir. Girişler ve çıkışlar, Node.js programlama modeli bağlamı dışında bağlamalar olarak da adlandırılır. Modelin v4'ünden önce bu bağlamalar dosyalarda function.json yapılandırıldı.

Tetikleyici girişi

Tetikleyici tek gerekli giriş veya çıkıştır. Birçok tetikleyici türü için, tür adına sahip app nesnesinde bir yöntem kullanarak bir işlev kaydedersiniz. Tetikleyiciye özgü bir yapılandırmayı doğrudan options bağımsız değişkende belirtebilirsiniz. Örneğin, HTTP tetikleyicisi bir yol belirtmenize olanak tanır. Yürütme sırasında, bu tetikleyiciye karşılık gelen değer ilk bağımsız değişken olarak işleyicinize geçirilir.

const { app } = require('@azure/functions');

app.http('helloWorld1', {
    route: 'hello/world',
    handler: async (request, context) => {
        ...
    }
});

Çıktıyı döndür

Dönüş çıkışı isteğe bağlıdır ve bazı durumlarda varsayılan olarak yapılandırılır. Örneğin, ile app.http kaydedilen bir HTTP tetikleyicisi, otomatik olarak bir HTTP yanıt çıkışı döndürecek şekilde yapılandırılır. Çoğu çıkış türü için, options modülünden dışa aktarılan output nesnesinin yardımıyla @azure/functions bağımsız değişkeninde dönüş yapılandırmasını belirtirsiniz. Yürütme sırasında, işleyicinizden döndürerek bu çıkışı ayarlarsınız.

Aşağıdaki örnekte zamanlayıcı tetikleyicisi ve depolama kuyruğu çıkışı kullanılır:

const { app, output } = require('@azure/functions');

app.timer('timerTrigger1', {
    schedule: '0 */5 * * * *',
    return: output.storageQueue({
        connection: 'storage_APPSETTING',
        ...
    }),
    handler: (myTimer, context) => {
        return { hello: 'world' }
    }
});

Ek girişler ve çıkışlar

Tetikleyiciye ve dönüşe ek olarak, bir işlevi tanımlarken argümanda options ek girişler veya çıkışlar belirtebilirsiniz. input ve output nesneleri, @azure/functions modülünden dışarı aktarılan ve yapılandırmanın oluşturulmasına yardımcı olmak için özel türe özgü yöntemler sunar. Yürütme sırasında, özgün yapılandırma nesnesini ilk argüman olarak geçirerek context.extraInputs.get ile context.extraOutputs.set değerlerini alır veya ayarlarsınız.

Aşağıdaki örnek, bir depolama kuyruğu tarafından tetiklenen, ek bir depolama blobu girişi ve bu girişin kopyalandığı ek bir depolama blobu çıkışı olan bir işlevdir. Kuyruk iletisi bir dosya adı olmalı ve bir {queueTrigger} yardımıyla, yerine kopyalanacak blob adı olarak geçirilmelidir.

const { app, input, output } = require("@azure/functions");

const blobInput = input.storageBlob({
  connection: "storage_APPSETTING",
  path: "helloworld/{queueTrigger}",
});

const blobOutput = output.storageBlob({
  connection: "storage_APPSETTING",
  path: "helloworld/{queueTrigger}-copy",
});

app.storageQueue("copyBlob1", {
  queueName: "copyblobqueue",
  connection: "storage_APPSETTING",
  extraInputs: [blobInput],
  extraOutputs: [blobOutput],
  handler: (queueItem, context) => {
    const blobInputValue = context.extraInputs.get(blobInput);
    context.extraOutputs.set(blobOutput, blobInputValue);
  },
});

Genel girişler ve çıkışlar

app, trigger, input ve output nesneleri, @azure/functions modülü tarafından dışarı aktarılan, çoğu tür için tipine özgü yöntemler sağlar. Desteklenmeyen tüm türler için yapılandırmayı el ile belirtmenize olanak sağlayan bir generic yöntem sağlanır. Türe özgü bir metot tarafından sağlanan varsayılan ayarları değiştirmek istiyorsanız, generic metodu da kullanılabilir.

Aşağıdaki örnek, türe özgü yöntemler yerine genel yöntemler kullanan basit bir HTTP ile tetiklenen işlevdir.

const { app, output, trigger } = require("@azure/functions");

app.generic("helloWorld1", {
  trigger: trigger.generic({
    type: "httpTrigger",
    methods: ["GET", "POST"],
  }),
  return: output.generic({
    type: "http",
  }),
  handler: async (request, context) => {
    context.log(`Http function processed request for url "${request.url}"`);

    return { body: `Hello, world!` };
  },
});

SDK türleri

Birkaç bağlama uzantısı artık doğrudan Azure SDK türleriyle çalışmanızı sağlar.

Azure Blob depolama

Azure Functions'deki SDK bağlamaları özelliği, ham veriler yerine doğrudan BlobClient ve ContainerClient gibi Azure Blob depolama SDK'sı türleriyle çalışmanızı sağlar. Bu, bloblarla çalışırken tüm SDK yöntemlerine tam erişim sağlar.

Projenizi SDK türleriyle çalışacak şekilde yapılandırmak için:

  1. @azure/functions-extensions-blob Uzantı önizleme paketlerini projedeki dosyaya package.json ekleyin; en azından şu paketleri içermelidir:
"dependencies": {
  "@azure/functions": "4.7.2-preview",
  "@azure/functions-extensions-blob": "0.2.0-preview"
},
  1. Öğenizde akış türlerini desteklemek için enableHttpStream: true ekleyin app.setup.
import { app } from '@azure/functions';

app.setup({
    enableHttpStream: true,
});

Bu örnekte BlobClient'ın hem Depolama Blobu tetikleyicisinden hem de HTTP tetikleyicisi üzerindeki giriş bağlamasından nasıl alınacakları gösterilmektedir:

import "@azure/functions-extensions-blob"; // This is the mandatory first import for SDK binding
import { StorageBlobClient } from "@azure/functions-extensions-blob";
import { app, InvocationContext } from "@azure/functions";

export async function storageBlobTrigger(
  blobStorageClient: StorageBlobClient, // SDK binding provides this client
  context: InvocationContext
): Promise<void> {
  context.log(`Blob trigger processing: ${context.triggerMetadata.name}`);

  // Access to full SDK capabilities
  const blobProperties = await blobStorageClient.blobClient.getProperties();
  context.log(`Blob size: ${blobProperties.contentLength}`);

  // Download blob content
  const downloadResponse = await blobStorageClient.blobClient.download();
  context.log(`Content: ${downloadResponse}`);
}

// Register the function
app.storageBlob("storageBlobTrigger", {
  path: "snippets/{name}",
  connection: "AzureWebJobsStorage",
  sdkBinding: true, // Enable SDK binding
  handler: storageBlobTrigger,
});

HTTP tetikleyicisini kullanarak bir Depolama Blobu giriş bağlamasından ContainerClient elde etmenin nasıl olduğunu bu örnek göstermektedir.

import "@azure/functions-extensions-blob"; // This is the mandatory first import for SDK binding
import { StorageBlobClient } from "@azure/functions-extensions-blob";
import {
  app,
  HttpRequest,
  HttpResponseInit,
  input,
  InvocationContext,
} from "@azure/functions";

const blobInput = input.storageBlob({
  path: "snippets",
  connection: "AzureWebJobsStorage",
  sdkBinding: true,
});

export async function listBlobs(
  request: HttpRequest,
  context: InvocationContext
): Promise<HttpResponseInit> {
  // Get input binding for a specific container
  const storageBlobClient = context.extraInputs.get(
    blobInput
  ) as StorageBlobClient;

  // List all blobs in the container
  const blobs = [];
  for await (const blob of storageBlobClient.containerClient.listBlobsFlat()) {
    blobs.push(blob.name);
  }

  return { jsonBody: { blobs } };
}

app.http("listBlobs", {
  methods: ["GET"],
  authLevel: "function",
  extraInputs: [blobInput],
  handler: listBlobs,
});

SDK türleriyle çalışırken şu noktaları göz önünde bulundurun:

  • Yan etkilerin çalıştığından emin olmak için import "@azure/functions-extensions-blob"'ın dosyalarınızda ilk sırada olduğundan her zaman emin olun.
  • Bağlama yapılandırmanızda ayarlayın sdkBinding: true .
  • İşleminiz için uygun istemci türünü kullanın:
    • blobClient tek bir blob üzerindeki işlemler için
    • containerClient bir kapsayıcı üzerindeki işlemler için
  • Bloklarla try/catch hataları uygun şekilde işleme
  • Büyük blob işlemleri için bellek sorunlarını önlemek için akış yöntemlerini kullanmayı göz önünde bulundurun.

Daha fazla bilgi için bu Blob Storage SDK Bağlamaları için Node.js Örnekleri'ne bakın: İşlev uygulamanıza Blob için SDK Bağlamaları ekleme konusunda daha fazla örnek bulabilirsiniz.

Azure Service Bus

Bu örnek, Service Bus tetikleyicisi tarafından sağlanan ServiceBusReceivedMessage ile elde edilen ServiceBusMessageContext SDK türünü kullanır.

import '@azure/functions-extensions-servicebus'; // Ensure the Service Bus extension is imported
import { app, InvocationContext } from '@azure/functions';
import { ServiceBusMessageContext, messageBodyAsJson } from '@azure/functions-extensions-servicebus';

// This sample uses sdkBinding = true with manual message completion.
// With v0.4.0, message.body is returned as a raw Buffer instead of auto-parsed object.
export async function serviceBusQueueTrigger(
    serviceBusMessageContext: ServiceBusMessageContext,
    context: InvocationContext
): Promise<void> {
    const message = serviceBusMessageContext.messages[0];

    // v0.4.0: message.body is a Buffer — use messageBodyAsJson<T>() from the extension for one-line parsing
    const bodyData = messageBodyAsJson(message);
    context.log('Parsed message body:', bodyData);

    // Get current retry count from custom properties, default to 0
    const currentRetryCount = message.applicationProperties?.retryCnt
        ? parseInt(message.applicationProperties.retryCnt as string)
        : 0;
    context.log(`Current retry count: ${currentRetryCount}`);

    if (currentRetryCount >= 3) {
        // After 3 retries, complete the message to remove it from the queue
        context.log(`Maximum retry count (3) reached. Completing message to prevent infinite loop.`);
        await serviceBusMessageContext.actions.complete(message);
        context.log('Message completed after maximum retries');
    } else {
        // Abandon with updated retry count
        const newRetryCount = currentRetryCount + 1;
        const propertiesToModify = {
            retryCnt: newRetryCount.toString(),
            lastRetryTime: new Date().toISOString(),
            errorMessage: 'Processing failed',
        };

        context.log(`Abandoning message with retry count: ${newRetryCount}`);
        await serviceBusMessageContext.actions.abandon(message, propertiesToModify);
    }

    context.log('triggerMetadata: ', context.triggerMetadata);
}

app.serviceBusQueue('serviceBusQueueTrigger1', {
    connection: 'ServiceBusConnection',
    queueName: 'testqueue',
    sdkBinding: true,

SDK türlerini kullanan başka bir örnek için üstel gerileme stratejisi örneğine bakın.

Çağırma bağlamı

İşlevinizin her çağrısına girişleri okumak, çıkışları ayarlamak, günlüklere yazmak ve çeşitli meta verileri okumak için kullanılan bir çağırma context nesnesi geçirilir. v3 modelinde bağlam nesnesi her zaman işleyicinize geçirilen ilk bağımsız değişkendir.

context nesnesi aşağıdaki özelliklere sahiptir:

Özellik Açıklama
invocationId Geçerli işlev çağrısının kimliği.
executionContext Bkz. yürütme bağlamı.
bindings Bkz. bağlamalar.
bindingData Bu çağrı için tetikleyici girişiyle ilgili meta veriler, değerin kendisi hariç. Örneğin, bir olay merkezi tetikleyicisi özelliğine enqueuedTimeUtc sahiptir.
traceContext Dağıtılmış izleme bağlamı. Daha fazla bilgi için bkz. Trace Context.
bindingDefinitions girişlerinizin ve çıkışlarınızın yapılandırması, function.json'de tanımlandığı gibi.
req Bkz. HTTP isteği.
res Bkz. HTTP yanıtı.

context.yürütmeBağlamı

context.executionContext nesnesi aşağıdaki özelliklere sahiptir:

Özellik Açıklama
invocationId Geçerli işlev çağrısının kimliği.
functionName Çağrılan işlevin adı. dosyayı içeren function.json klasörün adı işlevin adını belirler.
functionDirectory Dosyayı içeren function.json klasör.
retryContext Bkz. yeniden deneme bağlamı.

context.executionContext.retryContext

context.executionContext.retryContext nesnesi aşağıdaki özelliklere sahiptir:

Özellik Açıklama
retryCount Geçerli yeniden deneme denemesini temsil eden bir sayı.
maxRetryCount Yürütmenin yeniden denenme sayısının maksimumu. -1 süresiz olarak yeniden deneneceği anlamına gelir.
exception Yeniden denemeye neden olan özel durum.

context.bindings

context.bindings nesnesi, girişleri okumak veya çıkışları ayarlamak için kullanılır. Aşağıdaki örnek, bir depolama kuyusu tetikleyicisi kullanarak bir depolama blobu girişi kopyalayarak bir depolama blobu çıkışı oluşturur. Kuyruk iletisinin içeriği, bir {queueTrigger} yardımıyla kopyalanacak dosya adı olarak ile değiştirilir.

{
    "name": "myQueueItem",
    "type": "queueTrigger",
    "direction": "in",
    "connection": "storage_APPSETTING",
    "queueName": "helloworldqueue"
},
{
    "name": "myInput",
    "type": "blob",
    "direction": "in",
    "connection": "storage_APPSETTING",
    "path": "helloworld/{queueTrigger}"
},
{
    "name": "myOutput",
    "type": "blob",
    "direction": "out",
    "connection": "storage_APPSETTING",
    "path": "helloworld/{queueTrigger}-copy"
}
module.exports = async function (context, myQueueItem) {
  const blobValue = context.bindings.myInput;
  context.bindings.myOutput = blobValue;
};

bağlam.tamamlandı

context.done yöntemi kullanım dışıdır. Zaman uyumsuz işlevler desteklenmeden önce, işlevin tamamlandığını belirtmek için context.done() çağrılırdı.

module.exports = function (context, request) {
  context.log("this pattern is now deprecated");
  context.done();
};

context.done() çağrısını kaldırmanızı ve işlevinizi zaman uyumsuz olarak işaretlemenizi, böylece bir 'promise' döndürmesini (hiçbir şey await olmasa bile) öneririz. İşleviniz tamamlanır tamamlanmaz (başka bir deyişle, döndürülen söz çözümlenir), v3 modeli işlevinizin tamam olduğunu bilir.

module.exports = async function (context, request) {
  context.log("you don't need context.done or an awaited call");
};

İşlevinizin her çağrısına, çağırma ve günlüğe kaydetme için kullanılan yöntemler hakkında bilgi içeren bir çağrı context nesnesi geçirilir. v4 modelinde nesne genellikle context işleyicinize geçirilen ikinci bağımsız değişkendir.

InvocationContext sınıfı aşağıdaki özelliklere sahiptir:

Özellik Açıklama
invocationId Geçerli işlev çağrısının kimliği.
functionName İşlevin adı.
extraInputs Ek girişlerin değerlerini almak için kullanılır. Daha fazla bilgi için bkz . ek girişler ve çıkışlar.
extraOutputs Ek çıkışların değerlerini ayarlamak için kullanılır. Daha fazla bilgi için bkz . ek girişler ve çıkışlar.
retryContext Bkz. yeniden deneme bağlamı.
traceContext Dağıtılmış izleme bağlamı. Daha fazla bilgi için bkz. Trace Context.
triggerMetadata Bu çağrı için tetikleyici girişiyle ilgili meta veriler, değerin kendisi hariç. Örneğin, bir olay merkezi tetikleyicisi özelliğine enqueuedTimeUtc sahiptir.
options İşlev doğrulandıktan sonra ve varsayılanlar açıkça belirtildikten sonra, işlevi kaydederken kullanılan seçenekler.

Bağlamı yeniden dene

retryContext nesnesi aşağıdaki özelliklere sahiptir:

Özellik Açıklama
retryCount Geçerli yeniden deneme denemesini temsil eden bir sayı.
maxRetryCount Yürütmenin yeniden denenme sayısının maksimumu. -1 süresiz olarak yeniden deneneceği anlamına gelir.
exception Yeniden denemeye neden olan özel durum.

Daha fazla bilgi için bkz. retry-policies.

Loglama

Azure Functions günlükleri yazmak için context.log() kullanılması önerilir. Azure Functions, işlev uygulaması günlüklerinizi daha iyi yakalamak için Azure Application Insights ile tümleşir. Azure Monitor parçası olan Application Insights, hem uygulama günlüklerinin hem de izleme çıkışlarınızın toplanması, görsel işlenmesi ve analizi için olanak sağlar. Daha fazla bilgi edinmek için bkz. monitoring Azure Functions.

Not

Alternatif Node.js console.log yöntemini kullanırsanız, bu günlükler uygulama düzeyinde izlenir ve belirli bir işlevle ilişkilendirılmaz . Belirli bir işleve ait olmaları için yerine context kullanmanızı console ve tüm günlüklerin ilişkili olmasını sağlarız.

Aşağıdaki örnek, çağrı kimliğini içererek varsayılan "bilgi" düzeyinde bir günlük yazmaktadır.

context.log(`Something has happened. Invocation ID: "${context.invocationId}"`);

Günlük düzeyleri

Varsayılan context.log yönteme ek olarak, günlükleri belirli düzeylerde yazmanıza olanak sağlayan aşağıdaki yöntemler kullanılabilir:

Metot Açıklama
context.log.error() Günlüklere hata düzeyinde bir olay yazar.
context.log.warn() Günlüklere uyarı düzeyi bir olay yazar.
context.log.info() Günlüklere bilgi düzeyinde bir olay yazar.
context.log.verbose() Günlüklere izleme düzeyinde bir olay yazar.
Metot Açıklama
context.trace() Günlüklere izleme düzeyinde bir olay yazar.
context.debug() Günlüklere hata ayıklama düzeyinde bir olay yazar.
context.info() Günlüklere bilgi düzeyinde bir olay yazar.
context.warn() Günlüklere uyarı düzeyi bir olay yazar.
context.error() Günlüklere hata düzeyinde bir olay yazar.

Günlük düzeyini yapılandırma

Azure Functions, günlükleri izlerken ve görüntülerken kullanılacak eşik düzeyini tanımlamanızı sağlar. Eşiği ayarlamak için logging.logLevel özelliğini host.json dosyasında kullanın. Bu özellik, tüm işlevlere uygulanan varsayılan düzeyi veya her işlev için bir eşik tanımlamanızı sağlar. Daha fazla bilgi edinmek için bkz. Azure Functions için izlemeyi yapılandırma.

Özel verileri izleme

Varsayılan olarak, Azure Functions çıktıyı izleme bilgisi olarak Application Insights'a yazar. Daha fazla denetim için Application Insights Node.js SDK'sını kullanarak Application Insights örneğine özel günlükler, ölçümler ve bağımlılıklar gönderebilirsiniz.

Not

Application Insights Node.js SDK'sı yöntemleri zaman içinde değişebilir. Burada gösterilen örneklerden küçük söz dizimi farklılıkları olabilir. En son API kullanımı örnekleri için Application Insights Node.js SDK belgelerine bakın.

Node.js v4 programlama modelinde dağıtılmış izleme için Application Insights SDK'sı @azure/functions-opentelemetry-instrumentation yerine paketi kullanabilirsiniz. Bu paket, Azure Functions için OpenTelemetry tabanlı otomatik izleme sağlar. Daha fazla bilgi için bakınız: Node.js için OpenTelemetry Azure Functions İzleme Araçları GitHub deposu.

const appInsights = require("applicationinsights");
appInsights.setup();
const client = appInsights.defaultClient;

module.exports = async function (context, request) {
  // Use this with 'tagOverrides' to correlate custom logs to the parent function invocation.
  var operationIdOverride = {
    "ai.operation.id": context.traceContext.traceparent,
  };

  client.trackEvent({
    name: "my custom event",
    tagOverrides: operationIdOverride,
    properties: { customProperty2: "custom property value" },
  });
  client.trackException({
    exception: new Error("handled exceptions can be logged with this method"),
    tagOverrides: operationIdOverride,
  });
  client.trackMetric({
    name: "custom metric",
    value: 3,
    tagOverrides: operationIdOverride,
  });
  client.trackTrace({
    message: "trace message",
    tagOverrides: operationIdOverride,
  });
  client.trackDependency({
    target: "http://dbname",
    name: "select customers proc",
    data: "SELECT * FROM Customers",
    duration: 231,
    resultCode: 0,
    success: true,
    dependencyTypeName: "ZSQL",
    tagOverrides: operationIdOverride,
  });
  client.trackRequest({
    name: "GET /customers",
    url: "http://myserver/customers",
    duration: 309,
    resultCode: 200,
    success: true,
    tagOverrides: operationIdOverride,
  });
};

tagOverrides parametresi, işlevin çağrı kimliğine operation_Id ayarlar. Bu ayar, belirli bir işlev çağrısı için otomatik olarak oluşturulan ve özel günlüklerin tümünü ilişkilendirmenizi sağlar.

HTTP tetikleyicileri

HTTP ve web kancası tetikleyicileri, HTTP iletilerini temsil etmek için istek ve yanıt nesnelerini kullanır.

HTTP ve webhook tetikleyicileri, HTTP iletilerini temsil etmek için HttpRequest ve HttpResponse nesnelerini kullanır. Sınıflar, Node.js'in paketini kullanarak getirme standardının bir alt kümesini temsil ederundici.

HTTP İsteği

İsteğe çeşitli yollarla erişilebilir:

  • İşlevinizin ikinci bağımsız değişkeni olarak:

    module.exports = async function (context, request) {
        context.log(`Http function processed request for url "${request.url}"`);
    

  • Özelliğinden context.req :

    module.exports = async function (context, request) {
        context.log(`Http function processed request for url "${context.req.url}"`);
    

  • Adlandırılmış giriş bağlamalarından: Bu seçenek, HTTP olmayan bağlamalarla aynı şekilde çalışır. içindeki function.json bağlama adı, üzerindeki anahtarla context.bindingsveya aşağıdaki örnekteki "request1" ile eşleşmelidir:

    {
      "name": "request1",
      "type": "httpTrigger",
      "direction": "in",
      "authLevel": "anonymous",
      "methods": ["get", "post"]
    }
    
    module.exports = async function (context, request) {
        context.log(`Http function processed request for url "${context.bindings.request1.url}"`);
    

HttpRequest nesnesi aşağıdaki özelliklere sahiptir:

Özellik Türü Açıklama
method string Bu işlevi çağırmak için kullanılan HTTP istek yöntemi.
url string İstek URL'si.
headers Record<string, string> HTTP isteği başlıkları. Bu nesne büyük/küçük harfe duyarlıdır. Bunun yerine, büyük/küçük harf duyarlılığı olmayan request.getHeader('header-name') kullanılması önerilir.
query Record<string, string> URL'den sorgu dizesi parametrelerinin anahtarları ve değerleri.
params Record<string, string> Rota parametre anahtarları ve değerleri.
user HttpRequestUser \| null İşlevler kimlik doğrulaması, SWA Kimlik Doğrulaması yoluyla veya böyle bir kullanıcı oturum açmamışsa "null" durumunda oturum açmış kullanıcıyı temsil eden nesne.
body Buffer \| string \| any Medya türü "application/octet-stream" veya "multipart/*" ise, body bir arabellek olur. Değer JSON ayrıştırma yapabilen bir dizeyse, body ayrıştırılan nesnedir. Aksi takdirde, body bir dizedir.
rawBody string Bir dize olarak gövde. Adı her ne kadar böyle olsa da, bu özellik bir arabellek döndürmez.
bufferBody Buffer Vücut bir tampon olarak.

İstek, HTTP ile tetiklenen bir işlev için işleyicinizin ilk bağımsız değişkeni olarak erişilebilir.

async (request, context) => {
    context.log(`Http function processed request for url "${request.url}"`);

HttpRequest nesnesi aşağıdaki özelliklere sahiptir:

Özellik Türü Açıklama
method string Bu işlevi çağırmak için kullanılan HTTP istek yöntemi.
url string İstek URL'si.
headers Headers HTTP isteği başlıkları.
query URLSearchParams URL'den sorgu dizesi parametrelerinin anahtarları ve değerleri.
params Record<string, string> Rota parametre anahtarları ve değerleri.
user HttpRequestUser \| null İşlevler kimlik doğrulaması, SWA Kimlik Doğrulaması yoluyla veya böyle bir kullanıcı oturum açmamışsa "null" durumunda oturum açmış kullanıcıyı temsil eden nesne.
body ReadableStream \| null Okunabilir bir akış olarak gövde.
bodyUsed boolean Gövdenin zaten okunup okunmadığını gösteren boole değeri.

bir isteğin veya yanıtın gövdesine erişmek için aşağıdaki yöntemler kullanılabilir:

Metot Dönüş Türü
arrayBuffer() Promise<ArrayBuffer>
blob() Promise<Blob>
formData() Promise<FormData>
json() Promise<unknown>
text() Promise<string>

Not

Gövde işlevleri yalnızca bir kez çalıştırılabilir. Sonraki çağrılar boş dizeler/ArrayBuffers ile çözülür.

HTTP Yanıtı

Yanıt çeşitli yollarla ayarlanabilir:

  • context.res Özelliğini ayarlayın:

    module.exports = async function (context, request) {
        context.res = { body: `Hello, world!` };
    

  • Yanıtı döndür: İşleviniz asenkron ise ve bağlama adını $return içinde function.json olarak belirlerseniz, yanıtı context üzerinde ayarlamak yerine doğrudan döndürebilirsiniz.

    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
    
    module.exports = async function (context, request) {
        return { body: `Hello, world!` };
    

  • Adlandırılmış çıkış bağlamasını ayarlayın: Bu seçenek, HTTP olmayan bağlamalar ile aynı şekilde çalışır. içindeki function.json bağlama adı, aşağıdaki örnekteki context.bindingsveya "response1" üzerindeki anahtarla eşleşmelidir:

    {
      "type": "http",
      "direction": "out",
      "name": "response1"
    }
    
    module.exports = async function (context, request) {
        context.bindings.response1 = { body: `Hello, world!` };
    

  • Çağrı context.res.send(): Bu seçenek kullanım dışıdır. Örtük olarak context.done() çağırır ve zaman uyumsuz bir işlevde kullanılamaz.

    module.exports = function (context, request) {
        context.res.send(`Hello, world!`);
    

Yanıtı ayarlarken yeni bir nesne oluşturursanız, bu nesne aşağıdaki özelliklere HttpResponseSimple sahip olan arabirimle eşleşmelidir:

Özellik Türü Açıklama
headers Record<string, string> (isteğe bağlı) HTTP yanıt üst bilgileri.
cookies Cookie[] (isteğe bağlı) HTTP yanıt çerezleri.
body any (isteğe bağlı) HTTP yanıt gövdesi.
statusCode number (isteğe bağlı) HTTP yanıt durum kodu. Ayarlanmadıysa, varsayılan olarak olur 200.
status number (isteğe bağlı) ile statusCodeaynıdır. statusCode ayarlanırsa bu özellik yoksayılır.

Nesnenin context.res üzerine yazmadan da değiştirebilirsiniz. Varsayılan context.res nesne, özelliklerine HttpResponseFull ek olarak aşağıdaki yöntemleri destekleyen arabirimini HttpResponseSimple kullanır:

Metot Açıklama
status() Durumu ayarlar.
setHeader() Üst bilgi alanı ayarla. NOT: res.set() ve res.header() de desteklenir ve aynı şeyi yapar.
getHeader() Üst bilgi alanı alma. NOT: res.get() ayrıca desteklenir ve aynı şeyi yapar.
removeHeader() Üst bilgiyi kaldırır.
type() "content-type" üst bilgisini ayarlar.
send() Bu yöntem kullanım dışıdır. Gövdeyi ayarlar ve senkronizasyon işlevinin bittiğini belirtmek için context.done() çağırır. NOT: res.end() ayrıca desteklenir ve aynı şeyi yapar.
sendStatus() Bu yöntem kullanım dışıdır. Durum kodunu ayarlar ve bir eşitleme işlevinin bittiğini belirtmek için context.done() çağırır.
json() Bu yöntem kullanım dışıdır. "content-type" öğesini "application/json" olarak ayarlar, gövdeyi ayarlar ve eşitleme işlevinin bittiğini belirtmek için çağırır context.done() .

Yanıt çeşitli yollarla ayarlanabilir:

  • türüne HttpResponseInitsahip basit bir arabirim olarak: Bu seçenek, yanıtları döndürmenin en kısa yoludur.

    return { body: `Hello, world!` };
    

Arabirim HttpResponseInit aşağıdaki özelliklere sahiptir:

Özellik Türü Açıklama
body BodyInit (isteğe bağlı) HTTP yanıt gövdesi , ArrayBuffer, AsyncIterable<Uint8Array>, Blob, , FormData, Iterable<Uint8Array>, NodeJS.ArrayBufferView, URLSearchParamsnullveya stringşeklindedir.
jsonBody any (isteğe bağlı) JSON serileştirilebilir HTTP Yanıt gövdesi. Ayarlanırsa, HttpResponseInit.body özellik bu özellik için yoksayılır.
status number (isteğe bağlı) HTTP yanıt durum kodu. Ayarlanmadıysa, varsayılan olarak olur 200.
headers HeadersInit (isteğe bağlı) HTTP yanıt üst bilgileri.
cookies Cookie[] (isteğe bağlı) HTTP yanıt çerezleri.
  • türüne HttpResponsesahip bir sınıf olarak: Bu seçenek, yanıtın üst bilgiler gibi çeşitli bölümlerini okumak ve değiştirmek için yardımcı yöntemler sağlar.

    const response = new HttpResponse({ body: `Hello, world!` });
    response.headers.set("content-type", "application/json");
    return response;
    

HttpResponse sınıfı, oluşturucusunun isteğe bağlı bağımsız değişkeni olarak HttpResponseInit kabul eder ve aşağıdaki özelliklere sahiptir:

Özellik Türü Açıklama
status number HTTP yanıt durum kodu.
headers Headers HTTP yanıt üst bilgileri.
cookies Cookie[] HTTP yanıt çerezleri.
body ReadableStream | null Okunabilir bir akış olarak gövde.
bodyUsed boolean Cesedin önceden okunup okunmadığını gösteren boole değeri.

HTTP akışları

HTTP akışları, büyük verileri işlemeyi, OpenAI yanıtlarını akışla aktarmayı, dinamik içerik sunup diğer temel HTTP senaryolarını desteklemeyi kolaylaştıran bir özelliktir. Node.js işlev uygulamanızdaki HTTP uç noktalarına istekleri ve yanıtları akışla göndermenizi sağlar. Uygulamanızın http üzerinden istemci ve sunucu arasında gerçek zamanlı değişim ve etkileşim gerektirdiği senaryolarda HTTP akışlarını kullanın. HTTP kullanırken uygulamalarınız için en iyi performansı ve güvenilirliği elde etmek için HTTP akışlarını da kullanabilirsiniz.

Önemli

HTTP akışları v3 modelinde desteklenmez. HTTP akış özelliğini kullanmak için v4 modeline yükseltin. v4 programlama modelindeki mevcut HttpRequest ve HttpResponse türleri, akış olarak da dahil olmak üzere ileti gövdesini işlemenin çeşitli yollarını zaten destekler.

Önkoşullar

Akışları etkinleştirme

İşlev uygulamanızda Azure ve yerel projelerinizde HTTP akışlarını etkinleştirmek için şu adımları kullanın:

  1. Büyük miktarlarda veri akışı yapmayı planlıyorsanız, Azure'da FUNCTIONS_REQUEST_BODY_SIZE_LIMIT ayarını değiştirin. İzin verilen varsayılan maksimum gövde boyutu 104857600 olup isteklerinizi yaklaşık 100 MB boyuta kadar sınırlar.

  2. Yerel geliştirme için FUNCTIONS_REQUEST_BODY_SIZE_LIMIT ögesini de local.settings.json dosyasına ekleyin.

  3. Ana alanınıza dahil edilen herhangi bir dosyaya aşağıdaki kodu uygulamanıza ekleyin.

    const { app } = require("@azure/functions");
    
    app.setup({ enableHttpStream: true });
    

Akış örnekleri

Bu örnekte, bir HTTP POST isteği aracılığıyla veri alan HTTP ile tetiklenen bir işlev gösterilir ve işlev bu verileri belirtilen bir çıkış dosyasına akışla aktarır:

const { app } = require('@azure/functions');
const { createWriteStream } = require('fs');
const { Writable } = require('stream');

app.http('httpTriggerStreamRequest', {
    methods: ['POST'],
    authLevel: 'anonymous',
    handler: async (request, context) => {
        const writeStream = createWriteStream('<output file path>');
        await request.body.pipeTo(Writable.toWeb(writeStream));

        return { body: 'Done!' };
    },
});

Bu örnekte, gelen HTTP GET isteklerine yanıt olarak dosyanın içeriğini akışla aktaran HTTP ile tetiklenen bir işlev gösterilmektedir:

const { app } = require('@azure/functions');
const { createReadStream } = require('fs');

app.http('httpTriggerStreamResponse', {
    methods: ['GET'],
    authLevel: 'anonymous',
    handler: async (request, context) => {
        const body = createReadStream('<input file path>');

        return { body };
    },
});

Akışları kullanan çalışmaya hazır bir örnek uygulama için GitHub üzerindeki bu örneğe göz atın.

Akışla ilgili dikkat edilmesi gerekenler

  • Akışlardan en yüksek avantajı elde etmek için kullanın request.body . Yine de her zaman gövdesini dizgi olarak döndüren request.text() gibi yöntemleri kullanmaya devam edebilirsiniz.

Kancalar

v3 modelinde hooklar desteklenmez. Kancaları kullanmak için v4 modeline yükseltin.

Azure Functions yaşam döngüsünün farklı noktalarında kod yürütmek için bir kanca kullanın. Hook'lar kaydedildikleri sırayla yürütülür ve uygulamanızın herhangi bir dosyasından kaydedilebilir. Şu anda iki hook (kanca) kapsamı vardır: "uygulama" düzeyi ve "çağırma" düzeyi.

Çağırma kancaları

Çağrı kancaları, her bir işlev çağrısında bir kez; ya bir kancadan preInvocation önce ya da bir kancada postInvocation sonra yürütülür. Kancanız varsayılan olarak tüm tetikleyici türleri için çalıştırılır, ancak türe göre de filtreleme yapabilirsiniz. Aşağıdaki örnekte bir çağırma kancasının nasıl kaydedildiği ve tetikleyici türüne göre nasıl filtreleneceği gösterilmektedir:

const { app } = require('@azure/functions');

app.hook.preInvocation((context) => {
    if (context.invocationContext.options.trigger.type === 'httpTrigger') {
        context.invocationContext.log(
            `preInvocation hook executed for http function ${context.invocationContext.functionName}`
        );
    }
});

app.hook.postInvocation((context) => {
    if (context.invocationContext.options.trigger.type === 'httpTrigger') {
        context.invocationContext.log(
            `postInvocation hook executed for http function ${context.invocationContext.functionName}`
        );
    }
});

Kanca işleyicisinin ilk bağımsız değişkeni, bu kanca türüne özgü bir bağlam nesnesidir.

PreInvocationContext nesnesi aşağıdaki özelliklere sahiptir:

Özellik Açıklama
inputs Çağrıya geçirilen bağımsız değişkenler.
functionHandler Çağırma için işlev işleyicisi. Bu değerdeki değişiklikler işlevin kendisini etkiler.
invocationContext çağırma bağlam nesnesi işleve geçirildi.
hookData Aynı kapsamdaki kancalar arasında veri depolamak ve paylaşmak için önerilen konum. Diğer hooks'ların verileriyle çakışmaması için benzersiz bir özellik adı kullanmalısınız.

PostInvocationContext nesnesi aşağıdaki özelliklere sahiptir:

Özellik Açıklama
inputs Çağrıya geçirilen bağımsız değişkenler.
result İşlevin sonucu. Bu değerdeki değişiklikler işlevin genel sonucunu etkiler.
error İşlev tarafından atılan hata veya hata yoksa null/undefined. Bu değerdeki değişiklikler işlevin genel sonucunu etkiler.
invocationContext çağırma bağlam nesnesi işleve geçirildi.
hookData Aynı kapsamdaki kancalar arasında veri depolamak ve paylaşmak için önerilen konum. Diğer hooks'ların verileriyle çakışmaması için benzersiz bir özellik adı kullanmalısınız.

Uygulama kancaları

Uygulama kancaları, uygulamanızın her bir örneği için, bir appStart kancasında başlatma sırasında veya bir appTerminate kancasında sonlandırma sırasında bir kez yürütülür. Uygulama sonlandırma kancalarının yürütülmesi sınırlı bir süreye sahiptir ve tüm senaryolarda yürütülemez.

Azure Functions çalışma zamanı şu anda çağrı dışında bağlam günlüğünü desteklemez. Uygulama düzeyi kancaları sırasında verileri günlüğe kaydetmek için Application Insights npm paketini kullanın.

Aşağıdaki örnek, uygulama kancalarını kaydeder.

const { app } = require('@azure/functions');

app.hook.appStart((context) => {
    // add your logic here
});

app.hook.appTerminate((context) => {
    // add your logic here
});

Kanca işleyicisinin ilk bağımsız değişkeni, bu kanca türüne özgü bir bağlam nesnesidir.

AppStartContext nesnesi aşağıdaki özelliklere sahiptir:

Özellik Açıklama
hookData Aynı kapsamdaki kancalar arasında veri depolamak ve paylaşmak için önerilen konum. Diğer hooks'ların verileriyle çakışmaması için benzersiz bir özellik adı kullanmalısınız.

AppTerminateContext nesnesi aşağıdaki özelliklere sahiptir:

Özellik Açıklama
hookData Aynı kapsamdaki kancalar arasında veri depolamak ve paylaşmak için önerilen konum. Diğer hooks'ların verileriyle çakışmaması için benzersiz bir özellik adı kullanmalısınız.

Ölçeklendirme ve eşzamanlılık

Varsayılan olarak, Azure Functions uygulamanızdaki yükü otomatik olarak izler ve gerektiğinde Node.js için daha fazla konak örneği oluşturur. Azure Functions, yerleşik (kullanıcı tarafından yapılandırılamaz) eşikleri kullanarak, QueueTrigger için, iletilerin yaşı ve kuyruk boyutu gibi farklı tetikleyici türlerine göre örneklerin ne zaman ekleneceğine karar verir. Daha fazla bilgi için bkz . Tüketim ve Premium planları nasıl çalışır?

Bu ölçeklendirme davranışı birçok Node.js uygulaması için yeterlidir. CPU'ya bağlı uygulamalar için birden çok dil çalışanı işlemi kullanarak performansı daha da geliştirebilirsiniz. FUNCTIONS_WORKER_PROCESS_COUNT uygulama ayarını kullanarak konak başına çalışan işlemlerinin sayısını varsayılan değer olan 1'den en fazla 10'a kadar artırabilirsiniz. Azure Functions sonra eş zamanlı işlev çağrılarını bu çalışanlara eşit olarak dağıtmaya çalışır. Bu davranış, YOĞUN CPU kullanan bir işlevin diğer işlevlerin çalışmasını engelleme olasılığını düşürür. Bu ayar, Azure Functions talebi karşılamak için uygulamanızın ölçeğini genişletirken oluşturduğu her konak için geçerlidir.

Uyarı

FUNCTIONS_WORKER_PROCESS_COUNT Ayarı dikkatli kullanın. Aynı örnekte çalışan birden çok işlem öngörülemeyen davranışlara yol açabilir ve işlev yükleme sürelerini artırabilir. Bu ayarı kullanırsanız, bir paket dosyasından çalıştırarak bu dezavantajları dengelemenizi kesinlikle öneririz.

Node.js sürümü

Herhangi bir işlevden günlüğe kaydederek process.version çalışma zamanının kullandığı geçerli sürümü görebilirsiniz. Her programlama modeli tarafından desteklenen Node.js sürümlerinin listesi için bkz supported versions .

Node sürümünü ayarlama

Node.js sürümünüzü yükseltme yönteminiz, işlev uygulamanızın çalıştığı işletim sistemine bağlıdır.

Windows üzerinde çalıştığında, Node.js sürümü WEBSITE_NODE_DEFAULT_VERSION uygulama ayarı tarafından ayarlanır. Bu ayar, Azure CLI veya Azure portalı kullanılarak güncelleştirilebilir.

Node.js sürümleri hakkında daha fazla bilgi için bkz . Desteklenen sürümler.

Node.js sürümünüzü yükseltmeden önce işlev uygulamanızın Azure Functions çalışma zamanının en son sürümünde çalıştığından emin olun. Çalışma zamanı sürümünüzü yükseltmeniz gerekiyorsa bkz. 3.x Azure Functions sürümden 4.x sürümüne uygulamaları dağıtma.

Windows üzerinde çalışan işlev uygulamanızın Node.js sürümünü güncelleştirmek için Azure CLI az functionapp config appsettings set komutunu çalıştırın:

az functionapp config appsettings set  --settings WEBSITE_NODE_DEFAULT_VERSION=~22 \
 --name <FUNCTION_APP_NAME> --resource-group <RESOURCE_GROUP_NAME>

Bu, uygulama ayarını, WEBSITE_NODE_DEFAULT_VERSION

Değişiklikler yapıldıktan sonra işlev uygulamanız yeniden başlatılır. Node.js için İşlev desteği hakkında daha fazla bilgi edinmek için bkz . Dil çalışma zamanı destek ilkesi.

Ortam değişkenleri

Ortam değişkenleri işletimsel gizli diziler (bağlantı dizesi, anahtarlar, uç noktalar vb.) veya profil oluşturma değişkenleri gibi ortam ayarları için yararlı olabilir. Hem yerel hem de bulut ortamlarınıza ortam değişkenleri ekleyebilir ve bunlara işlev kodunuzdan process.env erişebilirsiniz.

Aşağıdaki örnek WEBSITE_SITE_NAME ortam değişkenini günlüğe kaydeder.

module.exports = async function (context) {
  context.log(`WEBSITE_SITE_NAME: ${process.env["WEBSITE_SITE_NAME"]}`);
};
async function timerTrigger1(myTimer, context) {
  context.log(`WEBSITE_SITE_NAME: ${process.env["WEBSITE_SITE_NAME"]}`);
}

Yerel geliştirme ortamında

Yerel olarak çalıştırdığınızda, işlev projeniz bir dosyasını içerir; bu dosyada, ortam değişkenlerinizi nesnesinde depolarsınız.

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "FUNCTIONS_WORKER_RUNTIME": "node",
    "CUSTOM_ENV_VAR_1": "hello",
    "CUSTOM_ENV_VAR_2": "world"
  }
}

Azure bulut ortamında

Azure çalıştırdığınızda işlev uygulaması hizmet bağlantı dizeleri gibi Application ayarlarını ayarlamanıza ve kullanmanıza olanak tanır ve yürütme sırasında bu ayarları ortam değişkenleri olarak kullanıma sunar.

İşlev uygulaması ayarlarını eklemenin, güncelleştirmenin ve silmenin birkaç yolu vardır:

İşlev uygulaması ayarlarında yapılan değişiklikler, işlev uygulamanızın yeniden başlatılmasını gerektirir.

Çalışan ortamı değişkenleri

Node.js özgü çeşitli İşlevler ortam değişkenleri vardır:

languageWorkersnode'un bağımsız değişkenleri

Bu ayar, Node.js işleminizi başlatırken özel bağımsız değişkenler belirtmenize olanak tanır. Çoğunlukla çalışanı hata ayıklama modunda başlatmak için yerel olarak kullanılır, ancak özel bağımsız değişkenlere ihtiyacınız varsa Azure'da da kullanılabilir.

Uyarı

Mümkünse, Azure languageWorkers__node__arguments kullanmaktan kaçının çünkü soğuk başlangıç zamanlarında olumsuz bir etkisi olabilir. Önceden hazır çalışan kullanmak yerine, çalışma zamanının özel bağımsız değişkenlerinizle sıfırdan yeni bir çalışan başlatması gerekir.

logLevel Worker günlüğekaydetme

Bu ayar, Node.js özgü çalışan günlükleri için varsayılan günlük düzeyini ayarlar. Varsayılan olarak, yalnızca uyarı veya hata günlükleri gösterilir, ancak Node.js çalışanıyla ilgili sorunları tanılamaya yardımcı olmak için günlük seviyesini information veya debug olarak ayarlayabilirsiniz. Daha fazla bilgi için, günlük düzeylerini yapılandırma konusuna bakın.

ECMAScript modülleri (önizleme)

Not

ECMAScript modülleri şu anda Node.js 14 veya daha yüksek sürümlerde Azure Functions'da bir önizleme özelliği olarak bulunmaktadır.

ECMAScript modülleri (ES modülleri), Node.js için yeni resmi standart modül sistemidir. Şimdiye kadar, bu makaledeki kod örnekleri CommonJS söz dizimini kullanır. Node.js 14 veya üzeri bir sürümde Azure Functions çalıştırırken, ES modülleri söz dizimini kullanarak işlevlerinizi yazmayı seçebilirsiniz.

ES modüllerini bir işlevde kullanmak için dosya adını uzantı kullanacak şekilde .mjs değiştirin. Aşağıdaki index.mjs dosya örneği, kitaplığı içeri aktarmak ve bir değer döndürmek için ES modülleri söz dizimini uuid kullanan HTTP ile tetiklenen bir işlevdir.

import { v4 as uuidv4 } from "uuid";

async function httpTrigger1(context, request) {
  context.res.body = uuidv4();
}

export default httpTrigger;
import { v4 as uuidv4 } from "uuid";

async function httpTrigger1(request, context) {
  return { body: uuidv4() };
}

app.http("httpTrigger1", {
  methods: ["GET", "POST"],
  handler: httpTrigger1,
});

İşlev giriş noktasını yapılandırma

function.json ve özellikleri scriptFileentryPoint, dışarı aktarılan işlevinizin konumunu ve adını yapılandırmak için kullanılabilir. scriptFile TypeScript kullanırken özelliği gereklidir ve derlenmiş JavaScript'e işaret etmelidir.

scriptFile’ı kullanma

Varsayılan olarak, bir JavaScript işlevi, karşılık gelen index.jsile aynı üst dizini paylaşan bir dosyasından yürütülürfunction.json.

scriptFile aşağıdaki örneğe benzer bir klasör yapısı almak için kullanılabilir:

<project_root>/
 | - node_modules/
 | - myFirstFunction/
 | | - function.json
 | - lib/
 | | - sayHello.js
 | - host.json
 | - package.json

function.json içinmyFirstFunction, çalıştırılacak dışarı aktarılan işlevi içeren dosyaya işaret eden bir scriptFile özellik içermelidir.

{
  "scriptFile": "../lib/sayHello.js",
  "bindings": [
    ...
  ]
}

entryPoint’ı kullanma

v3 modelinde, bir işlevin bulunup çalıştırılabilmesi için kullanılarak module.exports dışarı aktarılması gerekir. Varsayılan olarak, tetiklendiğinde yürütülen işlev bu dosyadan ya tek dışa aktarımdır, ya run adlı bir dışa aktarımdır, ya da index adlı bir dışa aktarımdır. Aşağıdaki örnek, entryPoint, function.json içinde özel bir değer olan "logHello" olarak ayarlar:

{
  "entryPoint": "logHello",
  "bindings": [
    ...
  ]
}
async function logHello(context) {
  context.log("Hello, world!");
}

module.exports = { logHello };

Yerel hata ayıklama

Yerel hata ayıklama için VS Code kullanmanızı öneririz. Bu, Node.js işleminizi otomatik olarak hata ayıklama modunda başlatır ve sizin için işleme bağlanır. Daha fazla bilgi için bkz fonksiyonu yerel olarak çalıştırma.

Farklı bir araç kullanıyorsanız veya Node.js sürecinizi hata ayıklama modunda manuel olarak başlatmak istiyorsanız, "languageWorkers__node__arguments": "--inspect" altına Values ekleyinlocal.settings.json. --inspect bağımsız değişkeni, Node.js varsayılan olarak 9229 numaralı bağlantı noktasında hata ayıklama istemcisini dinlemesini söyler. Daha fazla bilgi için Node.js hata ayıklama kılavuzuna bakın.

Öneriler

Bu bölümde, izlemenizi önerdiğimiz Node.js uygulamalar için çeşitli etkili desenler açıklanmaktadır.

Tek vCPU App Service planlarını seçin

App Service planını kullanan bir işlev uygulaması oluşturduğunuzda, birden çok vCPU içeren bir plan yerine tek vCPU planı seçmenizi öneririz. Bugün İşlevler, tek vCPU VM'lerde Node.js işlevleri daha verimli bir şekilde çalıştırır ve daha büyük VM'leri kullanmak beklenen performans iyileştirmelerini üretmez. Gerektiğinde, daha fazla tek vCPU VM örneği ekleyerek ölçeği el ile genişletebilir veya otomatik ölçeklendirmeyi etkinleştirebilirsiniz. Daha fazla bilgi için bkz . Örnek sayısını el ile veya otomatik olarak ölçeklendirme.

Paket dosyasından çalıştırma

Sunucusuz barındırma modelinde Azure Functions geliştirdiğinizde soğuk başlatmalar kaçınılmazdır. Soğuk başlangıç , işlev uygulamanızın bir süre etkinlik dışı kalma süresinden sonra ilk kez başlatılmasını ve başlatılmasının daha uzun sürmesini ifade eder. Özellikle büyük bağımlılık ağaçları olan Node.js uygulamalar için soğuk başlangıç önemli olabilir. Soğuk başlatma işlemini hızlandırmak için mümkün olduğunda işlevlerinizi paket dosyası olarak çalıştırın. Birçok dağıtım yöntemi varsayılan olarak bu modeli kullanır, ancak büyük soğuk başlangıçlarla karşılaşıyorsanız, bu şekilde çalıştığınızdan emin olmak için kontrol etmeniz gerekir.

Tek bir statik istemci kullanma

Azure Functions uygulamasında hizmete özgü bir istemci kullandığınızda, bağlantı sınırlarına takılabileceğiniz için her işlev çağrısında yeni bir istemci oluşturmayın. Bunun yerine, genel kapsamda tek bir statik istemci oluşturun. Daha fazla bilgi için bkz. Azure Functions de bağlantıları yönetme.

async ve await kullanın

Node.js'da Azure Functions yazarken async ve await anahtar sözcüklerini kullanarak kod yazmanız gerekir. async ve await kullanarak kod yazmak, geri çağırmalar veya Promise'ler ile .then ve .catch kullanmaktan iki yaygın sorundan kaçınmaya yardımcı olur.

  • Node.js işlemini çökertebilecek, diğer işlevlerin çalışmasını etkileyebilecek şekilde yakalanmamış özel durumlar oluşturma.
  • Beklenmeyen davranışlar, düzgün şekilde beklenmeyen zaman uyumsuz çağrıların neden olduğu context.log eksik günlükler gibi.

Aşağıdaki örnekte, zaman uyumsuz yöntem fs.readFile ikinci parametresi olarak hata öncelikli geri çağırma işleviyle çağrılır. Bu kod, daha önce bahsedilen sorunların her ikisine de neden olur. Doğru kapsamda açıkça yakalanmamış bir özel durum tüm işlemi çökebilir (sorun #1). Geri çağırmanın tamamlandığından emin olmadan geri dönmek, http yanıtının bazen boş bir gövdesi olduğu anlamına gelir (sorun #2).

// DO NOT USE THIS CODE
const { app } = require('@azure/functions');
const fs = require('fs');

app.http('httpTriggerBadAsync', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    handler: async (request, context) => {
        let fileData;
        fs.readFile('./helloWorld.txt', (err, data) => {
            if (err) {
                context.error(err);
                // BUG #1: This will result in an uncaught exception that crashes the entire process
                throw err;
            }
            fileData = data;
        });
        // BUG #2: fileData is not guaranteed to be set before the invocation ends
        return { body: fileData };
    },
});

Aşağıdaki örnekte, zaman uyumsuz yöntem fs.readFile ikinci parametresi olarak hata öncelikli geri çağırma işleviyle çağrılır. Bu kod, daha önce bahsedilen sorunların her ikisine de neden olur. Doğru kapsamda açıkça yakalanmamış bir özel durum tüm işlemi çökebilir (sorun #1). Geri çağırma kapsamı dışında kullanım dışı yöntemini context.done() çağırmak, dosya okunmadan önce işlevin tamamlandığına işaret edebilir (sorun #2). Bu örnekte, context.done()'nün çok erken çağrılması, Data from file: ile başlayan günlük girdilerinin eksik olmasına neden olur.

// NOT RECOMMENDED PATTERN
const fs = require("fs");

module.exports = function (context) {
  fs.readFile("./hello.txt", (err, data) => {
    if (err) {
      context.log.error("ERROR", err);
      // BUG #1: This will result in an uncaught exception that crashes the entire process
      throw err;
    }
    context.log(`Data from file: ${data}`);
    // context.done() should be called here
  });
  // BUG #2: Data is not guaranteed to be read before the Azure Function's invocation ends
  context.done();
};

async ve await anahtar sözcüklerini bu sorunların her ikisini de önlemeye yardımcı olması için kullanın. Node.js ekosistemindeki çoğu API, bir biçimde destek vaatlerine dönüştürülmüştür. Örneğin, v14 ile birlikte Node.js, geri çağırma API'si yerine bir fs/promises API'si sağlar.

Aşağıdaki örnekte, işlev yürütmesi sırasında oluşturulan işlenmeyen özel durumlar yalnızca özel durumu tetikleyen tek tek çağrıda başarısız olur. anahtar sözcüğü, await izleyen readFile adımların yalnızca tamamlandıktan sonra yürütülmesi anlamına gelir.

// Recommended pattern
const { app } = require('@azure/functions');
const fs = require('fs/promises');

app.http('httpTriggerGoodAsync', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    handler: async (request, context) => {
        try {
            const fileData = await fs.readFile('./helloWorld.txt');
            return { body: fileData };
        } catch (err) {
            context.error(err);
            // This rethrown exception will only fail the individual invocation, instead of crashing the whole process
            throw err;
        }
    },
});

async ve await ile, context.done() geri çağırmayı da çağırmanız gerekmez.

// Recommended pattern
const fs = require("fs/promises");

module.exports = async function (context) {
  let data;
  try {
    data = await fs.readFile("./hello.txt");
  } catch (err) {
    context.log.error("ERROR", err);
    // This rethrown exception will be handled by the Functions Runtime and will only fail the individual invocation
    throw err;
  }
  context.log(`Data from file: ${data}`);
};

Sorun giderme

Node.js Sorun Giderme kılavuzuna bakın.

Sonraki adımlar

Daha fazla bilgi edinmek için aşağıdaki kaynaklara bakın: