lambda function URLsのeventをプロキシしてhttp apiに流す

小規模なSlack BotはAWS lambda functions URLsに作ると楽だった の話の続きです. 先日lambda function URLsを利用してhttp apiのような実装を記述する方法を紹介しました. 今回は httpadapter と net/http/httputil を利用してlambda function URLsをリバースプロキシとして動かしてbackend apiに流す方法です. 概略図 実装 普通のリバースプロキシを実装するときはhttputil.ReverseProxyを定義してserverを作って待ち受けるわけですが、 今回の場合はhttputil.ReverseProxyを定義した後httpadapter.NewV2に食わせるだけですね. 次の例はlambdaのeventを受け取ったあとlocalで8080ポートで待ち受けるhttp serverにリクエストを流すproxyの例です. func main() { director := func(req *http.Request) { req.URL.Scheme = "http" req.URL.Host = ":8080" } rp := &httputil.ReverseProxy{Director: director} lambda.Start(httpadapter.NewV2(rp).ProxyWithContext) } すべてlambda関数上で完結させたい場合は func init() などでapiを予め立ち上げた後プロキシしてあげると良いと思います. github.com/ieee0824/le2hp ではそのような実装にしました.

2月 2, 2023

小規模なSlack BotはAWS lambda functions URLsに作ると楽だった

はじめに ここで言う小規模なSlack Botというのは個人で使うようなBotやチームレベルで使う書き捨てレベルのようなもののことです. このような想定のBotを実装するときそこまでちゃんとインフラコストをかけたくありません. 自前でサーバーを用意したとして処理内容と維持管理費用が割に合わないのです. 無料でhttp serverを立ち上げることができるけど定期的にリクエストを送っておかなければプロセスがkillされるようなサービスもあります. そのようなサービスを使う場合定期的にリクエストを送るか立ち上がるまで待った後Botのためのリクエストを送らないと機能しない問題があります. それらの問題を解消するのにlambda functions URLsは要件にあってそうだなぁと思いました. lambda function URLsはlambdaなので課金が発生する時間単位が短いのでたまにしか実行されないようなものでもサーバーを立てて実現するよりお金がかからないです. またlambda function URLsにリクエストを投げるとlambdaのeventが発火して即時にlambda関数が実行されるので待ち時間も発生しません. 一つ問題があるとしたらlambdaのeventとして作成したプログラムから見えるので普段Botをhttpのapiとして実装している場合はhttp requestとlambdaのeventとのギャップを埋める必要があるということです. とはいえそこまで大きな問題にはならないと思います. 特にGo言語の場合は github.com/awslabs/aws-lambda-go-api-proxy/httpadapter を利用するとほとんどhttp serverと同じような実装でアプリケーションを作ることができます. Goでlambda function URLsを使ってリクエスト受ける例 github.com/awslabs/aws-lambda-go-api-proxy/httpadapter を利用した実装例を上げておきます. frameworkを利用しない例 frameworkを利用しない例です. 生のGo言語でhttp serverを実装したことがある人なら雰囲気が解ると思います. package main import ( "io" "net/http" "github.com/aws/aws-lambda-go/lambda" "github.com/awslabs/aws-lambda-go-api-proxy/httpadapter" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "It Works!") }) // lambda function URLsはapi gateway v2と同じeventなのでv2にする必要がある lambda.Start(httpadapter.NewV2(http.DefaultServeMux).ProxyWithContext) } Ginを利用した例 frameworkを利用することもできます. 例えばGinを利用する場合は次のように記述ができます. package main import ( "context" "net/http" "github....

1月 31, 2023

fileのopen modeに関して

はじめに 最近というほどでもないがfileを開いて編集したあと上書きをして保存するみたいなプログラムを実装した. そのときにとあるバグを仕込んでしまったので書いておく. ファイルを開くときについて C言語とかを書いたことがある人ならわかると思うだろうが, fileを開いたときにはどういうmodeでファイルを開くかというmodeが存在する. それがGo言語だろうがC言語だろうがOSがそういうふうにできていれば関係なく存在する. 例えばGo言語でfileをreadonlyとして開くときはしばしば os.Open 関数を利用する. f, err := os.Open("適当なfile名") if err != nil { // なんかエラー処理 } ... os.Open の中身は次のようになっている. func Open(name string) (*File, error) { return OpenFile(name, O_RDONLY, 0) } O_RDONLY がopen modeになっている. ちなみに O_RDONLY 以外はこのようになっている. mode type 意味 O_RDONLY 読み込み可 O_WRONLY 書き込み可 O_RDWR 読み書き可 詳しいいことは他の資料をあさって読んだほうがよく分かると思う. Go言語でファイルを開くときは他にもいくつか方法がある. 例えば os.Create などだ....

9月 29, 2018