مشغّل HTTP الخاص بدالات Azure

يتيح لك مشغّل HTTP استدعاء دالة من خلال طلب HTTP. يمكنك استخدام مشغّل HTTP لإنشاء واجهات برمجة التطبيقات بلا خادم والاستجابة إلى الإخطارات على الويب.

القيمة المرجعة الافتراضية لدالة مشغّل HTTP هي:

  • HTTP 204 No Content مع وجود نص فارغ في دالات 2.x وأعلى
  • HTTP 200 OK مع وجود نص فارغ في دالات 1.x

لتعديل استجابة HTTP، قم بتكوين ربط المخرجات.

لمزيد من المعلومات حول روابط HTTP، راجع نظرة عامة ومرجع ربط المخرجات.

تلميح

إذا كنت تخطط لاستخدام روابط HTTP أو WebHook، فخطط لتجنب استنفاد المنفذ الذي قد ينتج عن إنشاء مثيل غير صحيح لـ HttpClient. لمزيد من المعلومات، راجع كيفية إدارة الاتصالات في وظائف Azure.

هام

تستخدم هذه المقالة علامات التبويب لدعم إصدارات متعددة من نموذج البرمجة Node.js. يتوفر نموذج v4 بشكل عام وتم تصميمه للحصول على تجربة أكثر مرونة وبديهية لمطوري JavaScript وTypeScript. لمزيد من التفاصيل حول كيفية عمل نموذج v4، راجع دليل مطور Azure Functions Node.js. لمعرفة المزيد حول الاختلافات بين v3 وv4، راجع دليل الترحيل.

تدعم Azure Functions نموذجي برمجة ل Python. تعتمد الطريقة التي تحدد بها روابطك على نموذج البرمجة الذي اخترته.

يتيح لك نموذج برمجة Python v2 تحديد الروابط باستخدام المحسنات مباشرة في التعليمات البرمجية لدالة Python. لمزيد من المعلومات، راجع دليل مطور Python.

تدعم هذه المقالة كلا نموذجي البرمجة.

مثال

يمكن إنشاء دالة C# باستخدام أحد أوضاع C# التالية:

  • نموذج العامل المعزول: دالة C# المترجمة التي يتم تشغيلها في عملية عامل معزولة عن وقت التشغيل. عملية العامل المعزولة مطلوبة لدعم وظائف C# التي تعمل على إصدارات LTS وغير LTS .NET و.NET Framework. تستخدم Microsoft.Azure.Functions.Worker.Extensions.* ملحقات دالات عملية العامل المعزولة مساحات الأسماء.
  • نموذج قيد المعالجة: دالة C# المحولة برمجيا التي تعمل في نفس العملية مثل وقت تشغيل الوظائف. في تباين هذا النموذج، يمكن تشغيل الدالات باستخدام البرمجة النصية C#، والتي يتم دعمها بشكل أساسي لتحرير مدخل C#. تستخدم Microsoft.Azure.WebJobs.Extensions.* ملحقات الوظائف قيد المعالجة مساحات الأسماء.

هام

سينتهي الدعم للنموذج قيد التنفيذ في 10 نوفمبر 2026. نوصي بشدة بترحيل تطبيقاتك إلى نموذج العامل المعزول للحصول على الدعم الكامل.

تعيين التعليمات البرمجية في هذه المقالة افتراضيًا إلى بناء الجملة ‎.NET Core المستخدم في الإصدار 2.x وأعلى من الدالات. للحصول على معلومات حول بناء الجملة 1.x، راجع قوالب الدالات 1.x.

يوضح المثال التالي مشغل HTTP الذي يقوم بإرجاع استجابة "hello, world" ك IActionResult، باستخدام تكامل ASP.NET Core في .NET Isolated:

[Function("HttpFunction")]
public IActionResult Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req)
{
    return new OkObjectResult($"Welcome to Azure Functions, {req.Query["name"]}!");
}

يوضح المثال التالي مشغل HTTP الذي يعرض استجابة "hello world" كعنصر HttpResponseData :

[Function(nameof(HttpFunction))]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequestData req,
    FunctionContext executionContext)
{
    var logger = executionContext.GetLogger(nameof(HttpFunction));
    logger.LogInformation("message logged");

    var response = req.CreateResponse(HttpStatusCode.OK);
    response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
    response.WriteString("Welcome to .NET isolated worker !!");

    return response;
}

يحتوي هذا القسم على الأمثلة التالية:

تُظهر الأمثلة التالية ربط مشغل HTTP.

قراءة المعلمة من سلسلة الاستعلام

يقرأ هذا المثال معلمة، تسمى id، من سلسلة الاستعلام، ويستخدمها لإنشاء مستند JSON تم إرجاعه إلى العميل، مع نوع المحتوى application/json.

@FunctionName("TriggerStringGet")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", 
            methods = {HttpMethod.GET}, 
            authLevel = AuthorizationLevel.ANONYMOUS)
        HttpRequestMessage<Optional<String>> request,
        final ExecutionContext context) {

    // Item list
    context.getLogger().info("GET parameters are: " + request.getQueryParameters());

    // Get named parameter
    String id = request.getQueryParameters().getOrDefault("id", "");

    // Convert and display
    if (id.isEmpty()) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                        .body("Document not found.")
                        .build();
    } 
    else {
        // return JSON from to the client
        // Generate document
        final String name = "fake_name";
        final String jsonDocument = "{\"id\":\"" + id + "\", " + 
                                        "\"description\": \"" + name + "\"}";
        return request.createResponseBuilder(HttpStatus.OK)
                        .header("Content-Type", "application/json")
                        .body(jsonDocument)
                        .build();
    }
}

