Cloud Run에서 완전 관리형 데이터베이스에 연결

1. 개요

이 실습에서는 서버리스 데이터베이스(Spanner 및 Firestore)를 Cloud Run에서 실행되는 애플리케이션(Go 및 Node.js)과 통합합니다. Cymbal Eats 애플리케이션에는 Cloud Run에서 실행되는 여러 서비스가 포함되어 있습니다. 다음 단계에서는 Cloud Spanner 관계형 데이터베이스와 NoSQL 문서 데이터베이스인 Cloud Firestore를 사용하도록 서비스를 구성합니다. 데이터 계층 및 애플리케이션 런타임에 서버리스 제품을 활용하면 모든 인프라 관리 업무를 덜 수 있으므로 오버헤드에 신경 쓰는 대신 애플리케이션 빌드에 집중할 수 있습니다.

2. 학습할 내용

이 실습에서는 다음 작업을 진행하는 방법을 학습합니다.

  • Spanner 통합
  • Spanner 관리형 서비스 사용 설정
  • 코드에 통합
  • Spanner에 연결하는 코드 배포
  • Firestore 통합
  • Firestore 관리형 서비스 사용 설정
  • 코드에 통합
  • Firestore에 연결하는 코드 배포

3. 설정 및 요구사항

자습형 환경 설정

  1. Google Cloud Console에 로그인하여 새 프로젝트를 만들거나 기존 프로젝트를 재사용합니다. 아직 Gmail이나 Google Workspace 계정이 없는 경우 계정을 만들어야 합니다.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • 프로젝트 이름은 이 프로젝트 참가자의 표시 이름입니다. 이는 Google API에서 사용하지 않는 문자열이며 언제든지 업데이트할 수 있습니다.
  • 프로젝트 ID는 모든 Google Cloud 프로젝트에서 고유하며, 변경할 수 없습니다(설정된 후에는 변경할 수 없음). Cloud 콘솔은 고유한 문자열을 자동으로 생성합니다. 일반적으로는 신경 쓰지 않아도 됩니다. 대부분의 Codelab에서는 프로젝트 ID (일반적으로 PROJECT_ID로 식별됨)를 참조해야 합니다. 생성된 ID가 마음에 들지 않으면 다른 임의 ID를 생성할 수 있습니다. 또는 직접 시도해 보고 사용 가능한지 확인할 수도 있습니다. 이 단계 이후에는 변경할 수 없으며 프로젝트 기간 동안 유지됩니다.
  • 참고로 세 번째 값은 일부 API에서 사용하는 프로젝트 번호입니다. 이 세 가지 값에 대한 자세한 내용은 문서를 참고하세요.
  1. 다음으로 Cloud 리소스/API를 사용하려면 Cloud 콘솔에서 결제를 사용 설정해야 합니다. 이 Codelab 실행에는 많은 비용이 들지 않습니다. 이 튜토리얼이 끝난 후에 요금이 청구되지 않도록 리소스를 종료하려면 만든 리소스 또는 프로젝트를 삭제하면 됩니다. Google Cloud 신규 사용자는 300달러(USD) 상당의 무료 체험판 프로그램에 참여할 수 있습니다.

환경 설정

  1. 프로젝트 ID 변수 만들기
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
export SPANNER_INSTANCE=inventory-instance
export SPANNER_DB=inventory-db
export REGION=us-east1
export SPANNER_CONNECTION_STRING=projects/$PROJECT_ID/instances/$SPANNER_INSTANCE/databases/$SPANNER_DB
  1. Spanner, Cloud Run, Cloud Build, Artifact Registry API 사용 설정
gcloud services enable \
     compute.googleapis.com \
     spanner.googleapis.com \
     run.googleapis.com \
     cloudbuild.googleapis.com \
     artifactregistry.googleapis.com \
     firestore.googleapis.com \
     appengine.googleapis.com \
     artifactregistry.googleapis.com
  1. 저장소 복제
git clone https://github.com/GoogleCloudPlatform/cymbal-eats.git
  1. 디렉터리로 이동
cd cymbal-eats/inventory-service/spanner

4. Spanner 인스턴스 만들기 및 구성

