如何在Azure函数中调用另一个函数

时间:2017-09-20 07:26:01

标签: azure azure-functions

我写了3个函数如下

  1. 在db
  2. 中创建用户
  3. 从db
  4. 获取用户
  5. 处理用户
  6. 在[3]函数中,我将调用[2]函数来使用户使用Azure函数URL,如下所示: -

    https://hdidownload.azurewebsites.net/api/getusers

    有没有其他方法可以在另一个没有完整路径的Azure功能中调用Azure功能?

6 个答案:

答案 0 :(得分:9)

在功能应用程序中没有任何内置功能可以从其他功能调用一个HTTP功能,而无需实际进行HTTP调用。

对于简单的用例,我会坚持使用完整的URL进行调用。

要获得更高级的工作流程,请查看Durable Functions,特别是Function Chaining

答案 1 :(得分:4)

所有先前的答案都是有效的,但正如评论中所提到的,今年早些时候(2018年第一季度/第二季度)引入了耐用功能的概念。简而言之,耐用功能:

  

...使您可以在无服务器环境中编写有状态功能。该扩展程序可以管理状态,检查点并为您重新启动。

这实际上意味着您现在还可以将多个功能链接在一起。如果需要,它管理从功能A => B => C流出的状态。

通过将“耐用功能扩展”安装到您的功能应用程序来工作。这样,您就可以使用一些新的上下文绑定,例如在C#中,您可以执行以下操作(伪代码):

[FunctionName("ExpensiveDurableSequence")]
public static async Task<List<string>> Run(
    [OrchestrationTrigger] DurableOrchestrationTrigger context)
{
    var response = new List<Order>();

    // Call external function 1 
    var token = await context.CallActivityAsync<string>("GetDbToken", "i-am-root");

    // Call external function 2
    response.Add(await context.CallActivityAsync<IEnumerable<Order>>("GetOrdersFromDb", token));

    return response;
}

[FunctionName("GetDbToken")]
public static string GetDbToken([ActivityTrigger] string username)
{
    // do expensive remote api magic here
    return token;
}

[FunctionaName("GetOrdersFromDb")]
public static IEnumerable<Order> GetOrdersFromDb([ActivityTrigger] string apikey)
{
    // do expensive db magic here
    return orders;
}

这里有一些不错的方面:

  • 主序列将两个附加的功能串联起来
  • 执行外部功能时,主要顺序是进入睡眠状态;这意味着一旦外部功能忙于处理您就不会再被计费

这使您可以同时按顺序运行多个功能(例如,功能链),或并行执行多个功能并等待它们全部完成(扇出/扇入)。

关于此的一些其他背景参考:

答案 2 :(得分:1)

你不能直接这样做,但你有两个选择:

  1. 将HTTP请求发送到另一个功能的公共URL。
  2. 将消息放入Azure队列,让其他Azure功能处理它。 (Microsoft建议使用此解决方案)
  3. 至于第一个选项,在C#中你可以这样做:

    [FunctionName("RequestImageProcessing")]
    public static async Task RequestImageProcessing([HttpTrigger(WebHookType = "genericJson")]
        HttpRequestMessage req)
    {
        using (var client = new HttpClient())
        {
            string anotherFunctionSecret = ConfigurationManager.AppSettings
                ["AnotherFunction_secret"];
            // anotherFunctionUri is another Azure Function's 
            // public URL, which should provide the secret code stored in app settings 
            // with key 'AnotherFunction_secret'
            Uri anotherFunctionUri = new Uri(req.RequestUri.AbsoluteUri.Replace(
                req.RequestUri.PathAndQuery, 
                $"/api/AnotherFunction?code={anotherFunctionSecret}"));
    
            var responseFromAnotherFunction = await client.GetAsync(anotherFunctionUri);
            // process the response
        }
    }
    
    [FunctionName("AnotherFunction")]
    public static async Task AnotherFunction([HttpTrigger(WebHookType = "genericJson")]
    HttpRequestMessage req)
    {
        await Worker.DoWorkAsync();
    }
    

答案 3 :(得分:0)

我没有找到任何好的消息来源,我做了以下,它运作良好。

使用以下格式的网址调用其他功能:

  

https://my-functn-app-1.azurewebsites.net/some-path-here1?code=123412somecodehereemiii888ii88k123m123l123k1l23k1l3==

在Node.js中,我打电话如下:

let request_options = {
        method: 'GET',
        host: 'my-functn-app-1.azurewebsites.net',
        path: '/path1/path2?&q1=v1&q2=v2&code=123412somecodehereemiii888ii88k123m123l123k1l23k1l3',
        headers: {
            'Content-Type': 'application/json'
        }
};
require('https')
    .request(
         request_options,
         function (res) {
               // do something here
         });

没有问题。
对于其他编程语言,它应该以类似的方式工作 希望这可以帮助。

答案 4 :(得分:0)

我知道我们有耐用的函数,但是我像正常的静态方法一样调用函数,并且可以正常工作,这里是一个示例:

public static class Helloworld
{
    [FunctionName("Helloworld")]
    public static string Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req, ILogger log)
    {
        return "Hello World";
    }

}

public static class HelloWorldCall
{
    [FunctionName("HelloWorldCall")]
    public static string Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req, ILogger log)
    {
        var caller = Helloworld.Run(req, log);
        return caller;
    }

}

答案 5 :(得分:0)

Durable functions支持此操作,但是,当前仅在使用C#,F#或JavaScript时才受支持。

另一个选择是

  1. 为新的Azure函数创建HTTP请求,但是,您必须以一种函数不等待响应的方式来执行它,否则链中的第一个函数必须等到最后一个完成。使用Python,将类似于:

    try:
            requests.get("http://secondAzureFunction.com/api/",timeout=0.0000000001)
    except requests.exceptions.ReadTimeout: 
            pass
    

对我来说,这似乎有些拙劣。

  1. 使用 Azure存储队列。第一个函数将消息传递到队列,这将触发另一个Azure函数。这似乎是更优雅的解决方案。如Fabio writes here

这可以使您的功能小巧,快速和分离,同时取用 提供,扩展和扩展所有逻辑的优势 错误处理。