Firestore でカウントアップする ID を返す API 作成したのでその時のメモをここに残します。
Firestore
Firestore は、Google 社が提供する NoSQL 型のデータベースです。
用途と主な利用ケース
サーバーレスの NoSQL ドキュメントデータベースで、構造化されたデータの格納やリアルタイム同期を可能にします。例えば、チャットアプリやコラボレーションツール、複雑なクエリが必要なアプリに適しています。データのオフラインアクセスや同期が必要なモバイルアプリにも有効です。
データモデル
ドキュメントベースのデータモデルを採用し、コレクションとドキュメントでデータを階層的に構造化できます。複雑なクエリやデータフィルタリングが可能で、リアルタイム更新をサポートしています。
パフォーマンスとスケーラビリティ
自動スケーリングが可能で、大規模なアプリケーションでも一貫したパフォーマンスを提供します。大規模なデータを扱う場合でも安定した性能を保てるのが特長です。
データの永続性と信頼性
データは自動的に複数の場所にレプリケートされ、高い信頼性と永続性を保証します。ACIDトランザクションをサポートし、データ整合性も確保しています。
料金
使った分だけ支払う「従量課金制」を採用しています。料金は、主に次の3つの要素から構成されています。
操作(リード、ライト、削除)
- リード: 100,000回のリード操作ごとに $0.06
- ライト: 100,000回のライト操作ごとに $0.18
- 削除: 100,000回の削除操作ごとに $0.02
無料枠
Firestore には無料枠があり、以下を含みます:
- 1日あたり 50,000回のドキュメントリード
- 1日あたり 20,000回のドキュメントライトと削除
- 1GBのデータ保存
- 10GB/月のネットワーク送信
サンプル
パッケージ
functions-framework==3.* google-cloud-firestore
コード
import functions_framework import json import logging import sys import threading import traceback from datetime import datetime from google.cloud import firestore logger = logging.getLogger() for h in logger.handlers: logger.removeHandler(h) h = logging.StreamHandler(sys.stdout) FORMAT = "%(levelname)s [%(funcName)s] %(message)s" h.setFormatter(logging.Formatter(FORMAT)) logger.addHandler(h) logger.setLevel(logging.DEBUG) COUNTER_COLLECTION = "counters" COUNTER_DOCUMENT = "sample_id" PREFIX = "sample-id" db = firestore.Client.from_service_account_json("./sample_client.json") def _generate_sample_id(): counter = 0 lock = threading.Lock() counter_doc_ref = db.collection(COUNTER_COLLECTION).document(COUNTER_DOCUMENT) snapshot = counter_doc_ref.get() if snapshot.exists: counter = snapshot.get("count") else: counter_doc_ref.set({"count": counter}) with lock: counter += 1 sample_id = counter counter_doc_ref.set({"count": sample_id}) current_date = datetime.now().strftime("%Y%m%d") sample_id = f"{PREFIX}-{current_date}-{str(sample_id).zfill(8)}" return sample_id @functions_framework.http def ss_gec_supporter_dev(request): try: _dict = { "request_method": request.method, "request_headers": request.headers, "request_args": request.args, "request_remote_addr": request.remote_addr, "request.user_agent": request.user_agent, } logger.debug(_dict) sample_id, _message, _status = None, None, 200 sample_id = _generate_sample_id() except Exception as e: logger.error(f"{traceback.format_exc()}") _status = 500 _message = e finally: results = { "sample_id": sample_id, "message": _message, } logger.info(results) return (json.dumps(results, indent=2), _status)
デプロイ
$ gcloud functions deploy sample_api \ --gen2 \ --runtime python312 \ --region asia-northeast1 \ --trigger-http \ --allow-unauthenticated