• トップ
  • ブログ一覧
  • 【第10回】Go言語(Golang)入門~ObjectBox活用編~
  • 【第10回】Go言語(Golang)入門~ObjectBox活用編~

    笹川(エンジニア)笹川(エンジニア)
    2019.11.13

    IT技術

    第10回~Go言語(Golang)入門~

    秋山笹川先生

    (株)ライトコードの笹川(ささがわ)です!

    今回は、前回に引き続き、ObjectBox を利用して、 「echo + ObjectBox」のREST APIを作ってみようと思います!

    それでは、いってみましょう!

    前回の記事はこちら

    featureImg2019.11.06【第9回】Go言語(Golang)入門~ObjectBox導入編~第9回~Go言語(Golang)入門~笹川先生(株)ライトコードの笹川(ささがわ)です!前回は、Goの環境やパッケージ...

    データ追加エンドポイントを実装してみよう

    まずは、データの操作の前にテーブルの実装をします。

    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ファイルは、こちらのリポジトリにて管理しています。

    次回の記事はこちら

    featureImg2019.11.20【第11回】Go言語(Golang)入門~FCM送信編~第11回~Go言語(Golang)入門~笹川先生(株)ライトコードの笹川(ささがわ)です!今回は、Firebase C...

    オススメのGo入門本

    Goプログラミング実践入門 標準ライブラリでゼロからWebアプリを作る
    Goプログラミング実践入門 標準ライブラリでゼロからWebアプリを作る

     

    こちらの記事もオススメ!

    featureImg2020.08.08Go言語 特集知識編人気急上昇中のGo言語(Golang)って何だ?実装編Go言語(Golang)入門...

    featureImg2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...

    第1回の記事はこちら

    featureImg2019.09.13【第1回】Go言語(Golang)入門~環境構築編~第1回~Go言語(Golang)を習得したい!~笹川先生(株)ライトコードでモバイルアプリケーション開発をしている笹川...

    笹川(エンジニア)

    笹川(エンジニア)

    おすすめ記事