Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Cloud Firestore With Go

mtskhs
April 24, 2021

Cloud Firestore With Go

GoConference2021Spring LTでの発表資料です。

* そもそもCloud Firestoreって
* Cloud FirestoreのGoによる開発爆速入門
* Cloud Firestoreの運用ツール開発における知見

mtskhs

April 24, 2021
Tweet

More Decks by mtskhs

Other Decks in Programming

Transcript

  1. Cloud Firestore
    With Go
    @mtskhs
    Go Conference 2021 Spring LT
    2021/04/24

    View full-size slide

  2. Who am I
    2
    ●  @mtskhs
    ● Go / React Native / TypeScript
    ● Go Conference 2019 Autumn
    Goにおける API Client実装パターン
    https://speakerdeck.com/matsu0228/api-client-implementation-pattern-in-go
    ● fsrpl - Cloud Firestoreの運用ツール
    https://firebaseopensource.com/projects/matsu0228/fsrpl/

    View full-size slide

  3. Ad
    3
    JavaScript と Firestore
    のテストノウハウ
    について書籍化
    🔍 Firestore Testing

    View full-size slide

  4. Contents
    1. Cloud Firestore With Go
    1.1. About Cloud Firestore
    1.2. When to use Go SDK
    1.3. How to use Go SDK
    1.4. Credentials on GCP
    2. fsrpl - Firestore replication tool written by Go
    2.1. about fsrpl
    2.2. Key points for OSS development
    4

    View full-size slide

  5. 1-1. About Cloud Firestore
    5
    Firestoreは、Firebaseに内包される主要なマネージドデータベース
    https://firebase.google.com/?hl=ja

    View full-size slide

  6. 1-1. About Cloud Firestore
    6
    👍👍 Pros
    ● clientから直接接続できる(そのためのセキュリティールール)
    ● リアルタイム更新     ※⚠GoのSDKではサポート外
    ● スケーラビリティ
    ● NoSQL / 柔軟なスキーマ変更が可能
    ● 低価格
    ● トランザクション・整合性

    View full-size slide

  7. 1-1. About Cloud Firestore
    7
    😦😦 Cons
    ● 検索が苦手
    ○ Like句のサポートなし
    ○ Where句やOrder句に指定したフィールドを持たないドキュメント
    は検索ヒットしない(ゼロ埋めが必要)
    ○ Where IN句のサポートがあるが、10件以下しか指定できない
    ○ 複数のWhere条件を指定するにはindex追加が必要
    ● 総じて、設計を工夫しないとデータ取得に時間がかかる
    ○ ↑CQRS(コマンドクエリ責務分離。書き込みと読み込みのモデルを
    分ける)の活用など、工夫は可能

    View full-size slide

  8. 1-2. When to use Firestore Go
    8
    前述のとおり、
    ● Firestoreには、Clientから直接参照・書き込みすることができる
    ● GoのSDKではサポート対象外機能もいくつかある(リアルタイム更新
    ・BulkWriterなど)
    使い所(だと個人的に感じるの)は、
    ● 外部からのデータを タイムラグをできるだけ少なくしてFirestoreに保
    存する場合
    ● Firestore Triggerが使えるCloud Functionsを使う際、限られたリソー
    ス(メモリ/最大処理時間9min)で重い処理を扱う場合 etc
    ● Goが書きたいとき😌

    View full-size slide

  9. 1-3. How to use Go SDK
    9
    ● Read - Get
    dsnap, err := client.Collection("cities").Doc("BJ").Get(ctx)
    if err != nil { return nil, err }
    var c City
    dsnap.DataTo(&c) // 👈構造体に
    fmt.Printf("Document data: %#v\n", c)
    https://firebase.google.com/docs/firestore/query-data/get-data#custom_objects

    View full-size slide

  10. 1-3. How to use Go SDK
    10
    ● Read - Query
    iter := client.Collection("cities").Where("capital", "==", true)
    .Documents(ctx) // 👈 "==" がクエリ演算子。次の値と等しいとき
    for {
    doc, err := iter.
    Next()
    if err == iterator.Done { break }
    if err != nil { return err }
    fmt.Println(doc.Data())
    }
    https://firebase.google.com/docs/firestore/query-data/get-data#get_multiple_documents_from_a_collecti

    View full-size slide

  11. 1-3. How to use Go SDK
    11
    ● Read - Query operators
    https://firebase.google.com/docs/firestore/query-data/queries#query_operators
    ● < 次の値未満
    ● <= 次の値以下
    ● == 次に等しい
    ● > 次の値より大きい
    ● >= 次の値以上
    ● != 次と等しくない
    ● array-contains 配列要素を含む
    ● array-contains-any いずれかに一致する配列要素を含む。最大
    10件まで
    ● In / not-in いずれかに一致する/しない。最大10件まで

    View full-size slide

  12. 1-3. How to use Go SDK
    12
    ● Write - insert or update all fields
    _, err := client.Collection("cities").Doc("LA").Set(ctx,
    map[string]interface{}{
    "name": "Los Angeles",
    "state": "CA",
    "country": "USA",
    })// 👈データ型は、struct tag付きの構造体でもよい
    if err != nil { return err }
    https://firebase.google.com/docs/firestore/manage-data/add-data#set_a_docume

    View full-size slide

  13. 1-3. How to use Go SDK
    13
    ● Write - insert or update partial fields
    _, err := client.Collection("cities").Doc("BJ").Set(ctx,
    map[string]interface{}{
    "capital": true,
    }, firestore.MergeAll) // 👈Setの第二引数にMergeAllする
    if err != nil { return err }
    https://firebase.google.com/docs/firestore/manage-data/add-data#update-da

    View full-size slide

  14. 1-3. How to use Go SDK
    14
    ● Write - delete
    _, err := client.Collection("cities").Doc("DC").Delete(ctx)
    if err != nil { return err }
    https://firebase.google.com/docs/firestore/manage-data/delete-data#delete_documen

    View full-size slide

  15. 1-3. How to use Go SDK
    15
    ● Transaction
    ref := client.Collection("cities").Doc("SF")
    err := client. RunTransaction (ctx, func(ctx context. Context, tx *firestore. Transaction) error
    {
    doc, err := tx. Get(ref) // tx.Get, NOT ref.Get!
    if err != nil { return err }
    pop, err := doc. DataAt("population")
    if err != nil { return err }
    // 👇更新処理中(tx.Set)に同時編集が影響する場合は、トランザクション関数が複数回実行される
    return tx.Set(ref, map[string]interface{}{ "population": pop.(int64) + 1,},
    firestore.MergeAll)
    })
    if err != nil { return err }
    https://firebase.google.com/docs/firestore/manage-data/transactions#transaction

    View full-size slide

  16. 1-4. Credentials on GCP
    16
    ● GCP上で認証・初期化する
    import (
    firebase "firebase.google.com/go"
    "google.golang.org/api/option"
    )
    // ...
    ctx := context. Background()
    conf := &firebase. Config{ProjectID: projectID} // projectIDを指定するだけでよい
    app, err := firebase. NewApp(ctx, conf)
    if err != nil { return err }
    client, err := app. Firestore(ctx)
    if err != nil { return err }
    defer client.Close()
    https://firebase.google.com/docs/firestore/quickstart#initialize

    View full-size slide

  17. 1-4. Credentials on GCP
    17
    ● GCP以外で認証する - サービスアカウントの秘密鍵を環境変数指定
    // 環境変数GOOGLE_APPLICATION_CREDENTIALS を設定して実行する
    // export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/service-account.json"
    import (
    firebase "firebase.google.com/go"
    )
    // ...
    ctx := context. Background()
    app, err := firebase. NewApp(ctx, nil) // optionは指定しないでよい
    if err != nil { return err }
    client, err := app. Firestore(ctx)
    if err != nil { return err }
    defer client.Close()
    https://firebase.google.com/docs/admin/setup#initialize-sdk

    View full-size slide

  18. Contents
    1. Cloud Firestore With Go
    1.1. About Cloud Firestore
    1.2. When to use Go SDK
    1.3. How to use Go SDK
    1.4. Credentials on GCP
    2. fsrpl - Firestore replication tool written by Go
    2.1. about fsrpl
    2.2. Key points for OSS development
    18

    View full-size slide

  19. 2-1. About fsrpl
    19
    ● Firestoreの運用における辛みを解決できるツール
    ○ copy - 指定したドキュメントを、別のパスにコピー
    ○ copy - 指定したFirestoreから、別のFirestoreへコピー
    ○ dump - 指定したドキュメントを、ローカルにjsonファイルとしてダン

    ○ restore - ローカルのjsonファイルを指定したパスにリストア
    https://firebaseopensource.com/projects/matsu0228/fsrpl/

    View full-size slide

  20. 2-2. Key points for OSS development
    20
    ● サービス開発を通して生じた辛みを解決できるものを💪
    ○ 自サービスの特定ユースケースに閉じずに一般化
    ● IFを意識🔧 既存の類似ライブラリ(mysqldump)と同様に
    ● 機会を探した - Firebase Open Source
    https://firebaseopensource.com

    View full-size slide

  21. Summary
    1. Cloud FirestoreをGoで扱う方法
    ● そもそもFirestoreって
    ● 簡単なCRUD
    ● 環境に応じたFirestoreの初期化方法
    2. Fsrpl - Firestore運用ツールの紹介
    ● copy, dump, restore
    ● OSS開発における知見
    21

    View full-size slide