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

# 概要

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

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

![fn_go.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65002/2d694d4e-830a-38fc-627c-fade8a640c73.png)

## 想定読者

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

# 準備

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

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

# Pythonでfunctionを動かす

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

## Fn上のアプリ

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

## 登録

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

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

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

```console
$ ls
func.go  func.yaml  go.mod
```

## コードを変更

下記のような、入力値のleftとrightを足して返すような関数に書き換えます。

```go

```

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

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

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

```console
$ fn --verbose deploy --app calc-fn-app --local -w /home/opc/calc-fn-app/divide
Deploying divide to app: calc-fn-app
Bumped to version 0.0.3
Building image fndemouser/divide:0.0.3
FN_REGISTRY:  fndemouser
Current Context:  default
Sending build context to Docker daemon  6.656kB
Step 1/10 : FROM fnproject/go:dev as build-stage
 ---> 96c8fb94a8e1
Step 2/10 : WORKDIR /function
 ---> Using cache
 ---> d5da6400b169
Step 3/10 : WORKDIR /go/src/func/
 ---> Using cache
 ---> 1f6d9b0553c1
Step 4/10 : ENV GO111MODULE=on
 ---> Using cache
 ---> 76b3280f859f
Step 5/10 : COPY . .
 ---> 8b49123ddb74
Step 6/10 : RUN cd /go/src/func/ && go build -o func
 ---> Running in 4ebf2264a532
go: finding github.com/pkg/errors v0.9.1
go: finding github.com/cockroachdb/apd v1.1.0
go: finding github.com/fnproject/fdk-go v0.0.1
go: downloading github.com/fnproject/fdk-go v0.0.1
go: downloading github.com/cockroachdb/apd v1.1.0
go: downloading github.com/pkg/errors v0.9.1
Removing intermediate container 4ebf2264a532
 ---> 4804dafb59b8
Step 7/10 : FROM fnproject/go
 ---> bc635796c9df
Step 8/10 : WORKDIR /function
 ---> Using cache
 ---> e16151850db8
Step 9/10 : COPY --from=build-stage /go/src/func/func /function/
 ---> 30d845c22c66
Step 10/10 : ENTRYPOINT ["./func"]
 ---> Running in b223d912dc43
Removing intermediate container b223d912dc43
 ---> 508f6decd40d
Successfully built 508f6decd40d
Successfully tagged fndemouser/divide:0.0.3

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

```

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

```console
$ fn list fn calc-fn-app
NAME            IMAGE                           ID
divide          fndemouser/divide:0.0.3         01E0GXAP0ENG8G00GZJ0000026
multiply        fndemouser/multiply:0.0.5       01E086F2D6NG8G00GZJ000001E
plus            fndemouser/plus:0.0.2           01E0393FDCNG8G00GZJ000000E
subtract        fndemouser/subtract:0.0.3       01E05KAKGENG8G00GZJ0000013
```

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

```console
$ docker images | grep divide
fndemouser/divide     0.0.3               508f6decd40d        About a minute ago   17.1MB
```


## 実行

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

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

8/4の結果である2が返ってきています。

# おわりに

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

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

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

このエントリを書くにあたり、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に