قراءة النص من طلب POST

يقرأ هذا المثال نص طلب POST، تسمى String، من سلسلة الاستعلام، ويستخدمها لإنشاء مستند JSON تم إرجاعه إلى العميل، مع نوع المحتوى application/json.

    @FunctionName("TriggerStringPost")
    public HttpResponseMessage run(
            @HttpTrigger(name = "req", 
              methods = {HttpMethod.POST}, 
              authLevel = AuthorizationLevel.ANONYMOUS)
            HttpRequestMessage<Optional<String>> request,
            final ExecutionContext context) {

        // Item list
        context.getLogger().info("Request body is: " + request.getBody().orElse(""));

        // Check request body
        if (!request.getBody().isPresent()) {
            return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                          .body("Document not found.")
                          .build();
        } 
        else {
            // return JSON from to the client
            // Generate document
            final String body = request.getBody().get();
            final String jsonDocument = "{\"id\":\"123456\", " + 
                                         "\"description\": \"" + body + "\"}";
            return request.createResponseBuilder(HttpStatus.OK)
                          .header("Content-Type", "application/json")
                          .body(jsonDocument)
                          .build();
        }
    }

قراءة المعلمة من مسار

يقرأ هذا المثال معلمة إلزامية، تسمى id، و معلمة اختيارية name من المسار، ويستخدمها لإنشاء مستند JSON تم إرجاعه إلى العميل، مع نوع المحتوى application/json.

@FunctionName("TriggerStringRoute")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", 
            methods = {HttpMethod.GET}, 
            authLevel = AuthorizationLevel.ANONYMOUS,
            route = "trigger/{id}/{name=EMPTY}") // name is optional and defaults to EMPTY
        HttpRequestMessage<Optional<String>> request,
        @BindingName("id") String id,
        @BindingName("name") String name,
        final ExecutionContext context) {

    // Item list
    context.getLogger().info("Route parameters are: " + id);

    // Convert and display
    if (id == null) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                        .body("Document not found.")
                        .build();
    } 
    else {
        // return JSON from to the client
        // Generate document
        final String jsonDocument = "{\"id\":\"" + id + "\", " + 
                                        "\"description\": \"" + name + "\"}";
        return request.createResponseBuilder(HttpStatus.OK)
                        .header("Content-Type", "application/json")
                        .body(jsonDocument)
                        .build();
    }
}

قراءة نص POJO من طلب POST

فيما يلي التعليمة البرمجية للفئة ToDoItem، المشار إليها في هذا المثال:


public class ToDoItem {

  private String id;
  private String description;  

  public ToDoItem(String id, String description) {
    this.id = id;
    this.description = description;
  }

  public String getId() {
    return id;
  }

  public String getDescription() {
    return description;
  }

  @Override
  public String toString() {
    return "ToDoItem={id=" + id + ",description=" + description + "}";
  }
}

يقرأ هذا المثال نص طلب POST. يتم إلغاء تسلسل نص الطلب تلقائيًا في الكائن ToDoItem، ويتم إرجاعه إلى العميل، مع نوع المحتوى application/json. يتم تسلسل المعلمة ToDoItem بواسطة وقت تشغيل الدالات كما يتم تعيينها إلى الخاصية body للفئة HttpMessageResponse.Builder.

@FunctionName("TriggerPojoPost")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", 
            methods = {HttpMethod.POST}, 
            authLevel = AuthorizationLevel.ANONYMOUS)
        HttpRequestMessage<Optional<ToDoItem>> request,
        final ExecutionContext context) {

    // Item list
    context.getLogger().info("Request body is: " + request.getBody().orElse(null));

    // Check request body
    if (!request.getBody().isPresent()) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                        .body("Document not found.")
                        .build();
    } 
    else {
        // return JSON from to the client
        // Generate document
        final ToDoItem body = request.getBody().get();
        return request.createResponseBuilder(HttpStatus.OK)
                        .header("Content-Type", "application/json")
                        .body(body)
                        .build();
    }
}

يوضح المثال التالي دالة TypeScript لمشغل HTTP. تبحث الدالة عن معلمة name إما في سلسلة الاستعلام أو نص طلب HTTP.

import { app, HttpRequest, HttpResponseInit, InvocationContext } from '@azure/functions';

export async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    context.log(`Http function processed request for url "${request.url}"`);

    const name = request.query.get('name') || (await request.text()) || 'world';

    return { body: `Hello, ${name}!` };
}

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

يوضح المثال التالي دالة JavaScript لمشغل HTTP. تبحث الدالة عن معلمة name إما في سلسلة الاستعلام أو نص طلب HTTP.

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

app.http('httpTrigger1', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    handler: async (request, context) => {
        context.log(`Http function processed request for url "${request.url}"`);

        const name = request.query.get('name') || (await request.text()) || 'world';

        return { body: `Hello, ${name}!` };
    },
});

