gcp

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Google Cloud Platform

Google Cloud Platform

Cloud Functions

Cloud Functions

typescript
import { HttpFunction, CloudEvent } from '@google-cloud/functions-framework';

// HTTP trigger
export const getProduct: HttpFunction = async (req, res) => {
  const product = await getProductById(req.query.id as string);
  res.json(product);
};

// Pub/Sub trigger
export const processOrder = async (cloudEvent: CloudEvent<{ message: { data: string } }>) => {
  const data = JSON.parse(Buffer.from(cloudEvent.data!.message.data, 'base64').toString());
  await handleOrder(data);
};

// Cloud Storage trigger
export const onFileUpload = async (cloudEvent: CloudEvent<{ bucket: string; name: string }>) => {
  const { bucket, name } = cloudEvent.data!;
  await processUploadedFile(bucket, name);
};
typescript
import { HttpFunction, CloudEvent } from '@google-cloud/functions-framework';

// HTTP trigger
export const getProduct: HttpFunction = async (req, res) => {
  const product = await getProductById(req.query.id as string);
  res.json(product);
};

// Pub/Sub trigger
export const processOrder = async (cloudEvent: CloudEvent<{ message: { data: string } }>) => {
  const data = JSON.parse(Buffer.from(cloudEvent.data!.message.data, 'base64').toString());
  await handleOrder(data);
};

// Cloud Storage trigger
export const onFileUpload = async (cloudEvent: CloudEvent<{ bucket: string; name: string }>) => {
  const { bucket, name } = cloudEvent.data!;
  await processUploadedFile(bucket, name);
};

Firestore

Firestore

typescript
import { Firestore, FieldValue } from '@google-cloud/firestore';

const db = new Firestore();

// Create/Update
await db.collection('users').doc(userId).set({
  name, email, createdAt: FieldValue.serverTimestamp(),
});

// Read
const doc = await db.collection('users').doc(userId).get();
const user = doc.data();

// Query
const snapshot = await db.collection('orders')
  .where('userId', '==', userId)
  .where('status', '==', 'active')
  .orderBy('createdAt', 'desc')
  .limit(10)
  .get();

const orders = snapshot.docs.map((d) => ({ id: d.id, ...d.data() }));

// Real-time listener
db.collection('messages')
  .where('roomId', '==', roomId)
  .onSnapshot((snapshot) => {
    snapshot.docChanges().forEach((change) => {
      if (change.type === 'added') handleNewMessage(change.doc.data());
    });
  });
typescript
import { Firestore, FieldValue } from '@google-cloud/firestore';

const db = new Firestore();

// Create/Update
await db.collection('users').doc(userId).set({
  name, email, createdAt: FieldValue.serverTimestamp(),
});

// Read
const doc = await db.collection('users').doc(userId).get();
const user = doc.data();

// Query
const snapshot = await db.collection('orders')
  .where('userId', '==', userId)
  .where('status', '==', 'active')
  .orderBy('createdAt', 'desc')
  .limit(10)
  .get();

const orders = snapshot.docs.map((d) => ({ id: d.id, ...d.data() }));

// Real-time listener
db.collection('messages')
  .where('roomId', '==', roomId)
  .onSnapshot((snapshot) => {
    snapshot.docChanges().forEach((change) => {
      if (change.type === 'added') handleNewMessage(change.doc.data());
    });
  });

Cloud Storage

Cloud Storage

typescript
import { Storage } from '@google-cloud/storage';

const storage = new Storage();
const bucket = storage.bucket(process.env.GCS_BUCKET!);

// Upload
await bucket.file(`uploads/${filename}`).save(buffer, {
  metadata: { contentType },
});

// Download
const [content] = await bucket.file(path).download();

// Signed URL
const [url] = await bucket.file(path).getSignedUrl({
  version: 'v4',
  action: 'read',
  expires: Date.now() + 3600 * 1000,
});
typescript
import { Storage } from '@google-cloud/storage';

const storage = new Storage();
const bucket = storage.bucket(process.env.GCS_BUCKET!);

// Upload
await bucket.file(`uploads/${filename}`).save(buffer, {
  metadata: { contentType },
});

// Download
const [content] = await bucket.file(path).download();