Spanner는 인벤토리 서비스 백엔드 관계형 데이터베이스입니다. 다음 단계에서 Spanner 인스턴스, 데이터베이스, 스키마를 만듭니다.

인스턴스 만들기

  1. Cloud Spanner 인스턴스 만들기
gcloud spanner instances create $SPANNER_INSTANCE --config=regional-${REGION} \
--description="Cymbal Menu Inventory" --nodes=1

출력 예시

Creating instance...done.   
  1. Spanner 인스턴스가 올바르게 구성되었는지 확인
gcloud spanner instances list

출력 예

NAME: inventory-instance
DISPLAY_NAME: Cymbal Menu Inventory
CONFIG: regional-us-east1
NODE_COUNT: 1
PROCESSING_UNITS: 100
STATE: READY

데이터베이스 및 스키마 만들기

새 데이터베이스를 만들고 Google 표준 SQL의 데이터 정의 언어 (DDL)를 사용하여 데이터베이스 스키마를 만듭니다.

  1. DDL 파일 만들기
echo "CREATE TABLE InventoryHistory (ItemRowID STRING (36) NOT NULL, ItemID INT64 NOT NULL, InventoryChange INT64, Timestamp TIMESTAMP) PRIMARY KEY(ItemRowID)" >> table.ddl
  1. Spanner 데이터베이스 만들기
gcloud spanner databases create $SPANNER_DB \
--instance=$SPANNER_INSTANCE \
--ddl-file=table.ddl

출력 예

Creating database...done.

데이터베이스 상태 및 스키마 확인

  1. 데이터베이스 상태 보기
gcloud spanner databases describe $SPANNER_DB \
--instance=$SPANNER_INSTANCE

출력 예

createTime: '2022-04-22T15:11:33.559300Z'
databaseDialect: GOOGLE_STANDARD_SQL
earliestVersionTime: '2022-04-22T15:11:33.559300Z'
encryptionInfo:
- encryptionType: GOOGLE_DEFAULT_ENCRYPTION
name: projects/cymbal-eats-7-348013/instances/menu-inventory/databases/menu-inventory
state: READY
versionRetentionPeriod: 1h
  1. 데이터베이스의 스키마 보기
gcloud spanner databases ddl describe $SPANNER_DB \
--instance=$SPANNER_INSTANCE

출력 예

CREATE TABLE InventoryHistory (
  ItemRowID STRING(36) NOT NULL,
  ItemID INT64 NOT NULL,
  InventoryChange INT64,
  TimeStamp TIMESTAMP,
) PRIMARY KEY(ItemRowID);

5. Spanner 통합

이 섹션에서는 Spanner를 애플리케이션에 통합하는 방법을 알아봅니다. 또한 SQL Spanner는 모든 애플리케이션에 Spanner를 통합할 수 있도록 클라이언트 라이브러리, JDBC 드라이버, R2DBC 드라이버, REST API, RPC API를 제공합니다.

다음 섹션에서는 Go 클라이언트 라이브러리를 사용하여 Spanner에서 데이터를 설치, 인증, 수정합니다.

클라이언트 라이브러리 설치

Cloud Spanner 클라이언트 라이브러리를 사용하면 애플리케이션 기본 사용자 인증 정보 (ADC)를 자동으로 사용해 서비스 계정 사용자 인증 정보를 찾아 Cloud Spanner와 쉽게 통합할 수 있습니다.

인증 설정

Google Cloud CLI 및 Google Cloud 클라이언트 라이브러리는 이러한 도구가 Google Cloud에서 실행될 때 이를 자동으로 감지하고 현재 Cloud Run 버전의 런타임 서비스 계정을 사용합니다. 이 전략을 애플리케이션 기본 사용자 인증 정보라고 하며 여러 환경 간에 코드 이동성을 지원합니다.

하지만 기본 서비스 계정 대신 사용자 관리형 서비스 계정을 할당하여 전용 ID를 만드는 것이 가장 좋습니다.

  1. 서비스 계정에 Spanner 데이터베이스 관리자 역할 부여하기
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
--role="roles/spanner.databaseAdmin"

출력 예

Updated IAM policy for project [cymbal-eats-6422-3462].
[...]

클라이언트 라이브러리 사용