يُظهر المثال التالي ربط مشغل في ملف function.js ودالة PowerShell. تبحث الدالة عن معلمة name إما في سلسلة الاستعلام أو نص طلب HTTP.

{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "Request",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "Response"
    }
  ]
}
using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters or the body of the request.
$name = $Request.Query.Name
if (-not $name) {
    $name = $Request.Body.Name
}

$body = "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."

if ($name) {
    $body = "Hello, $name. This HTTP triggered function executed successfully."
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body       = $body
})

يوضح المثال التالي ربط المشغل ودالة Python التي تستخدم الربط. تبحث الدالة عن معلمة name إما في سلسلة الاستعلام أو نص طلب HTTP. يعتمد المثال على ما إذا كنت تستخدم نموذج برمجة v1 أو v2 Python.

import azure.functions as func
import logging

app = func.FunctionApp()

@app.function_name(name="HttpTrigger1")
@app.route(route="hello", auth_level=func.AuthLevel.ANONYMOUS)
def test_function(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')
    return func.HttpResponse(
        "This HTTP triggered function executed successfully.",
        status_code=200
        )

السمات

تستخدم HttpTriggerAttribute كل من مكتبات العملية العملية وعملية العامل المعزولة C# لتعريف ربط المشغل. يستخدم البرنامج النصي C# بدلا من ذلك ملف تكوين function.json كما هو موضح في دليل البرمجة النصية C#‎.

في تطبيقات وظائف معالجة العامل المعزولة HttpTriggerAttribute ، يدعم المعلمات التالية:

المعلمات ‏‏الوصف
AuthLevel تحديد المفاتيح، إن وجدت، التي يجب أن تكون موجودة عند الطلب لاستدعاء الدالة. للحصول على القيم المدعومة، راجع مستوى التخويل.
اساليب صفيف من طرق HTTP التي تستجيب لها الوظيفة. في حالة عدم التحديد، تستجيب الدالة لكافة أساليب HTTP. راجع تخصيص نقطة نهاية HTTP.
المسار تحديد قالب المسار، الذي يتحكم في عناوين URLs للطلب التي تستجيب الدالة الخاص بك إليها. القيمة الافتراضية إذا لم يتم توفير أي شيء هي <functionname>. لمزيد من المعلومات، راجع تخصيص نقطة نهاية HTTP.

الديكور

ينطبق فقط على نموذج برمجة Python v2.

بالنسبة لوظائف Python v2 المعرفة باستخدام مصمم الديكور، يتم تعريف الخصائص التالية للمشغل في route مصمم الديكور، الذي يضيف ربط HttpTrigger وHttpOutput:

الخاصية ‏‏الوصف
route مسار نقطة نهاية http. إذا كان بلا، فسيتم تعيينه إلى اسم الدالة إذا كان موجودا أو اسم دالة python معرفا من قبل المستخدم.
trigger_arg_name اسم الوسيطة ل HttpRequest. القيمة الافتراضية هي "req".
binding_arg_name اسم الوسيطة ل HttpResponse. القيمة الافتراضية هي "$return".
methods مجموعة من أساليب HTTP التي تستجيب لها الدالة.
auth_level تحديد المفاتيح، إن وجدت، التي يجب أن تكون موجودة عند الطلب لاستدعاء الدالة.

للحصول على وظائف Python المعرفة باستخدام function.json، راجع قسم التكوين.

تعليقات توضيحية

في مكتبة وقت تشغيل وظائف Java، استخدم التعليق التوضيحي HttpTrigger، والذي يدعم الإعدادات التالية:

التكوين

ينطبق فقط على نموذج برمجة Python v1.

يوضح الجدول التالي الخصائص التي يمكنك تعيينها على الكائن الذي options تم تمريره app.http() إلى الأسلوب .

الخاصية ‏‏الوصف
authLevel تحديد المفاتيح، إن وجدت، التي يجب أن تكون موجودة عند الطلب لاستدعاء الدالة. للحصول على القيم المدعومة، راجع مستوى التخويل.
الأساليب صفيف من طرق HTTP التي تستجيب لها الوظيفة. في حالة عدم التحديد، تستجيب الدالة لكافة أساليب HTTP. راجع تخصيص نقطة نهاية HTTP.
المسار تحديد قالب المسار، الذي يتحكم في عناوين URLs للطلب التي تستجيب الدالة الخاص بك إليها. القيمة الافتراضية إذا لم يتم توفير أي شيء هي <functionname>. لمزيد من المعلومات، راجع تخصيص نقطة نهاية HTTP.

يوضح الجدول التالي خصائص تكوين المشغل التي قمت بتعيينها في ملف function.json، والذي يختلف باختلاف إصدار وقت التشغيل.

يشرح الجدول الآتي خصائص تكوين ربط البيانات التي عليك تعيينها في ملف function.json.

خاصية function.json ‏‏الوصف
النوع مطلوب - يجب تعيينه إلى httpTrigger.
الاتجاه مطلوب - يجب تعيينه إلى in.
الاسم مطلوب - اسم المتغير المستخدم في التعليمات البرمجية للدالة للطلب أو نص الطلب.
authLevel تحديد المفاتيح، إن وجدت، التي يجب أن تكون موجودة عند الطلب لاستدعاء الدالة. للحصول على القيم المدعومة، راجع مستوى التخويل.
الأساليب صفيف من طرق HTTP التي تستجيب لها الوظيفة. في حالة عدم التحديد، تستجيب الدالة لكافة أساليب HTTP. راجع تخصيص نقطة نهاية HTTP.
المسار تحديد قالب المسار، الذي يتحكم في عناوين URLs للطلب التي تستجيب الدالة الخاص بك إليها. القيمة الافتراضية إذا لم يتم توفير أي شيء هي <functionname>. لمزيد من المعلومات، راجع تخصيص نقطة نهاية HTTP.

الاستخدام

يوضح هذا القسم بالتفصيل كيفية تكوين ربط وظيفة مشغل HTTP.

يجب تطبيق التعليق التوضيحي HttpTrigger على معلمة طريقة من أحد الأنواع التالية:

  • HttpRequestMessage<T>.
  • أي أنواع Java أصلية مثل int، String، byte [ ].
  • القيم التي تقبل البيانات الفارغة باستخدام اختياري.
  • أي نوع عنصر Java عادي (POJO).

الحمولة

يتم تعريف نوع إدخال المشغل كأحد الأنواع التالية:

النوع ‏‏الوصف
طلب Http يتطلب استخدام هذا النوع تكوين التطبيق مع تكامل ASP.NET Core في .NET Isolated.
يمنحك هذا حق الوصول الكامل إلى كائن الطلب وHttpContext الكلي.
بيانات طلب Http إسقاط لكائن الطلب.
نوع مخصص عندما يكون نص الطلب JSON، سيحاول وقت التشغيل تحليله لتعيين خصائص الكائن.

عندما تكون معلمة المشغل عبارة عن HttpRequestDataHttpRequest، يمكن أيضا ربط الأنواع المخصصة بمعلمات إضافية باستخدام Microsoft.Azure.Functions.Worker.Http.FromBodyAttribute. يتطلب استخدام هذه السمة Microsoft.Azure.Functions.Worker.Extensions.Http الإصدار 3.1.0 أو أحدث. لاحظ أن هذا نوع مختلف عن السمة المماثلة في Microsoft.AspNetCore.Mvc، وعند استخدام تكامل ASP.NET Core، ستحتاج إلى مرجع أو using عبارة مؤهلة بالكامل. يوضح المثال التالي كيفية استخدام السمة للحصول على محتويات النص الأساسي فقط مع الاستمرار في الوصول إلى الكامل HttpRequest، باستخدام تكامل ASP.NET Core:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using FromBodyAttribute = Microsoft.Azure.Functions.Worker.Http.FromBodyAttribute;

namespace AspNetIntegration
{
    public class BodyBindingHttpTrigger
    {
        [Function(nameof(BodyBindingHttpTrigger))]
        public IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req,
            [FromBody] Person person)
        {
            return new OkObjectResult(person);
        }
    }

    public record Person(string Name, int Age);
}

