Fn Projectを使ってRubyで書いたfunctionを動かしてみる

# 概要

このエントリでは、OSSのFaaSサーバである「Fn Project」を使い、Rubyの関数を動かすパターンを扱います。

下図のようなRubyによる引き算の関数をFnのサーバにデプロイして動かします。

![vsc_subtract.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65002/9e41f9dd-7349-21b5-2c33-22eb9bccdf35.png)

## 想定読者

- Fn ProjectでのJavaScriptプログラムまだ自分で動かしていない方
- [「Fn Projectを使ってJavaScriptで書いたfunctionをNodeで動かしてみる」](https://qiita.com/hrkt/items/8dd1cd0e0e68e8575b6e)のRuby版に興味がある方

# 準備

Fn Projectを動かすまでのところは、別エントリ[「OCIのMicro InstanceでCentOSにFn Projectのサーバをインストールしてみる」](https://qiita.com/hrkt/items/e37bab448c8aa1b00117)を参照ください。

このエントリでは、筆者はOCIのMicro Instanceの上で作業しています。

# Rubyでfunctionを動かす

作業の基本的な流れは、[Introduction to Fn with Ruby](https://fnproject.io/tutorials/ruby/intro/)に書いてあるものに従っています。

## Fn上のアプリ

別のエントリ[「Fn Projectを使ってJavaScriptで書いたfunctionをNodeで動かしてみる」](https://qiita.com/hrkt/items/8dd1cd0e0e68e8575b6e)で、「fn create app」で、fn上に「calc-fn-app」アプリを作ってあるものにFunctionを追加する形をとります。

## 登録

/subractという位置にRubyで関数を一つ作るため、「fn init」を実行します。

```console
$ fn init --runtime ruby --trigger http subtract
Creating function at: ./subtract
Function boilerplate generated.
func.yaml created.
```

下記のような3つのファイルができています。

```console
$ ls
func.rb  func.yaml  Gemfile
```

## コードを変更

下記のような、入力値のleftからrightを引いて返すような関数に書き換えます。

```ruby
require 'fdk'
require 'bigdecimal'

def subtract(context:, input:)
  left = input.respond_to?(:fetch) ? input.fetch('left') : "0"
  right = input.respond_to?(:fetch) ? input.fetch('right') : "0"
  l = BigDecimal(left)
  r = BigDecimal(right)
  { result: (l - r).to_s }
end

FDK.handle(target: :subtract)

```



アプリデプロイします。「-w」で作業ディレクトリを指定して、登録しています。

```console
fn --verbose deploy --app calc-fn-app --local -w /home/opc/calc-fn-app/subtract
```

初回実行時には、以下のような流れとなるようです。

```console
$ fn --verbose deploy --app calc-fn-app --local -w /home/opc/calc-fn-app/subtract
Deploying subtract to app: calc-fn-app
Bumped to version 0.0.2
Building image fndemouser/subtract:0.0.2
FN_REGISTRY:  fndemouser
Current Context:  default
Sending build context to Docker daemon   5.12kB
Step 1/9 : FROM fnproject/ruby:dev as build-stage
 ---> 37ecabff3a24
Step 2/9 : WORKDIR /function
 ---> Using cache
 ---> c7a9fa394654
Step 3/9 : ADD Gemfile* /function/
 ---> Using cache
 ---> 0eb3e26ba0c2
Step 4/9 : RUN bundle install
 ---> Using cache
 ---> 1742c3ab6077
Step 5/9 : FROM fnproject/ruby
 ---> f5452b336752
Step 6/9 : WORKDIR /function
 ---> Using cache
 ---> 1a847b1ba6b0
Step 7/9 : COPY --from=build-stage /usr/lib/ruby/gems/ /usr/lib/ruby/gems/
 ---> Using cache
 ---> 024231201746
Step 8/9 : ADD . /function/
 ---> 0891f94df165
Step 9/9 : ENTRYPOINT ["ruby", "func.rb"]
 ---> Running in ed2ffef17490
Removing intermediate container ed2ffef17490
 ---> f886ccf5818c
Successfully built f886ccf5818c
Successfully tagged fndemouser/subtract:0.0.2

Updating function subtract using image fndemouser/subtract:0.0.2...
Successfully created function: subtract with fndemouser/subtract:0.0.2
Successfully created trigger: subtract
Trigger Endpoint: http://127.0.0.1:18080/t/calc-fn-app/subtract
```

fnのコマンドで確認します。(別エントリでplusを作ってあります)

```console
$ fn list fn calc-fn-app
NAME            IMAGE                           ID
plus            fndemouser/plus:0.0.2           01E0393FDCNG8G00GZJ000000E
subtract        fndemouser/subtract:0.0.2       01E05KAKGENG8G00GZJ0000013
```

Dockerのコマンドで確認すると、対応するコンテナのイメージができていることがわかります。

```console
$ docker images | grep subtract
fndemouser/subtract   0.0.2               f886ccf5818c        4 minutes ago       42.9MB
```




## 実行

登録時の末尾にあったURLにcurlでアクセスしてみます。

```console
$ curl -d '{"left":"1", "right":"2"}' http://127.0.0.1:18080/t/calc-fn-app/subtract
{"result":"-0.1e1"}
```

1-2の結果である-1が返ってきています。

これを指数形式で表示したくなかったときの修正をしてみます。

コードの下記の部分を修正します。

```ruby
  { result: (l - r).to_s("F") }
```

修正したFunctionをデプロイしなおします。(参照：[instance method BigDecimal#to_s](https://docs.ruby-lang.org/ja/latest/method/BigDecimal/i/to_s.html))

```console
$ fn --verbose deploy --app calc-fn-app --local -w /home/opc/calc-fn-app/subtract
(中略)
Successfully tagged fndemouser/subtract:0.0.3

Updating function subtract using image fndemouser/subtract:0.0.3...
```

前述と同じURLに、curlでアクセスしてみます。

```console
$ curl -d '{"left":"1", "right":"2"}' http://127.0.0.1:18080/t/calc-fn-app/subtract
{"result":"-1.0"}
```

意図した形のレスポンスが返ってきました。

# おわりに

このエントリでは、Fn projectを使ってRubyで書いたfunctionを動かしてみることを扱いました。

このエントリで使用したコードは、[https://github.com/hrkt/calc-fn-app/releases/tag/0.0.2](https://github.com/hrkt/calc-fn-app/releases/tag/0.0.2)のタグに格納してあります。

## 補足：外部ライブラリ

このエントリでは、外部ライブラリを使いませんでしたが、Gemfile中に記載することで、Ruby gemsを利用できます。

## 補足：このエントリを書くにあたり

このエントリを書くにあたり、OCIのマイクロインスタンス上に下記の状況を作り、ノートPCからクラウド側にsshでリモートでつないで作業しました。

- sshの先にscreenで複数枚のウインドウ上げておいて作業して
- VS CodeをWEBで動かして「[cdr/code-serverとOCIのAlways FreeのMicroインスタンスでVS Codeを動かしてみる](https://qiita.com/hrkt/items/44c78f71eb72f9d29f38)」
- Fn projectのサーバもそこで動かして
- コードはGitHubに