Spanner 클라이언트 라이브러리는 Spanner 통합 시 발생하는 복잡성을 추상화하며 널리 사용되는 여러 프로그래밍 언어로 사용할 수 있습니다.

Spanner 클라이언트 만들기

Spanner 클라이언트는 Cloud Spanner 데이터베이스에서 데이터를 읽고 쓰는 클라이언트입니다. 클라이언트는 Close 메서드를 제외하고 동시에 사용해도 안전합니다.

아래 스니펫은 Spanner 클라이언트를 만듭니다.

main.go

var dataClient *spanner.Client
...
dataClient, err = spanner.NewClient(ctx, databaseName)

클라이언트를 데이터베이스 연결이라고 생각하면 됩니다. Cloud Spanner와의 모든 상호작용은 클라이언트를 거쳐야 합니다. 일반적으로 애플리케이션 시작 시 Client를 생성하고 이 클라이언트를 재사용하여 트랜잭션을 읽고 쓰고 실행할 수 있습니다. 각 클라이언트는 Cloud Spanner의 리소스를 사용합니다.

데이터 수정

Spanner 데이터베이스에서 데이터를 삽입, 업데이트, 삭제하는 방법에는 여러 가지가 있습니다. 다음은 사용 가능한 메서드입니다.

이 실습에서는 변형을 사용하여 Spanner의 데이터를 수정합니다.

Spanner의 변형

Mutation은 변형 작업을 위한 컨테이너입니다. 변형은 Cloud Spanner가 Cloud Spanner 데이터베이스의 여러 행과 테이블에 원자적으로 적용하는 일련의 삽입, 업데이트, 삭제를 나타냅니다.

main.go

m := []*spanner.Mutation{}

m = append(m, spanner.Insert(
        "inventoryHistory",
         inventoryHistoryColumns,
        []interface{}{uuid.New().String(), element.ItemID, element.InventoryChange, time.Now()}))

코드 스니펫은 인벤토리 기록 표에 새 행을 삽입합니다.

배포 및 테스트

이제 Spanner가 구성되었고 핵심 코드 요소를 검토했으므로 애플리케이션을 Cloud Run에 배포합니다.

Cloud Run에 애플리케이션 배포

Cloud Run은 단일 명령어로 코드를 자동으로 빌드, 푸시, 배포할 수 있습니다. 다음 명령어에서는 run 서비스에서 deploy 명령어를 호출하여 앞서 만든 SPANNER_CONNECTION_STRING과 같이 실행 중인 애플리케이션에서 사용하는 변수를 전달합니다.

  1. 터미널 열기를 클릭합니다.
  2. Cloud Run에 인벤토리 서비스 배포
gcloud run deploy inventory-service \
    --source . \
    --region $REGION \
    --update-env-vars SPANNER_CONNECTION_STRING=$SPANNER_CONNECTION_STRING \
    --allow-unauthenticated \
    --project=$PROJECT_ID \
    --quiet

출력 예

Service [inventory-service] revision [inventory-service-00001-sug] has been deployed and is serving 100 percent of traffic.
Service URL: https://inventory-service-ilwytgcbca-uk.a.run.app
  1. 서비스 URL 저장
INVENTORY_SERVICE_URL=$(gcloud run services describe inventory-service \
  --platform managed \
  --region $REGION \
  --format=json | jq \
  --raw-output ".status.url")

Cloud Run 애플리케이션 테스트

항목 삽입

  1. Cloud Shell에서 다음 명령어를 입력합니다.
POST_URL=$INVENTORY_SERVICE_URL/updateInventoryItem
curl -i -X POST ${POST_URL} \
--header 'Content-Type: application/json' \
--data-raw '[
    {
        "itemID": 1,
        "inventoryChange": 5
    }
]'

출력 예

HTTP/2 200
access-control-allow-origin: *
content-type: application/json
x-cloud-trace-context: 10c32f0863d26521497dc26e86419f13;o=1
date: Fri, 22 Apr 2022 21:41:38 GMT
server: Google Frontend
content-length: 2

OK

항목 쿼리

  1. 인벤토리 서비스 쿼리
GET_URL=$INVENTORY_SERVICE_URL/getAvailableInventory
curl -i ${GET_URL}

응답 예