تخصيص نقطة نهاية HTTP

بشكل افتراضي، عند إنشاء دالة مشغل HTTP، تكون الدالة قابلة للعنونة من خلال مسار النموذج:

https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>

يمكنك تخصيص هذا المسار باستخدام خاصية route الاختيارية على ربط الإدخال الخاص بمشغل HTTP. يمكنك استخدام أي قيد من قيود مسار واجهة برمجة تطبيقات الويب مع المعلمات الخاصة بك.

يقبل تعليمة برمجية الوظيفة التالي معلمتين category وid في المسار ويكتب استجابة باستخدام كلا المعلمتين.

[Function("HttpTrigger1")]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Function, "get", "post",
Route = "products/{category:alpha}/{id:int?}")] HttpRequestData req, string category, int? id,
FunctionContext executionContext)
{
    var logger = executionContext.GetLogger("HttpTrigger1");
    logger.LogInformation("C# HTTP trigger function processed a request.");

    var message = String.Format($"Category: {category}, ID: {id}");
    var response = req.CreateResponse(HttpStatusCode.OK);
    response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
    response.WriteString(message);

    return response;
}

يتم تحديد معلمات المسار باستخدام إعداد route للتعليق التوضيحي HttpTrigger. يقبل تعليمة برمجية الوظيفة التالي معلمتين category وid في المسار ويكتب استجابة باستخدام كلا المعلمتين.

package com.function;

import java.util.*;
import com.microsoft.azure.functions.annotation.*;
import com.microsoft.azure.functions.*;

public class HttpTriggerJava {
    public HttpResponseMessage<String> HttpTrigger(
            @HttpTrigger(name = "req",
                         methods = {"get"},
                         authLevel = AuthorizationLevel.FUNCTION,
                         route = "products/{category:alpha}/{id:int}") HttpRequestMessage<String> request,
            @BindingName("category") String category,
            @BindingName("id") int id,
            final ExecutionContext context) {

        String message = String.format("Category  %s, ID: %d", category, id);
        return request.createResponseBuilder(HttpStatus.OK).body(message).build();
    }
}

