😀
.NET で作成した Azure Functions の HttpTrigger を同じ Functions 内の別関数
Azure Functions 内に複数の関数を作成する事ができます。ある関数から別関数の実行結果を受け取り、何かしらの処理をしたい場合があるとします。呼び出される関数が HttpTrigger であれば単純に HTTP 通信すれば良いのでは?と考えてしまいますが、同じ Azure Functions 内なのでコードから直接実行できるのでは?と考え、実際にやってみました。
検証用 Azure Functions を作成
HttpTrigger 関数を二つ mainapp と backendapp という名前で作成します。
bash
$ func --version
4.0.5801
$ func init samplefunc --worker-runtime dotnet
$ cd samplefunc
$ func new --name mainapp --template HttpTrigger
$ func new --name backendapp --template HttpTrigger
$ func start
mainapp のコードを確認
テンプレートのコードに手を加えていない状態です。
mainapp.cs
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
namespace samplefunc
{
public static class mainapp
{
[FunctionName("mainapp")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
string responseMessage = string.IsNullOrEmpty(name)
? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
: $"Hello, {name}. This HTTP triggered function executed successfully.";
return new OkObjectResult(responseMessage);
}
}
}
mainapp に backendapp を実行するコードを追加
mainapp.cs
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Net.Http;
namespace samplefunc
{
public static class mainapp
{
[FunctionName("mainapp")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
string responseMessage = string.IsNullOrEmpty(name)
? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
: $"Hello, {name}. This HTTP triggered function executed successfully.";
var context = new DefaultHttpContext();
var request = context.Request;
request.QueryString = new QueryString("?name=hogehoge");
IActionResult actionResult = await backendapp.Run(request, log);
if (actionResult is OkObjectResult okObjectResult)
{
var backendResponse = okObjectResult.Value;
responseMessage += $"\n{backendResponse}";
}
return new OkObjectResult(responseMessage);
}
}
}
一つ目の追加箇所
backendapp に QueryString を渡すのに必要なパッケージを using します。
using System.Net.Http;
二つ目の追加箇所
任意の QueryString を backendapp に渡して、実行結果を responseMessage に追加します。
var context = new DefaultHttpContext();
var request = context.Request;
request.QueryString = new QueryString("?name=hogehoge");
IActionResult actionResult = await backendapp.Run(request, log);
if (actionResult is OkObjectResult okObjectResult)
{
var backendResponse = okObjectResult.Value;
responseMessage += $"\n{backendResponse}";
}
実行結果
QueryString で渡した値を含むレスポンスメッセージが表示されました。
bash
$ curl http://localhost:7071/api/mainapp
This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.
Hello, hogehoge. This HTTP triggered function executed successfully.
参考
Discussion