HTTP/2 200
access-control-allow-origin: *
content-type: text/plain; charset=utf-8
x-cloud-trace-context: b94f921e4c2ae90210472c88eb05ace8;o=1
date: Fri, 22 Apr 2022 21:45:50 GMT
server: Google Frontend
content-length: 166

[{"ItemID":1,"Inventory":5}]

6. Spanner 개념

Cloud Spanner는 선언적 SQL 문을 사용하여 데이터베이스를 쿼리합니다. SQL 문은 결과를 얻는 방법을 설명하지 않고 사용자가 원하는 것을 나타냅니다.

  1. 터미널에서 다음 명령어를 입력하여 이전에 만든 레코드의 테이블을 쿼리합니다.
gcloud spanner databases execute-sql $SPANNER_DB \
--instance=$SPANNER_INSTANCE \
--sql='SELECT * FROM InventoryHistory WHERE ItemID=1'

출력 예

ItemRowID: 1
ItemID: 1
InventoryChange: 3
Timestamp: 

쿼리 실행 계획

쿼리 실행 계획은 Spanner가 결과를 얻기 위해 사용하는 일련의 단계입니다. 특정 SQL 문의 결과를 얻는 방법에는 여러 가지가 있을 수 있습니다. 쿼리 실행 계획은 콘솔 및 클라이언트 라이브러리에서 액세스할 수 있습니다. Spanner가 SQL 쿼리를 처리하는 방법을 확인하려면 다음 안내를 따르세요.

  1. 콘솔에서 Cloud Spanner 인스턴스 페이지를 엽니다.
  2. Cloud Spanner 인스턴스로 이동
  3. Cloud Spanner 인스턴스의 이름을 클릭합니다. 데이터베이스 섹션에서 쿼리할 데이터베이스를 선택합니다.
  4. 쿼리를 클릭합니다.
  5. 쿼리 편집기에 다음 쿼리를 입력합니다.
SELECT * FROM InventoryHistory WHERE ItemID=1
  1. 실행을 클릭합니다.
  2. '설명'을 클릭합니다.

Cloud 콘솔에는 쿼리의 시각적 실행 계획이 표시됩니다.

149f8bae468f8b34.png

쿼리 최적화 도구

Cloud Spanner 쿼리 옵티마이저는 대체 실행 계획을 비교하고 가장 효율적인 계획을 선택합니다. 시간이 지남에 따라 쿼리 옵티마이저가 발전하면서 쿼리 실행 계획에서 선택의 폭을 넓히고 이러한 선택에 영향을 미치는 추정치의 정확성을 향상시켜 더 효율적인 쿼리 실행 계획을 수립할 것입니다.

Cloud Spanner는 새로운 쿼리 최적화 도구 버전으로 최적화 도구 업데이트를 출시합니다. 기본적으로, 각 데이터베이스는 버전이 출시된 후 30일 이내에 최신 버전의 옵티마이저를 사용하기 시작합니다.

gcloud spanner에서 쿼리를 실행할 때 사용되는 버전을 확인하려면 –query-mode 플래그를 PROFILE로 설정하세요.

  1. 옵티마이저 버전을 보려면 다음 명령어를 입력합니다.
gcloud spanner databases execute-sql $SPANNER_DB --instance=$SPANNER_INSTANCE \
--query-mode=PROFILE --sql='SELECT * FROM InventoryHistory'

출력 예

TOTAL_ELAPSED_TIME: 6.18 msecs
CPU_TIME: 5.17 msecs
ROWS_RETURNED: 1
ROWS_SCANNED: 1
OPTIMIZER_VERSION: 3
 RELATIONAL Distributed Union
 (1 execution, 0.11 msecs total latency)
 subquery_cluster_node: 1
    |
    +- RELATIONAL Distributed Union
    |  (1 execution, 0.09 msecs total latency)
    |  call_type: Local, subquery_cluster_node: 2
    |   |
    |   \- RELATIONAL Serialize Result
    |      (1 execution, 0.08 msecs total latency)
    |       |
    |       +- RELATIONAL Scan
    |       |  (1 execution, 0.08 msecs total latency)
    |       |  Full scan: true, scan_target: InventoryHistory, scan_type: TableScan
    |       |   |
    |       |   +- SCALAR Reference
    |       |   |  ItemRowID
    |       |   |
    |       |   +- SCALAR Reference
    |       |   |  ItemID
    |       |   |
    |       |   +- SCALAR Reference
    |       |   |  InventoryChange
    |       |   |
    |       |   \- SCALAR Reference
    |       |      Timestamp
    |       |
    |       +- SCALAR Reference
    |       |  $ItemRowID
    |       |
    |       +- SCALAR Reference
    |       |  $ItemID
    |       |
    |       +- SCALAR Reference
    |       |  $InventoryChange
    |       |
    |       \- SCALAR Reference
    |          $Timestamp
    |
    \- SCALAR Constant
       true