على سبيل المثال، تحدد التعليمات route البرمجية TypeScript التالية خاصية لمشغل HTTP بمعلمتين و categoryid. يقرأ المثال المعلمات من الطلب ويعيد قيمها في الاستجابة.

import { app, HttpRequest, HttpResponseInit, InvocationContext } from '@azure/functions';

export async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    const category = request.params.category;
    const id = request.params.id;

    return { body: `Category: ${category}, ID: ${id}` };
}

app.http('httpTrigger1', {
    methods: ['GET'],
    authLevel: 'anonymous',
    route: 'products/{category:alpha}/{id:int?}',
    handler: httpTrigger1,
});

على سبيل المثال، تحدد التعليمات route البرمجية JavaScript التالية خاصية لمشغل HTTP بمعلمتين، category و id. يقرأ المثال المعلمات من الطلب ويعيد قيمها في الاستجابة.

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

app.http('httpTrigger1', {
    methods: ['GET'],
    authLevel: 'anonymous',
    route: 'products/{category:alpha}/{id:int?}',
    handler: async (request, context) => {
        const category = request.params.category;
        const id = request.params.id;

        return { body: `Category: ${category}, ID: ${id}` };
    },
});

على سبيل المثال، تحدد التعليمات route البرمجية التالية خاصية لمشغل HTTP بمعلمتين، category و id:

@app.function_name(name="httpTrigger")
@app.route(route="products/{category:alpha}/{id:int?}")

يمكن الوصول إلى معلمات المسار التي يتم الإعلان عنها في ملف function.json كخاصية للكائن $Request.Params.

$Category = $Request.Params.category
$Id = $Request.Params.id

$Message = "Category:" + $Category + ", ID: " + $Id

Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body = $Message
})

يتم عرض سياق تنفيذ الدالة عبر معلمة تم الإعلان عنها باسم func.HttpRequest. يسمح هذا المثيل للدالة بالوصول إلى معلمات مسار البيانات وقيم سلسلة الاستعلام والأساليب التي تسمح لك بإرجاع استجابات HTTP.

بمجرد تعريفها، تتوفر معلمات المسار للدالة عن طريق استدعاء الأسلوب route_params.

import logging

import azure.functions as func

def main(req: func.HttpRequest) -> func.HttpResponse:

    category = req.route_params.get('category')
    id = req.route_params.get('id')
    message = f"Category: {category}, ID: {id}"

    return func.HttpResponse(message)

باستخدام هذا التكوين، تكون الدالة الآن قابلة للعنونة من خلال المسار التالي بدلاً من المسار الأصلي.

https://<APP_NAME>.azurewebsites.net/api/products/electronics/357

يسمح هذا التكوين للتعليمات البرمجية للدالة بدعم معلمتين في العنوان والفئة والمعرف. لمزيد من المعلومات حول كيفية ترميز معلمات المسار في عنوان URL، راجع التوجيه في ASP.NET Core.

بشكل افتراضي، يتم بدء كافة مسارات الدالة من خلال api. يمكنك أيضًا تخصيص أو إزالة البادئة باستخدام الخاصية extensions.http.routePrefix في ملف host.js. يقوم المثال التالي بإزالة بادئة مسار api باستخدام سلسلة فارغة للبادئة في ملف host.js.

{
    "extensions": {
        "http": {
            "routePrefix": ""
        }
    }
}

استخدام معلمات المسار

معلمات المسار التي حددت نمط دالة route متوفرة لكل ربط. على سبيل المثال، إذا كان لديك مسار محدد باسم "route": "products/{id}" فإنه يمكن لربط تخزين جدول استخدام قيمة المعلمة {id} في تكوين الربط.

يُظهر التكوين التالي كيفية تمرير المعلمة {id} إلى rowKey الخاص بالربط.

@app.table_input(arg_name="product", table_name="products", 
                 row_key="{id}", partition_key="products",
                 connection="AzureWebJobsStorage")
import { app, HttpRequest, HttpResponseInit, input, InvocationContext } from '@azure/functions';

const tableInput = input.table({
    connection: 'MyStorageConnectionAppSetting',
    partitionKey: 'products',
    tableName: 'products',
    rowKey: '{id}',
});

export async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    return { jsonBody: context.extraInputs.get(tableInput) };
}

app.http('httpTrigger1', {
    methods: ['GET'],
    authLevel: 'anonymous',
    route: 'products/{id}',
    extraInputs: [tableInput],
    handler: httpTrigger1,
});
const { app, input } = require('@azure/functions');

const tableInput = input.table({
    connection: 'MyStorageConnectionAppSetting',
    partitionKey: 'products',
    tableName: 'products',
    rowKey: '{id}',
});

app.http('httpTrigger1', {
    methods: ['GET'],
    authLevel: 'anonymous',
    route: 'products/{id}',
    extraInputs: [tableInput],
    handler: async (request, context) => {
        return { jsonBody: context.extraInputs.get(tableInput) };
    },
});
{
    "type": "table",
    "direction": "in",
    "name": "product",
    "partitionKey": "products",
    "tableName": "products",
    "rowKey": "{id}"
}

