使用 Azure Functions 代理Work with Azure Functions Proxies

本文介绍了如何配置和使用 Azure Functions 代理。This article explains how to configure and work with Azure Functions Proxies. 使用此功能可在 Function App 上指定由其他资源实现的终结点。With this feature, you can specify endpoints on your function app that are implemented by another resource. 可以使用这些代理将大型 API 拆分到多个 Function App 中(与在微服务体系结构中一样),同时对客户端仍然呈现为单个 API 接口。You can use these proxies to break a large API into multiple function apps (as in a microservice architecture), while still presenting a single API surface for clients.

此参考信息面向 Azure Functions 开发人员。This is reference information for Azure Functions developers. Azure Functions 的新手请从以下资源入手:If you're new to Azure Functions, start with the following resources:

Note

标准版 Functions 针对代理执行收费。Standard Functions billing applies to proxy executions. 有关详细信息,请参阅 Azure Functions 定价For more information, see Azure Functions pricing.

创建代理Create a proxy

本部分介绍如何在 Functions 门户中创建代理。This section shows you how to create a proxy in the Functions portal.

  1. 打开 Azure 门户,并转到 Function App。Open the Azure portal, and then go to your function app.
  2. 在左窗格中,选择“新建代理”。In the left pane, select New proxy.
  3. 为代理提供一个名称。Provide a name for your proxy.
  4. 通过指定路由模板HTTP 方法配置在此 Function App 上公开的终结点。Configure the endpoint that's exposed on this function app by specifying the route template and HTTP methods. 这些参数的行为取决于 HTTP 触发器的规则。These parameters behave according to the rules for HTTP triggers.
  5. 将“后端 URL”设置为另一个终结点。Set the backend URL to another endpoint. 此终结点可以是其他 Function App 中的函数,也可以是任何其他 API。This endpoint could be a function in another function app, or it could be any other API. 该值不需要是静态值,并且可以引用应用程序设置原始客户端请求中的参数The value does not need to be static, and it can reference application settings and parameters from the original client request.
  6. 单击创建Click Create.

代理现在已作为新终结点存在于 Function App 上。Your proxy now exists as a new endpoint on your function app. 从客户端角度来看,它等同于 Azure Functions 中的 HttpTrigger。From a client perspective, it is equivalent to an HttpTrigger in Azure Functions. 可以通过复制代理 URL 并使用最喜欢的 HTTP 客户端对其进行测试来试验新代理。You can try out your new proxy by copying the Proxy URL and testing it with your favorite HTTP client.

修改请求和响应Modify requests and responses

使用 Azure Functions 代理可以修改针对后端发出的请求以及从后端返回的响应。With Azure Functions Proxies, you can modify requests to and responses from the back-end. 这些转换可以使用使用变量中定义的变量。These transformations can use variables as defined in Use variables.

修改后端请求Modify the back-end request

默认情况下,后端请求初始化为原始请求的副本。By default, the back-end request is initialized as a copy of the original request. 除了设置后端 URL 以外,还可以对 HTTP 方法、标头和查询字符串参数进行更改。In addition to setting the back-end URL, you can make changes to the HTTP method, headers, and query string parameters. 修改的值可以引用应用程序设置原始客户端请求中的参数The modified values can reference application settings and parameters from the original client request.

可在门户中通过展开代理详细信息页的“请求替代”部分修改后端请求。Back-end requests can be modified in the portal by expanding the request override section of the proxy detail page.

修改响应Modify the response

默认情况下,客户端响应初始化为后端响应的副本。By default, the client response is initialized as a copy of the back-end response. 可对响应的状态代码、原因短语、标头和正文进行更改。You can make changes to the response's status code, reason phrase, headers, and body. 修改的值可以引用应用程序设置原始客户端请求中的参数后端响应中的参数The modified values can reference application settings, parameters from the original client request, and parameters from the back-end response.

可在门户中通过展开代理详细信息页的“响应替代”部分修改后端请求。Back-end requests can be modified in the portal by expanding the response override section of the proxy detail page.

