Fn Project で作成したファンクションの入出力を JSON 形式にしてみましょう。
以下のチュートリアルをベースにしています。
tutorials/JavaFDKIntroduction at master · fnproject/tutorials · GitHub
ファンクションの修正
fn init
でテンプレートとして作成されるファンクションを使って、入出力を JSON 形式に変更してみましょう。テンプレートで作成されるクラスは以下のとおりです。handleRequestメソッドがファンクションとして実行されます。
既存
package com.example.fn; public class HelloFunction { public String handleRequest(String input) { String name = (input == null || input.isEmpty()) ? "world" : input; return "Hello, " + name + "!"; } }
入出力を文字列から JSON 形式にするには、引数や戻り値の型を String クラスから任意のクラスへ変更します。チュートリアルでは、入力用の Input クラスと出力用の Result クラスを定義し、handleRequest メソッドの引数として Input クラスを、戻り値として Result クラスを指定してます。
JSON 対応後
package com.example.fn; public class HelloFunction { public static class Input { public String name; } public static class Result { public String salutation; } public Result handleRequest(Input input) { Result result = new Result(); result.salutation = "Hello " + input.name; return result; } }
テストケースの修正
ファンクションを変更したのでテストケースも修正しましょう。
既存
package com.example.fn; import com.fnproject.fn.testing.*; import org.junit.*; import static org.junit.Assert.*; public class HelloFunctionTest { @Rule public final FnTestingRule testing = FnTestingRule.createDefault(); @Test public void shouldReturnGreeting() { testing.givenEvent().enqueue(); testing.thenRun(HelloFunction.class, "handleRequest"); FnResult result = testing.getOnlyResult(); assertEquals("Hello, world!", result.getBodyAsString()); } }
空のリクエストボディで関数を実行した結果が"Hello, world!"
という文字列かどうかを試す試験でした。入出力の JSON 可に伴い、リクエスト用の JSON を用いて関数を実行した結果が検証用の JSON と同一かを試験します。
リクエスト用 JSON
{ "name": "Bob" }
検証用 JSON
{ "salutation": "Hello Bob" }
テストコードではこれらのJSON をエスケープした文字列を使って試験します。リクエストボディに"{\"name\":\"Bob\"}"
を指定して暗数を実行した結果が"{\"salutation\":\"Hello Bob\"}"
であることを検証します。
JSON対応後
package com.example.fn; import com.fnproject.fn.testing.*; import org.junit.*; import static org.junit.Assert.*; public class HelloFunctionTest { @Rule public final FnTestingRule testing = FnTestingRule.createDefault(); @Test public void shouldReturnGreeting(){ testing.givenEvent().withBody("{\"name\":\"Bob\"}").enqueue(); testing.thenRun(HelloFunction.class,"handleRequest"); FnResult result = testing.getOnlyResult(); assertEquals("{\"salutation\":\"Hello Bob\"}", result.getBodyAsString()); } }
デプロイと実行
現在の位置とファイルの確認
> pwd /home/chiroito/javafn > ls func.yaml pom.xml src
ファンクションを Fn Server へデプロイします。
> fn deploy --app myapp
デプロイが成功したら、ファンクションを実行してみましょう。現段階(0.4.9)ではfn call
ではリクエストボディを含めることには対応していないようですので、curl
を使用してファンクションを実行します。
本環境では Fn Server は localhost の 8080 番ポートで動いています。
>curl --data '{"name": "Bob"}' http://localhost:8080/r/javafn/myapp {"salutation":"Hello Bob"}