عند استخدام معلمات المسار، يتم إنشاء invoke_URL_template تلقائيًا للدالة الخاصة بك. يمكن للعملاء لديك استخدام قالب عنوان URL لفهم المعلمات التي يحتاجون إلى تمريرها في عنوان URL عند استدعاء الدالة باستخدام عنوان URL الخاص بها. انتقل إلى إحدى الدالات التي تم تشغيلها في HTTP في مدخل Azure وحدد الحصول على عنوان URL للدالة.

يمكنك الوصول برمجيًا إلى invoke_URL_template باستخدام واجهات برمجة تطبيقات Azure Resource Manager لدالات القائمة أو الحصول على دالة.

تدفقات HTTP (معاينة)

يمكنك الآن دفق الطلبات والاستجابات من نقطة نهاية HTTP في تطبيقات وظائف Node.js v4. لمزيد من المعلومات، راجع تدفقات HTTP.

العمل مع هويات العميل

إذا كان تطبيق الدالة يستخدم مصادقة / تخويل خدمة التطبيق، يمكنك عرض معلومات حول العملاء المصادق عليهم من التعليمات البرمجية الخاصة بك. تتوفر هذه المعلومات كعناوين للطلبات التي تم إدخالها بواسطة النظام الأساسي.

يمكنك أيضًا قراءة هذه المعلومات من بيانات الربط. تتوفر هذه الإمكانية فقط لوقت تشغيل الدالات في 2.x وأعلى. كما أنها متوفرة حاليًا فقط للغات ‎.NET.

تتوفر المعلومات المتعلقة بالعملاء المصادق عليهم كـ ClaimsPrincipal، وهو متاح كجزء من سياق الطلب كما هو موضح في المثال التالي:

المستخدم المصادق عليه متوفر عبر عناوين HTTP.

المستخدم المصادق عليه متوفر عبر عناوين HTTP.

مستوى التخويل

مستوى التخويل هو قيمة سلسلة تشير إلى نوع مفتاح التخويل المطلوب للوصول إلى نقطة نهاية الوظيفة. بالنسبة لوظيفة يتم تشغيلها بواسطة HTTP، يمكن أن يكون مستوى التخويل إحدى القيم التالية:

قيمة المستوى ‏‏الوصف
مجهول لا يوجد مفتاح API مطلوب. هذه هي القيمة الافتراضية عندما لا يتم تعيين المستوى على وجه التحديد.
وظيفة مفتاح API الخاص بالدالة مطلوب.
مشرف المفتاح الرئيسي مطلوب.
قيمة المستوى ‏‏الوصف
مجهول لا يوجد مفتاح API مطلوب.
وظيفة مفتاح API الخاص بالدالة مطلوب. هذه هي القيمة الافتراضية عندما لا يتم تعيين المستوى على وجه التحديد.
مشرف المفتاح الرئيسي مطلوب.

مفاتيح الوصول إلى الدالة

تتيح لك الوظائف استخدام المفاتيح لزيادة صعوبة الوصول إلى نقاط نهاية وظيفة HTTP خلال التطوير. ما لم يتم تعيين مستوى وصول HTTP في وظيفة يتم تشغيلها بواسطة HTTP على anonymous، يجب أن تتضمن الطلبات مفتاح وصول API في الطلب.

بينما توفر المفاتيح آلية أمان افتراضية، قد تحتاج إلى النظر في خيارات أخرى لتأمين نقطة نهاية HTTP في الإنتاج. على سبيل المثال، ليس من الممارسات الجيدة توزيع البيانات السرية المشتركة في التطبيقات العامة. إذا تم استدعاء وظيفتك من عميل عام، فقد ترغب في التفكير في تنفيذ آلية أمان أخرى. لمعرفة المزيد، راجع تأمين نقطة نهاية HTTP في الإنتاج.

عندما تقوم بتجديد قيم مفاتيح الوظيفة، يجب عليك إعادة توزيع قيم المفاتيح المحدّثة يدوياً على جميع العملاء الذين يتصلون بوظيفتك.

نطاقات التخويل (مستوى الوظيفة)

يوجد نطاقي وصول لمفاتيح المستوى الوظيفي:

  • دالة: تنطبق هذه المفاتيح فقط على الوظائف المحددة التي يتم تعريفها بموجبها. عند استخدامها كمفتاح API، فإنها تسمح فقط بالوصول إلى هذه الوظيفة.

  • المضيف: يمكن استخدام المفاتيح ذات النطاق المضيف للوصول إلى جميع الوظائف داخل Function App. عند استخدامها كمفتاح API، فإنها تسمح بالوصول إلى أي وظيفة داخل Function App.

تتم تسمية كل مفتاح كمرجع، وهناك مفتاح افتراضي (يسمى "افتراضي") على مستوى الدالة والمضيف. مفاتيح الوظائف لها الأسبقية على مفاتيح المضيف. عندما يتم تعريف مفتاحين بنفس الاسم، يتم استخدام مفتاح الوظيفة دائماً.

المفتاح الرئيسي (على مستوى المسؤول)

يحتوي كل تطبيق وظيفي أيضاً على مفتاح مضيف على مستوى المسؤول يسمى _master. بالإضافة إلى توفير وصول على مستوى المضيف إلى جميع الوظائف في التطبيق، يوفر المفتاح الرئيسي أيضاً وصولاً إدارياً إلى وقت التشغيل REST APIs. لا يمكن إبطال هذا المفتاح. عند تعيين مستوى وصول لـ admin، يجب أن تستخدم الطلبات المفتاح الرئيسي؛ يؤدي أي مفتاح آخر إلى فشل الوصول.

