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