ItemRowID: 1
ItemID: 1
InventoryChange: 3
Timestamp:

옵티마이저 버전 업데이트

이 실습의 최신 버전은 버전 4입니다. 다음으로 쿼리 옵티마이저에 버전 4를 사용하도록 Spanner 테이블을 업데이트합니다.

  1. 옵티마이저 업데이트
gcloud spanner databases ddl update $SPANNER_DB \
--instance=$SPANNER_INSTANCE \
--ddl='ALTER DATABASE InventoryHistory
SET OPTIONS (optimizer_version = 4)'

출력 예

Schema updating...done. 
  1. 옵티마이저 버전 업데이트를 보려면 다음 명령어를 입력합니다.
gcloud spanner databases execute-sql $SPANNER_DB --instance=$SPANNER_INSTANCE \
--query-mode=PROFILE --sql='SELECT * FROM InventoryHistory'

출력 예

TOTAL_ELAPSED_TIME: 8.57 msecs
CPU_TIME: 8.54 msecs
ROWS_RETURNED: 1
ROWS_SCANNED: 1
OPTIMIZER_VERSION: 4
[...]

측정항목 탐색기에서 쿼리 최적화 도구 버전 시각화

Cloud 콘솔의 측정항목 탐색기를 사용하여 데이터베이스 인스턴스의 쿼리 수를 시각화할 수 있습니다. 각 데이터베이스에서 사용 중인 옵티마이저 버전을 확인할 수 있습니다.

  1. Cloud 콘솔에서 Monitoring으로 이동하고 왼쪽 메뉴에서 측정항목 탐색기를 선택합니다.
  2. 리소스 유형 필드에서 Cloud Spanner 인스턴스를 선택합니다.
  3. 측정항목 필드에서 '쿼리 수'와 '적용'을 선택합니다.
  4. 그룹화 기준 필드에서 데이터베이스, 옵티마이저_버전, 상태를 선택합니다.

581b859c25790b21.png

7. Firestore 데이터베이스 만들기 및 구성

Firestore는 자동 확장, 고성능, 간편한 애플리케이션 개발을 위해 설계된 NoSQL 문서 데이터베이스입니다. Firestore 인터페이스의 많은 기능이 기존 데이터베이스와 동일하지만 NoSQL 데이터베이스는 데이터 객체 간의 관계를 설명하는 면에서 다릅니다.

다음 작업에서는 Firestore에서 지원하는 주문 서비스 Cloud Run 애플리케이션을 만드는 방법을 안내합니다. 주문 서비스는 이전 섹션에서 만든 인벤토리 서비스를 호출하여 주문을 시작하기 전에 Spanner 데이터베이스를 쿼리합니다. 이 서비스를 통해 충분한 인벤토리가 존재하고 주문을 처리할 수 있습니다.

6843abaf4263e112.png

8. Firestore 개념

데이터 모델

Firestore 데이터베이스는 컬렉션과 문서로 구성됩니다.

b60acd63d4793a6c.png

문서

각 문서에는 키-값 쌍이 들어 있습니다. Firestore는 작은 문서의 대규모 컬렉션을 저장하는 데 최적화되어 있습니다.

5571cb2f261d2dbe.png

컬렉션

모든 문서를 컬렉션에 저장해야 합니다. 문서는 문자열과 같은 기본 필드 또는 목록과 같은 복잡한 객체를 포함하여 하위 컬렉션 및 중첩된 객체를 포함할 수 있습니다.

5811378cb721e5ec.png

Firestore 데이터베이스 만들기

  1. Firestore 데이터베이스 만들기
gcloud firestore databases create --location=$REGION

출력 예

