The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.

Funqy

Quarkus Funqy は、Quarkus のサーバーレス戦略の一部であり、AWS Lambda、Azure Functions、Google Cloud Functions、Knative、Knative Events(Cloud Events)などの様々な FaaS 環境にデプロイ可能なファンクションを書くためのポータブルな Java API を提供することを目的としています。また、スタンドアロンのサービスとしても使用することができます。

Funqy は複数の異なるクラウド、ファンクションプロバイダーやプロトコルに跨った抽象化を提供するため、その API は非常にシンプルである必要があり、ユーザーが使い慣れている他のリモーティング抽象化で提供される機能を全て備えているとは限りません。一方で、Funqy は可能な限り最適化され、かつ小さいという良い副次的効果があります。これは、Funqy は柔軟性を少し犠牲にしている分、オーバーヘッドが非常に少ないフレームワークであることを意味しています。

Funqy の基礎

Funqy API はシンプルです。メソッドに @Funq をアノテーションします。このメソッドはオプションの入力パラメータを1つだけ持つことができ、レスポンスを返すこともあれば返さないこともあります。

import io.quarkus.funqy.Funq;

public class GreetingFunction {
    @Funq
    public String greet(String name) {
       return "Hello " + name;
    }
}

Javaクラスは入力と出力としても使用でき、Java Bean の規約に従う必要があり、デフォルトのコンストラクタを持たなければなりません。パラメータや戻り値の型として宣言されたJavaの型は、Funqyのランタイムが期待する型です。Funqyは起動時間を短縮するためにビルド時に型のイントロスペクションを行いますので、派生型は実行時にFunqyのマーシャリング層に意識されません。

以下に、POJO を入出力の型として使用した例をご紹介します。

public class GreetingFunction {
    public static class Friend {
        String name;

        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
    }

    public static class Greeting {
        String msg;

        public Greeting() {}
        public Greeting(String msg) { this.msg = msg }

        public String getMessage() { return msg; }
        public void setMessage(String msg) { this.msg = msg; }
    }

    @Funq
    public Greeting greet(Friend friend) {
       return new Greeting("Hello " + friend.getName());
    }
}

非同期リアクティブ型

Funqy supports the SmallRye Mutiny Uni reactive type as a return type. The only requirement is that the Uni must fill out the generic type.

import io.quarkus.funqy.Funq;
import io.smallrye.mutiny.Uni;

public class GreetingFunction {

    @Funq
    public Uni<Greeting> reactiveGreeting(String name) {
       ...
    }
}

ファンクション名

ファンクション名のデフォルト値はメソッド名で、大文字と小文字は区別されます。ファンクションを別の名前で参照したい場合は、以下のように @Funq アノテーションにパラメータを記述します。

import io.quarkus.funqy.Funq;

public class GreetingFunction {

    @Funq("HelloWorld")
    public String greet(String name) {
       return "Hello " + name;
    }
}

Funqy DI

各Funqy JavaクラスはQuarkus Arcコンポーネントであり、CDIまたはSpring DIによる依存性注入をサポートしています。Spring DIでは、ビルドに quarkus-spring-di 依存関係を含める必要があります。

Funqy クラスのデフォルトのオブジェクトライフサイクルは @Dependent となります。

import io.quarkus.funqy.Funq;

import jakarta.inject.Inject;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class GreetingFunction {

    @Inject
    GreetingService service;

    @Funq
    public Greeting greet(Friend friend) {
        Greeting greeting = new Greeting();
        greeting.setMessage(service.greet(friend.getName()));
        return greeting;
    }
}

コンテキストの注入

通常、 Funqy API はプロトコル (例: HTTP ) やファンクション API (例: AWS Lambda) に固有の抽象化を注入したり、使用したりすることはできません。例外もあり、デプロイ先の環境に応じたコンテキスト情報を注入できる場合もあります。

ランタイムに固有のコンテキスト情報を注入することは推奨されません。 ファンクションを移植性の高いものにしてください。

コンテキスト情報は、ファンクションのパラメータやクラスのフィールドに使用できる @Context アノテーションを介して注入されます。例として、 Funqy Knative Cloud Events に搭載されている io.quarkus.funqy.knative.events.CloudEvent インターフェースがあります。

import io.quarkus.funqy.Funq;
import io.quarkus.funqy.Context;
import io.quarkus.funqy.knative.events.CloudEvent;

public class GreetingFunction {

    @Funq
    public Greeting greet(Friend friend, @Context CloudEvent eventInfo) {
        System.out.println("Received greeting request from: " eventInfo.getSource());

        Greeting greeting = new Greeting();
        greeting.setMessage("Hello " + friend.getName()));
        return greeting;
    }
}

Funqy を使うべきか?

REST over HTTP has become a very common way to write services over the past decade. While Funqy has an HTTP binding it is not a replacement for REST. Because Funqy has to work across a variety of protocols and function cloud platforms, it is very minimalistic and constrained. For example, if you use Funqy you lose the ability to link (think URIs) to the data your functions spit out. You also lose the ability to leverage cool HTTP features like cache-control and conditional GETs. Many developers will be ok with that as many won’t be using these REST/HTTP features or styles. You’ll have to make the decision on what camp you are in. Quarkus does support REST integration (through Jakarta REST, Spring MVC, Vert.x Web, and Servlet) with various cloud/function providers, but there are some disadvantages of using that approach as well. For example, if you want to do HTTP with AWS Lambda, this requires you to use the AWS API Gateway which may slow down deployment and cold start time or even cost you more.

The purpose of Funqy is to allow you to write cross-provider functions so that you can move off of your current function provider if, for instance, they start charging you a lot more for their service. Another reason you might not want to use Funqy is if you need access specific APIs of the target function environment. For example, developers often want access to the AWS Context on Lambda. In this case, we tell them they may be better off using the Quarkus AWS Lambda integration instead.

関連コンテンツ