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

Funqy HTTPバインディング (スタンドアロン)

このガイドでは、Funqyをスタンドアロンサービスとしてデプロイし、HTTPを使ってFunqy関数を呼び出す方法をクイックスタートコードで説明します。

FunqyのHTTPバインディングはHTTP上のRESTの代わりではありません。Funqyは多くの異なるプロトコルや Function プロバイダに対してポータブルである必要があるので、HTTPバインディングは非常にミニマムで、リンクのようなREST機能やキャッシュコントロールや条件付きGETのようなHTTPを利用する機能を失うことになります。代わりにQuarkusのJAX-RS、Spring MVC、またはVert.x Web Reactive Routesのサポートを使用することを検討すると良いでしょう。しかしながら、Funqy はこれらの選択肢と比べてオーバーヘッドが小さいでしょう(例外として Vert.x はそれでもすごく早いですが)。

前提条件

このガイドを完成させるには、以下が必要です:

  • 約15分

  • IDE

  • JDK 11+ がインストールされ、 JAVA_HOME が適切に設定されていること

  • Apache Maven 3.8.1+

  • 使用したい場合、 Quarkus CLI

  • Funqy の基礎 を読む。短時間で読めます!

クイックスタート

Gitレポジトリをクローンするか git clone https://github.com/quarkusio/quarkus-quickstarts.gitアーカイブ をダウンロードします。

ソリューションは funqy-http-quickstart ディレクトリ にあります。

コード

Javaコードを見ると、HTTP固有のAPIがないことがわかります。単純な Java メソッドに @Funq とアノテーションが付けられているだけです。シンプルで、簡単で、わかりやすいです。

Maven 依存関係

Funqy HTTP Function を書くには、 quarkus-funqy-http 依存関係をQuarkus pom.xml ファイルにインクルードするだけでよいです。

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-funqy-http</artifactId>
</dependency>

プロジェクトのビルド

mvn clean quarkus:dev

これにより、Quarkus 開発モードで Function が起動されます。

Funqy HTTP Function の実行

Function を実行するための URL パスは、Function 名です。例えば、Function 名が foo の場合、Function を実行する URL パスは /foo になります。

HTTP POST または GET メソッドを使用して Function を呼び出すことができます。Function の戻り値は、Jackson JSON ライブラリを使用して JSON にマーシャルされます。Jackson アノテーションを使用することができます。Function に入力パラメーターがある場合、POST 呼び出しは入力タイプとして JSON を使用しなければなりません。ここでもJackson はアンマーシャリングに使用されます。

ブラウザを http://localhost:8080/hello に向けると、 PrimitiveFunctions.java で定義されている hello Function を呼び出すことができます。

クイックスタートの他の Function を呼び出すには、HTTP POST が必要です。 GreetingFunction.java で定義されている greet 関数を実行するには、この curl スクリプトを呼び出します。

curl "http://localhost:8080/greet" \
-X POST \
-H "Content-Type: application/json" \
-d '{"name":"Bill"}'

プリミティブ型は、標準の JSON マッピングを使用して入力として渡すこともできます。toLowerCase function defined in PrimitiveFunctions.java で定義されている toLowerCase 関数を実行するには、この curl スクリプトを呼び出します。

curl "http://localhost:8080/toLowerCase" \
-X POST \
-H "Content-Type: application/json" \
-d '"HELLO WORLD"'

PrimitiveFunctions.java で定義されている double Function を実行するには、この curl スクリプトを呼び出します。

curl "http://localhost:8080/double" \
-X POST \
-H "Content-Type: application/json" \
-d '2'

GET クエリパラメーターのマッピング

GETリクエストのために、Funqy HTTPバインディングは、Function の入力パラメーターのためのクエリパラメーターマッピングも提供しています。Bean スタイル・クラスと java.util.Map だけが入力パラメーターに使用できます。Bean スタイル・クラスでは、クエリ・パラメーター名は Bean クラスのプロパティーにマッピングされます。以下は、単純な Map の例です。