// Signed URL
const [url] = await bucket.file(path).getSignedUrl({
  version: 'v4',
  action: 'read',
  expires: Date.now() + 3600 * 1000,
});

Pub/Sub

Pub/Sub

typescript
import { PubSub } from '@google-cloud/pubsub';

const pubsub = new PubSub();

// Publish
const topic = pubsub.topic('order-events');
await topic.publishMessage({
  json: { orderId: '123', status: 'completed' },
  attributes: { eventType: 'ORDER_COMPLETED' },
});

// Subscribe
const subscription = pubsub.subscription('order-processor');
subscription.on('message', async (message) => {
  const data = JSON.parse(message.data.toString());
  await processOrder(data);
  message.ack();
});
typescript
import { PubSub } from '@google-cloud/pubsub';

const pubsub = new PubSub();

// Publish
const topic = pubsub.topic('order-events');
await topic.publishMessage({
  json: { orderId: '123', status: 'completed' },
  attributes: { eventType: 'ORDER_COMPLETED' },
});

// Subscribe
const subscription = pubsub.subscription('order-processor');
subscription.on('message', async (message) => {
  const data = JSON.parse(message.data.toString());
  await processOrder(data);
  message.ack();
});

BigQuery

BigQuery

typescript
import { BigQuery } from '@google-cloud/bigquery';

const bq = new BigQuery();

const [rows] = await bq.query({
  query: `SELECT product_id, SUM(quantity) as total
          FROM \`project.dataset.orders\`
          WHERE DATE(created_at) = @date
          GROUP BY product_id
          ORDER BY total DESC
          LIMIT 10`,
  params: { date: '2026-03-05' },
});
typescript
import { BigQuery } from '@google-cloud/bigquery';

const bq = new BigQuery();

const [rows] = await bq.query({
  query: `SELECT product_id, SUM(quantity) as total
          FROM \`project.dataset.orders\`
          WHERE DATE(created_at) = @date
          GROUP BY product_id
          ORDER BY total DESC
          LIMIT 10`,
  params: { date: '2026-03-05' },
});

Authentication

身份认证

typescript
// Application Default Credentials (works everywhere)
// Local: gcloud auth application-default login
// GCE/Cloud Run/GKE: automatic via metadata server
// CI/CD: GOOGLE_APPLICATION_CREDENTIALS env var

import { GoogleAuth } from 'google-auth-library';
const auth = new GoogleAuth({ scopes: ['https://www.googleapis.com/auth/cloud-platform'] });
typescript
// Application Default Credentials (works everywhere)
// Local: gcloud auth application-default login
// GCE/Cloud Run/GKE: automatic via metadata server
// CI/CD: GOOGLE_APPLICATION_CREDENTIALS env var

import { GoogleAuth } from 'google-auth-library';
const auth = new GoogleAuth({ scopes: ['https://www.googleapis.com/auth/cloud-platform'] });

Anti-Patterns

反模式

Anti-PatternFix
Service account key files in repoUse Application Default Credentials
Not using composite indexes (Firestore)Define indexes for multi-field queries
Synchronous Pub/Sub publishBatch messages, use
topic.publishMessage
Full table scans in BigQueryUse partitioned/clustered tables
No IAM least privilegeGrant minimum required roles per service
反模式修复方案
仓库中存放服务账号密钥文件使用Application Default Credentials
(Firestore)未使用复合索引为多字段查询定义索引
同步发布Pub/Sub消息批量处理消息,使用
topic.publishMessage
BigQuery中执行全表扫描使用分区/聚簇表
未遵循IAM最小权限原则为每个服务授予最小必要角色

Production Checklist

生产环境检查清单

  • Application Default Credentials (no key files)
  • IAM roles with least privilege
  • VPC Service Controls for sensitive data
  • Cloud Monitoring and alerting configured
  • Resource labels for cost tracking
  • Firestore composite indexes deployed
  • 使用Application Default Credentials(无密钥文件)
  • IAM角色遵循最小权限原则
  • 为敏感数据配置VPC服务控制
  • 已配置Cloud Monitoring及告警
  • 已配置资源标签用于成本追踪
  • 已部署Firestore复合索引