Success! Selected Google Cloud Firestore Native database for cymbal-eats-6422-3462

9. 애플리케이션에 Firestore 통합

이 섹션에서는 서비스 계정을 업데이트하고, Firestore 액세스 서비스 계정을 추가하고, Firestore 보안 규칙을 검토 및 배포하고, Firestore에서 데이터가 수정되는 방식을 검토합니다.

인증 설정

  1. 서비스 계정에 Datastore 사용자 역할 부여
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
  --role="roles/datastore.user"

출력 예

Updated IAM policy for project [cymbal-eats-6422-3462].

Firestore 보안 규칙

보안 규칙은 액세스 제어 및 데이터 검증을 표현력이 뛰어나면서도 직접적인 형식으로 제공합니다.

  1. order-service/starter-code 디렉터리로 이동
cd ~/cymbal-eats/order-service
  1. Cloud 편집기에서 Firestore.rules 파일 열기
cat firestore.rules

firestore.rules

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents { ⇐ All database
    match /{document=**} { ⇐ All documents
      allow read: if true; ⇐ Allow reads
    }
    match /{document=**} {
      allow write: if false; ⇐ Deny writes
    }
  }
}

경고: Firestore 저장소에 대한 액세스를 제한하는 것이 좋습니다. 이 실습에서는 모든 읽기가 허용됩니다. 이는 권장되는 프로덕션 구성이 아닙니다.

Firestore 관리형 서비스 사용 설정

  1. 터미널 열기를 클릭합니다.
  2. 현재 프로젝트 ID로 .firebaserc 파일을 만듭니다. 배포 대상 설정은 프로젝트 디렉터리의 .firebaserc 파일에 저장됩니다.

firebaserc.tmpl

sed "s/PROJECT_ID/$PROJECT_ID/g" firebaserc.tmpl > .firebaserc
  1. Firebase 바이너리 다운로드
curl -sL https://firebase.tools | upgrade=true bash

출력 예

-- Checking for existing firebase-tools on PATH...
Your machine already has firebase-tools@10.7.0 installed. Nothing to do.
-- All done!
  1. Firestore 규칙을 배포합니다.
firebase deploy 

출력 예시

=== Deploying to 'cymbal-eats-6422-3462'...

i  deploying firestore
i  cloud.firestore: checking firestore.rules for compilation errors...
✔  cloud.firestore: rules file firestore.rules compiled successfully
i  firestore: uploading rules firestore.rules...
✔  firestore: released rules firestore.rules to cloud.firestore

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/cymbal-eats-6422-3462/overview

데이터 수정

컬렉션과 문서는 Firestore에서 암시적으로 생성됩니다. 데이터를 컬렉션 내의 문서에 할당하기만 하면 됩니다. 컬렉션이나 문서가 없으면 Firestore에서 컬렉션이나 문서를 만듭니다.

Firestore에 데이터 추가

Cloud Firestore에 데이터를 쓰는 방법에는 여러 가지가 있습니다.

  • 문서 식별자를 명시적으로 지정하여 컬렉션 내 문서의 데이터를 설정합니다.
  • 컬렉션에 새 문서를 추가합니다. 이 경우 Cloud Firestore에서 자동으로 문서 식별자를 생성합니다.
  • 자동으로 생성된 식별자가 있는 빈 문서를 만들고 나중에 데이터를 할당합니다.

다음 섹션에서는 set 메서드를 사용하여 문서를 만드는 방법을 안내합니다.

문서 설정

문서를 만들려면 set() 메서드를 사용합니다. set() 메서드를 사용하면 만들 문서의 ID를 지정해야 합니다.

아래의 코드 스니펫을 살펴보세요.

index.js

const orderDoc = db.doc(`orders/123`);
await orderDoc.set({
    orderNumber: 123,
    name: Anne,
    address: 555 Bright Street,
    city: Mountain View,
    state: CA,
    zip: 94043,
    orderItems: [id: 1],
    status: 'New'
  });

이 코드는 사용자 생성 문서 ID 123을 지정하는 문서를 만듭니다. Firestore에서 자동으로 ID를 생성하도록 하려면 add() 또는 create() 메서드를 사용합니다.

문서 업데이트