@Funq
public String hello(Map<String, Integer> map) {
...
}

キー値は、プリミティブ型(char を除く)か String でなければなりません。値は、プリミティブ型 (char を除く)、 StringOffsetDateTime 、または複雑な Bean スタイルのクラスを使用できます。上記の例に対して、対応する curl リクエストを以下に示します。

curl "http://localhost:8080/a=1&b=2"

hello Function の map 入力パラメーターは、 a →1, b →2 というキーバリューペアを持ちます。

Bean スタイルクラスを入力パラメーター型として使用することもできます。以下に例を示します。

public class Person {
    String first;
    String last;

    public String getFirst() { return first; }
    public void setFirst(String first) { this.first = first; }
    public String getLast() { return last; }
    public void setLast(String last) { this.last = last; }
}

public class MyFunctions {
    @Funq
    public String greet(Person p) {
       return "Hello " + p.getFirst() + " " + p.getLast();
    }
}

プロパティーの値は、 char 以外の任意のプリミティブ型にすることができます。また、 StringOffsetDateTime も可能です。 OffsetDateTime クエリのパラメーター値は ISO-8601 形式でなければなりません。

HTTP GET とクエリパラメーターを使用して呼び出すことができます。

curl "http://localhost:8080/greet?first=Bill&last=Burke"

上記のリクエストでは、クエリパラメーター名が入力クラスの対応するプロパティーにマッピングされています。

入力クラスは、入れ子になった Bean クラスを持つこともできます。前の例を拡張します。

public class Family {
    private Person dad;
    private Person mom;

    public Person getDad() { return dad; }
    public void setDad(Person dad) { this.dad = dad; }
    public Person getMom() { return mom; }
    public void setMom(Person mom) { this.mom = mom; }
}

public class MyFunctions {
    @Funq
    public String greet(Family family) {
       ...
    }
}

この場合、入れ子になった値のクエリパラメーターは . 表記法を使用します。例えば、以下のようになります。

curl "http://localhost:8080/greet?dad.first=John&dad.last=Smith&mom.first=Martha&mom.last=Smith"

java.util.ListSet もプロパティー値としてサポートされています。例えば

public class Family {
    ...

    List<String> pets;
}

public class MyFunctions {
    @Funq
    public String greet(Family family) {
       ...
    }
}

GETリクエストを実行するためには、 pets クエリパラメーターを複数回リストアップするだけです。

curl "http://localhost:8080/greet?pets=itchy&pets=scratchy"

より複雑な型の場合、 List および Set のメンバーは、クエリパラメーターに識別子を持つ必要があります。例えば、以下のようになります。

public class Family {
    ...

    List<Person> kids;
}

public class MyFunctions {
    @Funq
    public String greet(Family family) {
       ...
    }
}

それぞれの kids クエリーパラメーターは、参照している kid を識別する必要があります。これにより、ランタイムはどのプロパティー値がリストのどのメンバーに属するかを把握することができます。これが curl リクエストです。

curl "http://localhost:8080/greet?kids.1.first=Buffy&kids.2.first=Charlie"

上記のURLでは、リストの対象メンバーを識別するために 12 という値を使用していますが、任意の一意の文字列を使用することができます。

プロパティーは java.util.Map でもよいです。 マップのキーは、任意のプリミティブ型と String が利用できます。例えば、以下のようになります。

public class Family {
    ...

    Map<String, String> address;
}

public class MyFunctions {
    @Funq
    public String greet(Family family) {
       ...
    }
}

対応する呼び出しは次のようになります。

curl "http://localhost:8080/greet?address.state=MA&address.city=Boston"

Map の値が複雑な型であれば、最後に set するプロパティーを追加して表記を続けるだけです。

public class Family {
    ...

    Map<String, Address> addresses;
}

public class MyFunctions {
    @Funq
    public String greet(Family family) {
       ...
    }
}
curl "http://localhost:8080/greet?addresses.home.state=MA&addresses.home.city=Boston"