تنبيه

نظرا للأذونات المرتفعة في تطبيق الوظائف الذي تم منحه بواسطة المفتاح الرئيسي، يجب عدم مشاركة هذا المفتاح مع جهات خارجية أو توزيعه في تطبيقات العميل الأصلية. توخ الحذر عند اختيار مستوى وصول المسؤول.

الحصول على المفاتيح

يتم تخزين المفاتيح كجزء من تطبيق الدالة في Azure ويتم تشفيرها في حالة الراحة. لعرض المفاتيح أو إنشاء مفاتيح جديدة أو نقل المفاتيح إلى قيم جديدة، انتقل إلى إحدى الدالات التي تم تشغيلها في HTTP في مدخل Azure وحدد مفاتيح الدالات.

يمكنك أيضًا إدارة مفاتيح المضيف. انتقل إلى تطبيق الدالة في مدخل Azure وحدد مفاتيح التطبيق.

يمكنك الحصول على مفاتيح الدالة والمضيف برمجيًا باستخدام واجهات برمجة تطبيقات Azure Resource Manager. هناك واجهات برمجة التطبيقات إلى مفاتيح دالة القائمة ومفاتيح مضيف القائمة، وعند استخدام فتحات النشر، تكون واجهات برمجة التطبيقات المكافئة هي فتحة مفاتيح دالة القائمة وفتحة مفاتيح مضيف القائمة.

يمكنك أيضًا إنشاء دالة جديدة ومفاتيح الدالة برمجيًا باستخدام واجهات برمجة التطبيقات إنشاء أو تحديث سر الدالة وإنشاء أو تحديث فتحة سر الدالة وإنشاء أو تحديث سر المضيف وإنشاء أو تحديث فتحة سر المضيف.

يمكن حذف مفاتيح الدالة والمضيف برمجيًا باستخدام واجهات برمجة التطبيقات حذف سر الدالة وحذف فتحة سر الدالة وحذف سر المضيف وحذف فتحة سر المضيف.

يمكنك أيضًا استخدام واجهات برمجة التطبيقات لإدارة المفاتيح القديمة للحصول على مفاتيح الدالة، ولكن يفضل استخدام واجهات برمجة تطبيقات Azure Resource Manager بدلاً من ذلك.

تخويل مفتاح API

تتطلب معظم قوالب مشغل HTTP مفتاح API في الطلب. لذا يبدو طلب HTTP الخاص بك عادة مثل عنوان URL التالي:

https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?code=<API_KEY>

يمكن تضمين المفتاح في متغير سلسلة استعلام مسمى code، كما هو مذكور أعلاه. ويمكن أيضًا تضمينه في عنوان HTTP x-functions-key. يمكن أن تكون قيمة المفتاح عبارة عن أي مفتاح دالة معرّف للدالة أو أي مفتاح مضيف.

يمكنك السماح بطلبات مجهولة المصدر، والتي لا تتطلب مفاتيح. يمكنك أيضًا طلب استخدام المفتاح الرئيسي. تغيّر مستوى التخويل الافتراضي باستخدام الخاصية authLevel في JSON الربط. لمزيد من المعلومات، راجع المشغل- التكوين.

إشعار

عند تشغيل الدالات محليًا، يتم تعطيل التخويل بغض النظر عن إعداد مستوى التخويل المحدد. بعد النشر إلى Azure، يتم فرض الإعداد authLevel في المشغل. لا تزال المفاتيح مطلوبة عند تشغيل محليًا في حاوية.

تأمين نقطة نهاية HTTP في الإنتاج

لتأمين نقاط النهاية الدالة بالكامل في الإنتاج، يجب عليك مراعاة تنفيذ أحد خيارات الأمان التالية على مستوى تطبيق الدالة. عند استخدام أحد أساليب الأمان التالية على مستوى تطبيق الدالة، يجب عليك تعيين مستوى تخويل الدالة الذي يتم تشغيله في HTTP إلى anonymous.

تفعيل مصادقة/تخويل خدمة التطبيق

يتيح لك النظام الأساسي ل App Service استخدام معرف Microsoft Entra والعديد من موفري الهوية التابعين لجهة خارجية لمصادقة العملاء. يمكنك استخدام هذه الإستراتيجية لتنفيذ قواعد التخويل المخصصة لوظائفك، ويمكنك العمل مع معلومات المستخدم من التعليمة البرمجية لوظيفتك. لمعرفة المزيد، راجع المصادقة والتخويل في خدمات تطبيق Azure والعمل باستخدام هويات العميل.

استخدم إدارة Azure API (APIM) لمصادقة الطلبات

يوفر APIM مجموعة متنوعة من خيارات أمان واجهة برمجة التطبيقات (API) للطلبات الواردة. لمعرفة المزيد، راجع نُهج مصادقة إدارة واجهة برمجة التطبيقات. باستخدام APIM في مكانه، يمكنك تكوين تطبيق الوظائف الخاص بك لقبول الطلبات فقط من عنوان IP لمثيل APIM الخاص بك. لمعرفة المزيد، راجع قيود عنوان IP.