使用变量Use variables

代理的配置不需要是静态的。The configuration for a proxy does not need to be static. 可将它调整为使用原始客户端请求、后端响应或应用程序设置中的变量。You can condition it to use variables from the original client request, the back-end response, or application settings.

引用本地函数Reference local functions

可以使用 localhost 直接引用同一函数应用内的函数,而无需往返代理请求。You can use localhost to reference a function inside the same function app directly, without a roundtrip proxy request.

"backendurl": "https://localhost/api/httptriggerC#1" 将引用路由 /api/httptriggerC#1 中的本地 HTTP 触发函数"backendurl": "https://localhost/api/httptriggerC#1" will reference a local HTTP triggered function at the route /api/httptriggerC#1

Note

如果函数使用“函数”、“管理员”或“sys” 授权级别,将需要根据原始函数 URL 提供代码和 clientId。If your function uses function, admin or sys authorization levels, you will need to provide the code and clientId, as per the original function URL. 在这种情况下,引用将如下所示:"backendurl": "https://localhost/api/httptriggerC#1?code=<keyvalue>&clientId=<keyname>"In this case the reference would look like: "backendurl": "https://localhost/api/httptriggerC#1?code=<keyvalue>&clientId=<keyname>"

引用请求参数Reference request parameters

可将请求参数用作后端 URL 属性的输入,或者在修改请求和响应的过程中使用请求参数。You can use request parameters as inputs to the back-end URL property or as part of modifying requests and responses. 一些参数可以从基本代理配置中指定的路由模板绑定,而其他一些参数可以来自传入请求的属性。Some parameters can be bound from the route template that's specified in the base proxy configuration, and others can come from properties of the incoming request.

路由模板参数Route template parameters

可按名称引用路由模板中使用的参数。Parameters that are used in the route template are available to be referenced by name. 需将参数名称括在大括号 ({}) 中。The parameter names are enclosed in braces ({}).

例如,如果代理具有诸如 /pets/{petId} 的路由模板,则后端 URL 可以包括 {petId} 的值,就像在 https://<AnotherApp>.chinacloudsites.cn/api/pets/{petId} 中那样。For example, if a proxy has a route template, such as /pets/{petId}, the back-end URL can include the value of {petId}, as in https://<AnotherApp>.chinacloudsites.cn/api/pets/{petId}. 如果路由模板以通配符结尾,例如 /api/{*restOfPath},则值 {restOfPath} 将是传入请求中的其余路径段的字符串表示形式。If the route template terminates in a wildcard, such as /api/{*restOfPath}, the value {restOfPath} is a string representation of the remaining path segments from the incoming request.

其他请求参数Additional request parameters

除了路由模板参数以外,还可以在配置值中使用以下值:In addition to the route template parameters, the following values can be used in config values:

  • {request.method}:对原始请求使用的 HTTP 方法。{request.method}: The HTTP method that's used on the original request.
  • {request.headers.<HeaderName>}:从原始请求中读取的标头。{request.headers.<HeaderName>}: A header that can be read from the original request. 请将 <HeaderName> 替换为要读取的标头的名称。Replace <HeaderName> with the name of the header that you want to read. 如果该标头未包含在请求中,则该值为空字符串。If the header is not included on the request, the value will be the empty string.
  • {request.querystring.<ParameterName>}:可从原始请求中读取的查询字符串参数。{request.querystring.<ParameterName>}: A query string parameter that can be read from the original request. 请将 <ParameterName> 替换为要读取的参数的名称。Replace <ParameterName> with the name of the parameter that you want to read. 如果该参数未包含在请求中,则该值为空字符串。If the parameter is not included on the request, the value will be the empty string.

引用后端响应参数Reference back-end response parameters

