APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

【Microsoft Build 2023速報】Azure Functions関連アップデートがアツい!

はじめに

コンテナソリューション事業部の髙井です。今年もMicrosoft Buildが始まりましたね。

AI関連のアップデートで世間は盛り上がっていますが、Azure Functions関連のアプデもいい感じなので気になった機能をまとめます。

個人的にけっこう嬉しいやつが多かったです。

面倒なfunction.jsonが不要に

PythonのV2モデルおよびNoje.jsのV4モデルが出ています。

ボイラープレートが減って、面倒で間違えやすいfunction.jsonを書かなくてよくなりました

function.jsonというのは以下のようなやつです。

{
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    }
  ]
}

これまで、コード書いたあと別でこのjson作らないといけなかったんですよね。

nameを一致させたりバインディングを規定したり、なんというかAzure Functionsのためだけの知識が要求されるので、ふだんAzureを扱わない開発者にはわりと参入障壁になってたポイントなのかなと思います。

実際に私の知人がこのあたりで初見のとき詰まってたりしたので、これは本当にうれしいアプデだと思います。

Node.jsの場合

以下は、公式ブログから拝借したコードになります。

これまでのV3だと関数をexportして、それをfunction.jsonでバインドするような形でした。

module.exports = async function (context, req) {
  context.log('HTTP function processed a request');

  const name = req.query.name
    || req.body
    || 'world';

  context.res = {
    body: `Hello, ${name}!`
  };
};

V4になると、appをimportしてその配下のメソッドを使えばよくなります。インテリセンスも効きやすくなります。

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

app.http('helloWorld1', {
  methods: ['GET', 'POST'],
  handler: async (request, context) => {
    context.log('Http function processed request');

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

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

Pythonの場合

PythonはNode.jsと違い、アノテーションで解決できてしまう感じです。こちらも別の公式ブログエントリから。

V1まではazure.functions.HttpRequestを引数にとる関数を定義し、function.jsonとバインドしていましたが、

import azure.functions

def main(req: azure.functions.HttpRequest) -> str:
    user = req.params.get('user')
    return f'Hello, {user}!'

V2からはfunc.FunctionApp()に生えたメソッドでアノテーションを付けてあげる感じになります。

import azure.functions

app = func.FunctionApp()

@app.function_name(name="HttpTrigger1")
@app.route(route="req")
def main(req: azure.functions.HttpRequest) -> str:
    user = req.params.get('user')
    return f'Hello, {user}!'

バインディングもそこそこ対応しているみたいです。今回のBuildと合わせて発表のあったRedisバインディング(プレビュー)はまだのようですが、いずれ対応されるでしょう。
とはいえ、なんか公式ブログのリンクも切れているので、Redisはもう少しかかるのかも?

特にFlaskとかFastAPIが便利そう

今後は、FunctionsにFlaskとかFastAPIを立てるのが特に簡単そうでいいですね。

# function_app.py

import azure.functions as func 
from flask import Flask, request, Response, redirect, url_for 

flask_app = Flask(__name__) 
logger = logging.getLogger("my-function") 

@flask_app.get("/return_http") 
def return_http(): 
    return Response('<h1>Hello World™</h1>', mimetype='text/html') 

app = func.WsgiFunctionApp(app=flask_app.wsgi_app, 
                           http_auth_level=func.AuthLevel.ANONYMOUS)

これができると、Pythonで書いた処理を閉じ込めてAPI化するのが楽になるのでいいですね。

Pythonが得意とする系の処理だけをFunctionsに切り出してFlaskなりFastAPIなりで薄くラップしたAPIとして立てとくみたいな営みが簡単になることで、メインのサーバーサイドはPython以外の言語を使ってApp Serviceにホストするといった運用がし易くなります。

Pythonの一部機能やライブラリは使いたいけどサーバーサイド全体として採用するのは諸事情あって避けたいというシーンは、チラホラ聞いたりしますし、これがAzureでやりやすくなるのはいいことだと思います。

Python3.10がサポート

これもPythonを使うシーンでは嬉しいポイントです。

Python3.10からは、パターンマッチングの構文がサポートされていますし、Union型をまだるっこしいUnion[int, str]というシンタックスではなくstr | intで書けたりと、わりと目玉なアップデートがあるバージョンです。

Azure SQLの入出力バインディング

これもちょっと気になるアップデートですね。Azure SQLのバインディングがGAになったようです。

これまではCosmosDBだった部分をAzure SQLに置き換えたアーキが簡単に取れるようになりますね。

要件によってはNoSQLじゃなくてイベントドリブンにSQLを操作したいというシーンもあったでしょうから、これがバインディングとしてサポートされて、接続処理周りとかをすっ飛ばして関数が書けるようになるとけっこうラクチンだと思います。

おわりに

Container Appsが出てから「ACAいいじゃーん」とずっと思ってた私ですが、今回のAzure Functionsアプデによりボイラープレートが減ったことでFunctions使うシーンも増えそうな予感がしました。


私達ACS事業部はAzure・AKSを活用した内製化のご支援をしております。ご相談等ありましたらぜひご連絡ください。

www.ap-com.co.jp

また、一緒に働いていただける仲間も募集中です!
切磋琢磨しながらスキルを向上できる、エンジニアには良い環境だと思います。ご興味を持っていただけたら嬉しく思います。

www.ap-com.co.jp

本記事の投稿者: 髙井 比文
AKSをメインにしたインフラとアプリの領域際をご支援することが多いです。Azureは11冠です。
Hifumi Takai - Credly