نشر تطبيق وظيفتك بمعزل عن غيره

توفر بيئة خدمة تطبيقات Azure (ASE) بيئة استضافة مخصصة لتشغيل وظائفك فيها. يتيح لك ASE تكوين بوابة أمامية واحدة يمكنك استخدامها لمصادقة جميع الطلبات الواردة. للمزيد من المعلومات، راجع تكوين جدار حماية تطبيق الويب (WAF) لبيئة خدمة التطبيقات.

خطاف الويب

إشعار

وضع إخطار على الويب متوفر فقط للإصدار 1.x من وقت تشغيل الدالات. تم إجراء هذا التغيير لتحسين أداء مشغلات HTTP في الإصدار 2.x وأعلى.

في الإصدار 1.x، توفر قوالب الإخطارات على الويب التحقق من الصحة الإضافي للبيانات الأساسية للإخطار على الويب. في الإصدار 2.x وأعلى، لا يزال مشغل HTTP الأساسي يعمل وهو النهج الموصى به للإخطارات على الويب.

نوع WebHook

تشير خاصية الربط webHookType إلى النوع إذا كان خطاف الويب مدعوماً بواسطة الوظيفة، والتي تحدد أيضاً الحمولة المدعومة. يمكن أن يكون نوع إخطار على الويب إحدى القيم التالية:

اكتب القيمة ‏‏الوصف
genericJson نقطة نهاية إخطار على الويب للأغراض العامة بدون منطق لموفر معين. يقيد هذا الإعداد الطلبات لأولئك الذين يستخدمون HTTP POST فقط ومع نوع المحتوى application/json.
github تستجيب الدالة لخطافات الويب GitHub. لا تستخدم خاصية authLevel مع GitHub webhooks.
slack تستجيب الدالة لخطافات ويب Slack. لا تستخدم خاصية authLevel مع Slack webhooks.

عند تعيين الخاصية webHookType، لا تقم أيضاً بتعيين الخاصية methods على الربط.

إخطارات GitHub على الويب

للاستجابة إلى إخطارات GitHub على الويب، يمكنك أولاً إنشاء الدالة الخاصة بك مع مشغل HTTP، وتعيين الخاصية webHookType إلى github. ثم انسخ عنوان URL ومفتاح API الخاصين بها إلى صفحة إضافة إخطار على الويب في مستودع GitHub.

لقطة شاشة توضح كيفية إضافة إخطار على الويب لدالتك.

إخطارات Slack على الويب

ينشئ إخطار Slack على الويب رمزًا مميزًا بدلاً من السماح لك بتحديده، لذا يتعين عليك تكوين مفتاح خاص بالدالة مع الرمز المميز من Slack. انظر مفاتيح التخويل.

الإخطارات على الويب والمفاتيح

تتم معالجة تخويل إخطار على الويب بواسطة مكون مستقبل إخطار على الويب وجزء من مشغل HTTP وتختلف الآلية استنادًا إلى نوع إخطار على الويب. تعتمد كل آلية على مفتاح. بشكل افتراضي، يتم استخدام مفتاح الدالة المسمى "افتراضي". لاستخدام مفتاح مختلف، يمكنك تكوين موفر إخطار على الويب لإرسال اسم المفتاح مع الطلب بإحدى الطرق التالية:

  • سلسلة الاستعلام: يقوم الموفر بتمرير اسم المفتاح في معلمة سلسلة استعلامclientid، مثل https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?clientid=<KEY_NAME>.
  • عنوان الطلب: يقوم الموفر بتمرير اسم المفتاح في عنوان x-functions-clientid.

أنواع المحتوى

يتطلب تمرير البيانات الثنائية وبيانات النموذج إلى دالة غير C#‎ استخدام عنوان نوع المحتوى المناسب. تتضمن أنواع المحتويات المعتمدة octet-stream للبيانات الثنائية وأنواع الأجزاء المتعددة.

المشكلات المعروفة

في الدالات غير C#‎، تؤدي الطلبات المرسلة مع نوع المحتوى image/jpeg إلى قيمة string يتم تمريرها إلى الدالة. في مثل هذه الحالات، يمكنك تحويل القيمة string يدويًا إلى صفيف بايت للوصول إلى البيانات الثنائية الأولية.

الحدود

يقتصر طول طلب HTTP على 100 ميغابايت (104,857,600 بايت)، ويقتصر طول URL على 4 كيلوبايت (4096 بايت). يتم تحديد هذه الحدود بواسطة عنصر httpRuntime لملف Web.config الخاص بوقت التشغيل.

إذا لم تكتمل دالة تستخدم مشغل HTTP خلال 230 ثانية، فإن مهلة Azure Load Balancer ستنقضي وتُرجع خطأ HTTP 502. سوف تستمر الدالة في التشغيل ولكنها لن تتمكن من إرجاع استجابة HTTP. بالنسبة للدالات طويلة الأمد، نوصي باتباع أنماط غير متزامنة وإرجاع موقع حيث يمكنك اختبار الاتصال لحالة الطلب. للحصول على معلومات حول المدة التي يمكن تشغيل الدالة خلالها، راجع تغيير السعة والاستضافة - خطة الاستهلاك.

الخطوات التالية