在修改返回给客户端的响应过程中,可以使用响应参数。Response parameters can be used as part of modifying the response to the client. 可以在配置值中使用以下值:The following values can be used in config values:

  • {backend.response.statusCode}:在后端响应中返回的 HTTP 状态代码。{backend.response.statusCode}: The HTTP status code that's returned on the back-end response.
  • {backend.response.statusReason}:在后端响应中返回的 HTTP 原因短语。{backend.response.statusReason}: The HTTP reason phrase that's returned on the back-end response.
  • {backend.response.headers.<HeaderName>}:可以从后端响应中读取的标头。{backend.response.headers.<HeaderName>}: A header that can be read from the back-end response. 请将 <HeaderName> 替换为要读取的标头的名称。Replace <HeaderName> with the name of the header you want to read. 如果该标头未包含在响应中,则该值将为空字符串。If the header is not included on the response, the value will be the empty string.

引用应用程序设置Reference application settings

还可以通过将设置名称括在百分号 (%) 之间来引用针对 Function App 定义的应用程序设置You can also reference application settings defined for the function app by surrounding the setting name with percent signs (%).

例如,后端 URL https://%ORDER_PROCESSING_HOST%/api/orders 会将“%ORDER_PROCESSING_HOST%”替换为 ORDER_PROCESSING_HOST 设置的值。For example, a back-end URL of https://%ORDER_PROCESSING_HOST%/api/orders would have "%ORDER_PROCESSING_HOST%" replaced with the value of the ORDER_PROCESSING_HOST setting.

Tip

当有多个部署或测试环境时,请为后端主机使用应用程序设置。Use application settings for back-end hosts when you have multiple deployments or test environments. 这样可以确保始终与该环境的正确后端进行通信。That way, you can make sure that you are always talking to the right back-end for that environment.

对代理进行故障排除Troubleshoot Proxies

通过将标志 "debug":true 添加到 proxies.json 中的任何代理,将启用调试日志记录。By adding the flag "debug":true to any proxy in your proxies.json you will enable debug logging. 日志存储在 D:\home\LogFiles\Application\Proxies\DetailedTrace 中,可通过高级工具 (kudu) 访问。Logs are stored in D:\home\LogFiles\Application\Proxies\DetailedTrace and accessible through the advanced tools (kudu). 任何 HTTP 响应也将包含 Proxy-Trace-Location 标头,其中包含用于访问日志文件的 URL。Any HTTP responses will also contain a Proxy-Trace-Location header with a URL to access the log file.

可以通过添加设置为 trueProxy-Trace-Enabled 标头来从客户端调试代理。You can debug a proxy from the client side by adding a Proxy-Trace-Enabled header set to true. 这还会将跟踪结果记录到文件系统,并以响应中标头的形式返回跟踪 URL。This will also log a trace to the file system, and return the trace URL as a header in the response.

阻止代理跟踪Block proxy traces

出于安全原因,你可能不想允许任何人调用服务生成跟踪。For security reasons you may not want to allow anyone calling your service to generate a trace. 没有登录凭据这些人将无法访问跟踪内容,但生成跟踪会占用资源并公开你正在使用函数代理。They will not be able to access the trace contents without your login credentials, but generating the trace consumes resources and exposes that you are using Function Proxies.

通过将 "debug":false 添加到 proxies.json 中的任何特定代理可完全禁用跟踪。Disable traces altogether by adding "debug":false to any particular proxy in your proxies.json.

高级配置Advanced configuration

配置的代理存储在一个 proxies.json 文件中,此文件位于函数应用目录的根目录中。The proxies that you configure are stored in a proxies.json file, which is located in the root of a function app directory. 使用 Functions 支持的任何部署方法时,可以手动编辑此文件并将其部署为应用的一部分。You can manually edit this file and deploy it as part of your app when you use any of the deployment methods that Functions supports.

Tip

如果尚未设置一种部署方法,也可以在门户中使用 proxies.json 文件。If you have not set up one of the deployment methods, you can also work with the proxies.json file in the portal. 转到到 Function App,选择“平台功能”,并选择“应用服务编辑器”。Go to your function app, select Platform features, and then select App Service Editor. 这样,便可以看到 Function App 的整个文件结构并进行更改。By doing so, you can view the entire file structure of your function app and then make changes.

