📚
API Gateway にmultipart/form-dataでファイルアップロードしたかった話
ある日、私はAWS Serverless Application Model(SAM)でGoファイルをアップロードしてastを返してくれるAPIを作ろうとしていました
main.go
package main
import (
"fmt"
)
func main() {
fmt.Println("Wow!")
}
上記のファイルをmultipart/form-dataで下のように送信しました。
file: main.go
description: "nice to meet you !"
そして、おもむろにrequest.Bodyを取り出すと、、、
main.go
func main() {
lambda.Start(start)
}
func start(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
// ここ
println(request.Body)
}
ターミナル(結果)
----------------------------407965267923073511136631
Content-Disposition: form-data; name="file"; filename="main.go"
Content-Type: application/octet-stream
package main
import (
"fmt"
)
func main() {
fmt.Println("Wow!")
}
----------------------------407965267923073511136631
Content-Disposition: form-data; name="description"
nice to meet you !
----------------------------407965267923073511136631--
stringやんけ...
だから公式ではファイル送信時にbase64で送れいうとったんか...
...
でも、どうしてもファイルを送信したかったのでmultipart/form-data形式の文字列を読み込むパッケージを作りました🎉
go get github.com/gari8/shuttle
とかでインストールできます。
これはめちゃくちゃ薄いパッケージなのですが、multipart/form-dataの文字列を読み込んでname属性を指定して値を取り出すものです。
今回の場合main.goで使うと下記のようになります。
main.go
import (
...
"github.com/gari8/shuttle"
)
const (
boundary = "---------------------------"
)
func main() {
lambda.Start(start)
}
func start(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
// ここでmultipart文字列を第一引数に、バウンダリー文字列(------こんな感じのやつ)を第二引数に渡す
sh := shuttle.New(request.Body, boundary)
// 見たいものを指定
fmt.Println(sh.Launch("description"))
fmt.Println(sh.Launch("file"))
}
ターミナル(結果)
nice to meet you !
package main
import (
"fmt"
)
func main() {
fmt.Println("Wow!")
}
以下のようにdescription
とfile
それぞれの値を取り出せます!
使う場面はあまりなさそうですが、誰かの助けになれば幸いです!
Discussion