【第10回】Go言語(Golang)入門~ObjectBox活用編~
IT技術
第10回~Go言語(Golang)入門~
(株)ライトコードの笹川(ささがわ)です!
今回は、前回に引き続き、ObjectBox を利用して、 「echo + ObjectBox」のREST APIを作ってみようと思います!
それでは、いってみましょう!
前回の記事はこちら
データ追加エンドポイントを実装してみよう
まずは、データの操作の前にテーブルの実装をします。
1package model
2
3//go:generate go run github.com/objectbox/objectbox-go/cmd/objectbox-gogen
4
5type Favorite struct {
6 Id uint64
7 Name string
8 Description string
9 CreatedAt string
10}
テーブルの構造体を記述したあとに、おまじないを実行します。
1go generate ./...
これで、favorite.obx.go が作成されたら、テーブルデータの用意は完了です。
データベース接続&データ追加までの実装
それでは、前回同様に、データベースに接続してデータ追加までを実装します。
1package main
2
3import (
4 "go_example/model"
5 "net/http"
6 "time"
7
8 "github.com/labstack/echo"
9 "github.com/objectbox/objectbox-go/objectbox"
10)
11
12func main() {
13 e := echo.New()
14 e.POST("/add", addFavorite)
15 e.Logger.Fatal(e.Start(":1323"))
16}
17
18func addFavorite(c echo.Context) error {
19 favorite := new(AddFavoriteRequest)
20 // データ受け取り
21 if error := c.Bind(favorite); error != nil {
22 return error
23 }
24
25 // initialize
26 ob := initObjectBox()
27 defer ob.Close()
28 box := model.BoxForFavorite(ob)
29
30 // データ追加
31 id, _ := box.Put(&model.Favorite{
32 Name: favorite.Name,
33 Description: favorite.Description,
34 CreatedAt: time.Now().String(),
35 })
36
37 // 追加したデータを取得
38 result, _ := box.Get(id)
39
40 // 追加したデータをレスポンスに渡す
41 return c.JSON(http.StatusOK, result)
42}
43
44// AddFavoriteRequest データ追加リクエストのパース用構造体
45type AddFavoriteRequest struct {
46 Name string `json:"name"`
47 Description string `json:"description"`
48}
49
50func initObjectBox() *objectbox.ObjectBox {
51 objectBox, _ := objectbox.NewBuilder().Model(model.ObjectBoxModel()).Build()
52 return objectBox
53}
ObjectBox も echo も以前の記事で取り扱っているので、一つ一つの実装追加は省きます。
この形式でレスポンスが返ってきたら成功です。
1{
2 "Id": 0,
3 "Name": "hoge",
4 "Description": "fuga",
5 "CreatedAt": "1970-01-01 00:00:00 +0900"
6}
確認
では、実行してみます!
1$ curl -X POST http://localhost:1323/add -H 'Content-Type: application/json' -d '{ "name": "猫" , "Description": "モフモフだから"}'
結果はこちら。
1{
2 "Id": 1,
3 "Name": "猫",
4 "Description": "モフモフだから",
5 "CreatedAt": "2019-10-03 12:13:01.194436 +0900 JST m=+97.178858296"
6}
CreatedAt が、Date型を気にせず文字列変換したため、分かりにくい表記になっていますが成功です!
修正
ちなみに、下記のようにすれば分かりやすくなります。
1const dateLayout = "2006/01/02 15:04:05"
2// データ追加
3id, _ := box.Put(&model.Favorite{
4 Name: favorite.Name,
5 Description: favorite.Description,
6 CreatedAt: time.Now().Format(dateLayout),
7})
1"CreatedAt": "2019/10/03 12:24:47"
dateLayout の中身が、よく分からない日付ですね(笑)
理由は、以下の記事に載っていますので、気になる方はご参考ください。
【参考記事】
https://qiita.com/ruiu/items/5936b4c3bd6eb487c182
データを検索してみよう
データの「Name」と「Description」の、それぞれと両方で検索ができるようにしてみます。
Name の検索を実装
まずは、「Name」の検索を実装します。
1func findName(box *model.FavoriteBox, name string) ([]*model.Favorite, error) {
2 return box.Query(model.Favorite_.Name.Contains(name, true)).Find()
3}
Descriptionの検索を実装
次に、「Description」の検索を実装します。
1func findDescription(box *model.FavoriteBox, description string) ([]*model.Favorite, error) {
2 return box.Query(model.Favorite_.Description.Contains(description, true)).Find()
3}
NameとDescription両方での検索の実装
最後に、「Name」と「Description」の両方での検索を実装します。
1func findKeyword(box *model.FavoriteBox, keyword string) ([]*model.Favorite, error) {
2 return box.Query(objectbox.Any(model.Favorite_.Name.Contains(keyword, true),
3 model.Favorite_.Description.Contains(keyword, true))).Find()
4}
呼び出しを含めると、下記のようになります。
1package main
2
3import (
4 "go_example/model"
5 "net/http"
6 "time"
7
8 "github.com/labstack/echo"
9 "github.com/objectbox/objectbox-go/objectbox"
10)
11
12func main() {
13 e := echo.New()
14 e.POST("/add", addFavorite)
15 e.POST("/find", find)
16 e.Logger.Fatal(e.Start(":1323"))
17}
18
19func find(c echo.Context) error {
20 name := c.FormValue("name")
21 description := c.FormValue("description")
22 keyword := c.FormValue("keyword")
23 // パラメーターなしの場合はエラーで返す
24 if name == "" && description == "" && keyword == "" {
25 return c.JSON(http.StatusNotFound, "param is not found")
26 }
27
28 // テーブル呼び出し
29 box := getBox()
30
31 // NameでLIKE検索
32 if name != "" {
33 result, error := findName(box, name)
34 if error != nil {
35 return error
36 }
37 return c.JSON(http.StatusOK, result)
38 }
39
40 // DescriptionでLIKE検索
41 if description != "" {
42 result, error := findDescription(box, description)
43 if error != nil {
44 return error
45 }
46 return c.JSON(http.StatusOK, result)
47 }
48
49 // Name,DescriptionでのLIKE検索
50 result, error := findKeyword(box, keyword)
51 if error != nil {
52 return error
53 }
54
55 return c.JSON(http.StatusOK, result)
56}
57
58func findName(box *model.FavoriteBox, name string) ([]*model.Favorite, error) {
59 return box.Query(model.Favorite_.Name.Contains(name, true)).Find()
60}
61
62func findDescription(box *model.FavoriteBox, description string) ([]*model.Favorite, error) {
63 return box.Query(model.Favorite_.Description.Contains(description, true)).Find()
64}
65
66func findKeyword(box *model.FavoriteBox, keyword string) ([]*model.Favorite, error) {
67 return box.Query(objectbox.Any(model.Favorite_.Name.Contains(keyword, true),
68 model.Favorite_.Description.Contains(keyword, true))).Find()
69}
先に、いくつかデータを追加しておきます。
1curl -X POST http://localhost:1323/add -H 'Content-Type: application/json' -d '{ "name": "犬" , "Description": "かわいいから"}'
1curl -X POST http://localhost:1323/add -H 'Content-Type: application/json' -d '{ "name": "酒" , "Description": "美味しいから"}'
1curl -X POST http://localhost:1323/add -H 'Content-Type: application/json' -d '{ "name": "肉" , "Description": "美味しいから"}'
確認
それでは、検索してみましょう!
まずは、「Name」で検索してみます。
1$ curl -X POST http://localhost:1323/find -d 'name=猫'
2[{"Id":1,"Name":"猫","Description":"モフモフだから","CreatedAt":"2019/10/03 12:52:12"}]
次に、「Description」で検索してみます。
1$ curl -X POST http://localhost:1323/find -d 'description=かわいい'
2[{"Id":2,"Name":"犬","Description":"かわいいから","CreatedAt":"2019/10/03 12:56:52"}]
最後にキーワードで検索してみます。
1$ curl -X POST http://localhost:1323/find -d 'keyword=から'
2[{"Id":1,"Name":"猫","Description":"モフモフだから","CreatedAt":"2019/10/03 12:52:12"},{"Id":2,"Name":"犬","Description":"かわいいから","CreatedAt":"2019/10/03 12:56:52"},{"Id":3,"Name":"酒","Description":"美味しいから","CreatedAt":"2019/10/03 12:57:06"}]
うまく検索出来ていますね!
これで、検索の実装は完了です。
データを更新してみよう
「Name」をキーに、Descriptionの更新を実装してみます。
練習なので、検索してから更新して、更新結果をまた検索するように実装します。
1package main
2
3import (
4 "go_example/model"
5 "net/http"
6 "time"
7
8 "github.com/labstack/echo"
9 "github.com/objectbox/objectbox-go/objectbox"
10)
11
12func main() {
13 e := echo.New()
14 e.POST("/add", addFavorite)
15 e.POST("/find", find)
16 e.POST("/update", update)
17 e.Logger.Fatal(e.Start(":1323"))
18}
19
20func update(c echo.Context) error {
21 name := c.FormValue("name")
22 description := c.FormValue("description")
23 // パラメーターなしの場合はエラーで返す
24 if name == "" && description == "" {
25 return c.JSON(http.StatusNotFound, "param is not found")
26 }
27 box := getBox()
28 // 検索
29 list, error := box.Query(model.Favorite_.Name.Equals(name, true)).Find()
30 if error != nil {
31 return c.JSON(http.StatusNotFound, "item not found")
32 }
33 // 更新
34 for _, item := range list {
35 item.Description = description
36 box.Put(item)
37 }
38 // 更新結果取得
39 list, error = box.Query(model.Favorite_.Name.Equals(name, true)).Find()
40 if error != nil {
41 return error
42 }
43 return c.JSON(http.StatusOK, list)
44}
猫のDescriptionを「にゃーん」に変更してみます。
1$ curl -X POST http://localhost:1323/update -d 'name=猫&description=にゃーん'
2[{"Id":1,"Name":"猫","Description":"にゃーん","CreatedAt":"2019/10/03 12:52:12"}]
データが更新されているのが確認できました!
データを全件取得してみよう
全件のデータを取得するのは、今までの実装の中で一番簡単です。
全件検索のメソッドを呼び出して結果を返すだけです。
1package main
2
3import (
4 "go_example/model"
5 "net/http"
6 "time"
7
8 "github.com/labstack/echo"
9 "github.com/objectbox/objectbox-go/objectbox"
10)
11
12func main() {
13 e := echo.New()
14 e.POST("/add", addFavorite)
15 e.POST("/find", find)
16 e.POST("/update", update)
17 e.POST("/get/all", getAll)
18 e.Logger.Fatal(e.Start(":1323"))
19}
20
21func getAll(c echo.Context) error {
22 // テーブル呼び出し
23 box := getBox()
24
25 var list []*model.Favorite
26 list, err := box.GetAll()
27 if err != nil {
28 return err
29 }
30
31 return c.JSON(http.StatusOK, list)
32}
確認
それではリクエストしてみましょう。
1$ curl -X POST http://localhost:1323/get/all
2[{"Id":1,"Name":"猫","Description":"にゃーん","CreatedAt":"2019/10/03 12:52:12"},{"Id":2,"Name":"犬","Description":"かわいいから","CreatedAt":"2019/10/03 12:56:52"},{"Id":3,"Name":"酒","Description":"美味しいから","CreatedAt":"2019/10/03 12:57:06"}]
全件取れましたね!
データを削除してみよう
次は、「Name」をキーに削除する処理を実装します。
1package main
2
3import (
4 "go_example/model"
5 "net/http"
6 "time"
7
8 "github.com/labstack/echo"
9 "github.com/objectbox/objectbox-go/objectbox"
10)
11
12func main() {
13 e := echo.New()
14 e.POST("/add", addFavorite)
15 e.POST("/find", find)
16 e.POST("/update", update)
17 e.POST("/get/all", getAll)
18 e.POST("remove", remove)
19 e.Logger.Fatal(e.Start(":1323"))
20}
21
22func remove(c echo.Context) error {
23 name := c.FormValue("name")
24 if name == "" {
25 return c.JSON(http.StatusNotFound, "param is not found")
26 }
27 box := getBox()
28 // 検索
29 list, error := findName(box, name)
30 if error != nil {
31 return c.JSON(http.StatusNotFound, "item not found")
32 }
33 // 削除
34 for _, item := range list {
35 box.Remove(item)
36 }
37 // 削除結果取得
38 list, error = findName(box, name)
39 if error != nil {
40 return error
41 }
確認
それでは、リクエストしてみましょう!
今入っているデータは、下記のとおりです。
1[
2 {
3 "Id": 1,
4 "Name": "猫",
5 "Description": "にゃーん",
6 "CreatedAt": "2019/10/03 12:52:12"
7 },
8 {
9 "Id": 4,
10 "Name": "肉",
11 "Description": "美味しいから",
12 "CreatedAt": "2019/10/03 16:32:38"
13 },
14 {
15 "Id": 6,
16 "Name": "犬",
17 "Description": "かわいいから",
18 "CreatedAt": "2019/10/03 16:32:52"
19 }
20]
「肉」を指定して、削除してみましょう。
1$ curl -X POST http://localhost:1323/remove -d 'name=肉'
2[{"Id":1,"Name":"猫","Description":"にゃーん","CreatedAt":"2019/10/03 12:52:12"},{"Id":6,"Name":"犬","Description":"かわいいから","CreatedAt":"2019/10/03 16:32:52"}]
「肉」の項目が消えて、「猫」と「犬」のみになりましたね。
削除処理はこれで完了です!
第11回へつづく!
これで、ObjectBoxを用いたAPIの実装は終わりとなります。
簡単なアプリケーションやAPIなら有用じゃないでしょうか。
あまり認知度は高くないですが、多くの言語に対応しており、速度もそこそこ速いので ObjectBox はオススメです。
ぜひ使ってみてください!
なお、今回作成したgoファイルは、こちらのリポジトリにて管理しています。
次回の記事はこちら
2019.11.20【第11回】Go言語(Golang)入門~FCM送信編~第11回~Go言語(Golang)入門~笹川先生(株)ライトコードの笹川(ささがわ)です!今回は、Firebase C...
オススメの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技術