Proxies.json 是由一个代理对象定义的,包括已命名的代理及其定义。Proxies.json is defined by a proxies object, which is composed of named proxies and their definitions. (可选)可以引用用于代码完成的 JSON 架构(如果编辑器支持这样做)。Optionally, if your editor supports it, you can reference a JSON schema for code completion. 示例文件可能如下例所示:An example file might look like the following:

{
    "$schema": "http://json.schemastore.org/proxies",
    "proxies": {
        "proxy1": {
            "matchCondition": {
                "methods": [ "GET" ],
                "route": "/api/{test}"
            },
            "backendUri": "https://<AnotherApp>.chinacloudsites.cn/api/<FunctionName>"
        }
    }
}

每个代理都有一个友好名称,例如上例中的 proxy1Each proxy has a friendly name, such as proxy1 in the preceding example. 对应的代理定义对象是由以下属性定义的:The corresponding proxy definition object is defined by the following properties:

  • matchCondition:必需 - 一个对象,用于定义触发此代理执行的请求。matchCondition: Required--an object defining the requests that trigger the execution of this proxy. 它包含两个与 HTTP 触发器共享的属性:It contains two properties that are shared with HTTP triggers:
    • methods:代理响应的 HTTP 方法的数组。methods: An array of the HTTP methods that the proxy responds to. 如果未指定此属性,代理将响应路由上的所有 HTTP 方法。If it is not specified, the proxy responds to all HTTP methods on the route.
    • route:必需 - 定义路由模板,控制代理将响应哪些请求 URL。route: Required--defines the route template, controlling which request URLs your proxy responds to. 与在 HTTP 触发器中不同,此处没有默认值。Unlike in HTTP triggers, there is no default value.
  • backendUri:应当通过代理将请求发送到的后端资源的 URL。backendUri: The URL of the back-end resource to which the request should be proxied. 此值可以引用应用程序设置和原始客户端请求中的参数。This value can reference application settings and parameters from the original client request. 如果未包括此属性,则 Azure Functions 以 HTTP 200 OK 进行响应。If this property is not included, Azure Functions responds with an HTTP 200 OK.
  • requestOverrides:定义对后端请求执行的转换的对象。requestOverrides: An object that defines transformations to the back-end request. 请参阅定义 requestOverrides 对象See Define a requestOverrides object.
  • responseOverrides:定义对客户端响应执行的转换的对象。responseOverrides: An object that defines transformations to the client response. 请参阅定义 responseOverrides 对象See Define a responseOverrides object.

Note

Azure Functions 代理中的 route 属性不接受 Function App 主机配置的 routePrefix 属性。The route property in Azure Functions Proxies does not honor the routePrefix property of the Function App host configuration. 如果希望包括一个如 /api 等前缀,必须将其包括在 route 属性中。If you want to include a prefix such as /api, it must be included in the route property.

禁用单个代理Disable individual proxies

可以通过将 "disabled": true 添加到 proxies.json 文件中的代理来禁用单个代理。You can disable individual proxies by adding "disabled": true to the proxy in the proxies.json file. 这将导致满足 matchCondition 的任何请求返回 404。This will cause any requests meeting the matchCondition to return 404.

{
    "$schema": "http://json.schemastore.org/proxies",
    "proxies": {
        "Root": {
            "disabled":true,
            "matchCondition": {
                "route": "/example"
            },
            "backendUri": "https://<AnotherApp>.chinacloudsites.cn/api/<FunctionName>"
        }
    }
}

应用程序设置Application Settings

代理行为可以通过多个应用程序设置进行控制。The proxy behavior can be controlled by several app settings. Functions App 设置参考中概述了所有这些设置They are all outlined in the Functions App Settings reference

保留字符(字符串格式设置)Reserved Characters (string formatting)

代理使用“\”作为转义符从 JSON 文件中读取所有字符串。Proxies read all strings out of a JSON file, using \ as an escape symbol. 代理还会解释大括号。Proxies also interpret curly braces. 请参阅下面的完整示例集。See a full set of examples below.

