【第5回】Go言語(Golang)入門~REST API実装編~
2021.12.20
第5回~Go言語(Golang)入門~
(株)ライトコードの笹川(ささがわ)です!
前回は、RESR APIを構築するための機能を実装しました。
今回は、POSTで受け取った値をFirestoreへ追加し、追加されたデータをレスポンスとして返す実装をしてみたいと思います。
前回の記事はこちら
Firestoreへのデータ追加の実装を作ってみよう!
まずは、Firebaseの初期化処理を実装しようと思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | func firebaseInit(ctx context.Context) (*firestore.Client, error) { // Use a service account sa := option.WithCredentialsFile("path/to/serviceAccount.json") app, err := firebase.NewApp(ctx, nil, sa) if err != nil { log.Fatalln(err) return nil, err } client, err := app.Firestore(ctx) if err != nil { log.Fatalln(err) return nil, err } return client, nil } |
前回のFirestoreでのデータ操作をした際の記述に対して、戻り値を用意してます。
初期化処理は共通処理となるので、メソッド化しておいたほうが効率が良さそうです。
初期化処理だけで実行をしても意味がないので、このまま、データを追加する処理をしてからclientをクローズするまでを実装します。
Firestoreへのデータ追加処理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | func dataAdd(name string, age string, address string) error { ctx := context.Background() client, err := firebaseInit(ctx) if err != nil { log.Fatal(err) } // データ追加 _, err = client.Collection("users").Doc(name).Set(ctx, map[string]interface{}{ "age": age, "address": address, }) if err != nil { log.Fatalf("Failed adding alovelace: %v", err) } // 切断 defer client.Close() // エラーなしは成功 return err } |
Firestoreへのデータ追加処理は、これで完了です。
それでは、リクエストを受け取って、Json をパースして、Firestore へのデータ追加処理を呼び出してみましょう!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | type User struct { Name string `json:"name"` Age string `json:"age"` Address string `json:"address"` } func main() { e := echo.New() e.POST("/users", addUser) e.Logger.Fatal(e.Start(":1323")) } func addUser(c echo.Context) error { u := new(User) if error := c.Bind(u); error != nil { return error } // データ追加呼び出し if error := dataAdd(u.Name, u.Age, u.Address); error != nil { return error } return c.JSON(http.StatusOK, u) } |
これで実行してみます。
実行
リクエストのヘッダーに Content-Type: application/json を入れて、下記の Json を body にセットしてからリクエストしてみましょう!
1 2 3 4 5 | { "name": "test1", "age": "18", "address": "kanda" } |
curl だと下記のようなコマンドです。
1 2 3 4 5 6 7 8 | curl -X POST \ http://localhost:1323/users \ -H 'Content-Type: application/json' \ -d '{ "name": "test1", "age": "18", "address": "kanda" }' |
今の実装だと追加に失敗しない限りは、リクエストの body に入れた Json を返すようにしています。
笹川は、Postman を利用して実行してみました。
無事に成功です!
データを追加成功のレスポンスとしてFirestoreのデータを返してみよう!
データ追加のあとに、データ読み取りの処理を入れて、Json で返します。
実装
それでは、実装してみましょう!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | // Users はユーザー情報の配列 type Users *[]User func dataAdd(name string, age string, address string) ([]*User, error) { ctx := context.Background() client, err := firebaseInit(ctx) if err != nil { log.Fatal(err) } // データ追加 _, err = client.Collection("users").Doc(name).Set(ctx, map[string]interface{}{ "age": age, "address": address, }) if err != nil { log.Fatalf("Failed adding alovelace: %v", err) } // データ読み込み allData := client.Collection("users").Documents(ctx) // 全ドキュメント取得 docs, err := allData.GetAll() if err != nil { log.Fatalf("Failed adding getAll: %v", err) } // 配列の初期化 users := make([]*User, 0) for _, doc := range docs { // 構造体の初期化 u := new(User) // 構造体にFirestoreのデータをセット mapToStruct(doc.Data(), &u) // ドキュメント名を取得してnameにセット u.Name = doc.Ref.ID // 配列に構造体をセット users = append(users, u) } // 切断 defer client.Close() // 成功していればusersに値が、失敗の場合はerrに値が入る return users, err } // map -> 構造体の変換 func mapToStruct(m map[string]interface{}, val interface{}) error { tmp, err := json.Marshal(m) if err != nil { return err } err = json.Unmarshal(tmp, val) if err != nil { return err } return nil } |
想定よりも複雑な処理になりました。
データを読み取る実装自体は、以前の記事でも実装したので説明を割愛します。
今回のつまづきポイントは、Firestoreから受け取った値がmap型であり、それをJson形式で返すために試行錯誤した点です。
確認
追加処理を実装した際に test1 のユーザーは追加済みなので、test2 のユーザーを追加して確認してみます。
curl だと下記のリクエストで確認できます。
1 2 3 4 5 6 7 8 | curl -X POST \ http://localhost:1323/users \ -H 'Content-Type: application/json' \ -d '{ "name": "test2", "age": "28", "address": "chiba" }' |
レスポンスは、test1 と test2 の情報が下記のように配列で戻ってきたら成功です!
1 2 3 4 5 6 7 8 9 10 11 12 | [ { "name": "test1", "age": "18", "address": "kanda" }, { "name": "test2", "age": "28", "address": "chiba" } ] |
毎度のごとくPostmanで確認してみます。
無事に成功しました!
第6回へつづく!
今回は、REST APIとしてGo言語(Golang)からFirestoreのデータを追加してみました。
1つ1つの実装は難しくないのですが、組み合わせるとどうしても複雑化していってしまいますね。
Go言語(Golang)は、パッケージ分割などでフィルや処理を分割できます。
そのため、整理しながら開発していくのが良いように思います。
今後は、「実際にデプロイ」してみたり、「Androidアプリ等とのデータのやり取り」をしてみたいなと思います!
今回作成したgoファイルは、こちらのリポジトリにて管理しております。
次回の記事はこちら
オススメのGo入門本
こちらの記事もオススメ!
第1回の記事はこちら
書いた人はこんな人
- 新潟生まれ新潟育ち本業はモバイルアプリエンジニア。
日々、猫(犬)エンジニアとして活躍中!
- IT技術2月 19, 2024アプリ開発のすゝめ
- IT技術9月 20, 2023開発効率を少しだけ上げるGithubActionsの便利な使い方
- IT技術4月 7, 2023【ISUCON部】ライトコードISUCON部 始動!
- IT技術4月 18, 2022【Android】Webでよくみる入力Boxを手作り