업데이트 메서드 update()를 사용하면 전체 문서를 덮어쓰지 않고 일부 문서 필드를 업데이트할 수 있습니다.

아래 스니펫에서 코드는 주문 123을 업데이트합니다.

index.js

const orderDoc = db.doc(`orders/123`);
await orderDoc.update(name: "Anna");

문서 삭제

Firestore에서는 문서에서 컬렉션, 문서 또는 특정 필드를 삭제할 수 있습니다. 문서를 삭제하려면 delete() 메서드를 사용합니다.

아래 스니펫은 주문 123을 삭제합니다.

index.js

const orderDoc = db.doc(`orders/123`);
await orderDoc.delete();

10. 배포 및 테스트

이 섹션에서는 애플리케이션을 Cloud Run에 배포하고 create, update, delete 메서드를 테스트합니다.

Cloud Run에 애플리케이션 배포

  1. URL을 INVENTORY_SERVICE_URL 변수에 저장하여 인벤토리 서비스와 통합합니다.
INVENTORY_SERVICE_URL=$(gcloud run services describe inventory-service \
 --region=$REGION \
 --format=json | jq \
 --raw-output ".status.url")
  1. 주문 서비스 배포
gcloud run deploy order-service \
  --source . \
  --platform managed \
  --region $REGION \
  --allow-unauthenticated \
  --project=$PROJECT_ID \
  --set-env-vars=INVENTORY_SERVICE_URL=$INVENTORY_SERVICE_URL \
  --quiet

출력 예

[...]
Done.
Service [order-service] revision [order-service-00001-qot] has been deployed and is serving 100 percent of traffic.
Service URL: https://order-service-3jbm3exegq-uk.a.run.app

Cloud Run 애플리케이션 테스트

문서 새로 만들어 줘

  1. 주문 서비스 애플리케이션의 URL을 테스트를 위한 변수에 저장
ORDER_SERVICE_URL=$(gcloud run services describe order-service \
  --platform managed \
  --region $REGION \
  --format=json | jq \
  --raw-output ".status.url")
  1. 주문 요청을 작성하고 Firestore 데이터베이스에 새 주문 게시
curl --request POST $ORDER_SERVICE_URL/order \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "Jane Doe",
         "email": "Jane.Doe-cymbaleats@gmail.com",
    "address": "123 Maple",
    "city": "Buffalo",
    "state": "NY",
    "zip": "12346",
    "orderItems": [
        {
            "id": 1
        }
    ]
}'

출력 예

{"orderNumber":46429}

나중에 사용할 수 있도록 주문 번호 저장

export ORDER_NUMBER=<value_from_output>

결과 보기

Firestore에서 결과 보기

  1. Firestore 콘솔로 이동합니다.
  2. 데이터를 클릭합니다.

465ceca6198b2b88.png

문서 업데이트

제출된 주문에 수량이 포함되지 않았습니다.

  1. 레코드를 업데이트하고 수량 키-값 쌍 추가
curl --location -g --request PATCH $ORDER_SERVICE_URL/order/${ORDER_NUMBER} \
--header 'Content-Type: application/json' \
--data-raw '{
"orderItems": [
        {   
            "id": 1,
            "quantity": 1   
        }
    ]
}'

출력 예

{"status":"success"}

결과 보기

Firestore에서 결과 보기

  1. Firestore 콘솔로 이동합니다.
  2. 데이터를 클릭합니다.

cfcf78d200e15b84.png

문서 삭제

  1. Firestore 주문 컬렉션에서 항목 46429 삭제
curl --location -g --request DELETE $ORDER_SERVICE_URL/order/${ORDER_NUMBER}

결과 보기

  1. Firestore 콘솔로 이동합니다.
  2. 데이터를 클릭합니다.

73e14d69211d1539.png

11. 축하합니다.

축하합니다. 실습을 완료하셨습니다.

다음 단계:

다른 Cymbal Eats Codelab 살펴보기:

삭제

이 튜토리얼에서 사용된 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 리소스가 포함된 프로젝트를 삭제하거나 프로젝트를 유지하고 개별 리소스를 삭제하세요.

프로젝트 삭제

비용이 청구되지 않도록 하는 가장 쉬운 방법은 튜토리얼에서 만든 프로젝트를 삭제하는 것입니다.