CharacterCharacter 转义字符Escaped Character 示例Example
{ 或 }{ or } {{ 或 }}{{ or }} {{ example }} --> { example }
\ \\ example.com\\text.html --> example.com\text.html
"" \" \"example\" --> "example"

定义 requestOverrides 对象Define a requestOverrides object

requestOverrides 对象定义调用后端资源时对请求所做的更改。The requestOverrides object defines changes made to the request when the back-end resource is called. 该对象由以下属性定义:The object is defined by the following properties:

  • backend.request.method:用于调用后端的 HTTP 方法。backend.request.method: The HTTP method that's used to call the back-end.
  • backend.request.querystring.<ParameterName>:可为后端调用设置的查询字符串参数。backend.request.querystring.<ParameterName>: A query string parameter that can be set for the call to the back-end. 请将 <ParameterName> 替换为要设置的参数的名称。Replace <ParameterName> with the name of the parameter that you want to set. 如果提供空字符串,该参数不会包含在后端请求中。If the empty string is provided, the parameter is not included on the back-end request.
  • backend.request.headers.<HeaderName>:可为后端调用设置的标头。backend.request.headers.<HeaderName>: A header that can be set for the call to the back-end. 请将 <HeaderName> 替换为要设置的标头的名称。Replace <HeaderName> with the name of the header that you want to set. 如果提供空字符串,该标头不会包含在后端请求中。If you provide the empty string, the header is not included on the back-end request.

值可以引用应用程序设置和原始客户端请求中的参数。Values can reference application settings and parameters from the original client request.

示例配置可能如下所示:An example configuration might look like the following:

{
    "$schema": "http://json.schemastore.org/proxies",
    "proxies": {
        "proxy1": {
            "matchCondition": {
                "methods": [ "GET" ],
                "route": "/api/{test}"
            },
            "backendUri": "https://<AnotherApp>.chinacloudsites.cn/api/<FunctionName>",
            "requestOverrides": {
                "backend.request.headers.Accept": "application/xml",
                "backend.request.headers.x-functions-key": "%ANOTHERAPP_API_KEY%"
            }
        }
    }
}

定义 responseOverrides 对象Define a responseOverrides object

requestOverrides 对象定义对传回客户端的响应所做的更改。The requestOverrides object defines changes that are made to the response that's passed back to the client. 该对象由以下属性定义:The object is defined by the following properties:

  • response.statusCode:要返回给客户端的 HTTP 状态代码。response.statusCode: The HTTP status code to be returned to the client.
  • response.statusReason:要返回给客户端的 HTTP 原因短语。response.statusReason: The HTTP reason phrase to be returned to the client.
  • response.body:要返回给客户端的正文的字符串表示形式。response.body: The string representation of the body to be returned to the client.
  • response.headers.<HeaderName>:可为返回给客户端的响应设置的标头。response.headers.<HeaderName>: A header that can be set for the response to the client. 请将 <HeaderName> 替换为要设置的标头的名称。Replace <HeaderName> with the name of the header that you want to set. 如果提供空字符串,该标头不会包含在响应中。If you provide the empty string, the header is not included on the response.

值可以引用应用程序设置、原始客户端请求中的参数和后端响应中的参数。Values can reference application settings, parameters from the original client request, and parameters from the back-end response.

示例配置可能如下所示:An example configuration might look like the following:

{
    "$schema": "http://json.schemastore.org/proxies",
    "proxies": {
        "proxy1": {
            "matchCondition": {
                "methods": [ "GET" ],
                "route": "/api/{test}"
            },
            "responseOverrides": {
                "response.body": "Hello, {test}",
                "response.headers.Content-Type": "text/plain"
            }
        }
    }
}

Note

在此示例中,响应正文是直接设置的,因此不需要 backendUri 属性。In this example, the response body is set directly, so no backendUri property is needed. 此示例演示如何使用 Azure Functions 代理来模拟 API。The example shows how you might use Azure Functions Proxies for mocking APIs.