Node.js Hello World

이 코드 샘플은 Node.js에서 실행되는 'hello world' 애플리케이션입니다. 이 샘플은 다음 작업을 완료하는 방법을 보여줍니다.

  • 인증 설정
  • Bigtable 인스턴스에 연결
  • 새 테이블 만들기
  • 테이블에 데이터 쓰기
  • 데이터 다시 읽기
  • 테이블 삭제

인증 설정

이 페이지의 Node.js 샘플을 로컬 개발 환경에서 사용하려면 gcloud CLI를 설치 및 초기화한 다음 사용자 인증 정보로 애플리케이션 기본 사용자 인증 정보를 설정하세요.

  1. Install the Google Cloud CLI.
  2. To initialize the gcloud CLI, run the following command:

    gcloud init
  3. Create local authentication credentials for your user account:

    gcloud auth application-default login

자세한 내용은 다음을 참조하세요: Set up authentication for a local development environment.

샘플 실행

이 코드 샘플에서는 Node.js용 Google Cloud 클라이언트 라이브러리Bigtable 패키지를 사용하여 Bigtable과 통신합니다.

이 샘플 프로그램을 실행하려면 GitHub에서 샘플 안내를 따르세요.

Cloud 클라이언트 라이브러리를 Bigtable과 함께 사용

샘플 애플리케이션을 Bigtable에 연결하여 몇 가지 간단한 작업을 보여줍니다.

클라이언트 라이브러리 필요

이 샘플에는 Bigtable 클래스를 제공하는 @google-cloud/bigtable 모듈이 필요합니다.

const {Bigtable} = require('@google-cloud/bigtable');

Bigtable에 연결

Bigtable에 연결하려면 새 Bigtable 객체를 만듭니다. 그런 다음 instance() 메서드를 호출하여 Bigtable 인스턴스를 나타내는 Instance 객체를 가져옵니다.

const bigtableClient = new Bigtable();
const instance = bigtableClient.instance(INSTANCE_ID);

테이블 만들기

인스턴스의 table() 메서드를 호출하여 'hello world' 인사말의 테이블을 나타내는 Table 객체를 가져옵니다. 테이블이 없으면 테이블의 create() 메서드를 호출하여 각 값의 버전을 하나만 보관하는 column family가 한 개인 테이블을 만듭니다.

const table = instance.table(TABLE_ID);
const [tableExists] = await table.exists();
if (!tableExists) {
  console.log(`Creating table ${TABLE_ID}`);
  const options = {
    families: [
      {
        name: COLUMN_FAMILY_ID,
        rule: {
          versions: 1,
        },
      },
    ],
  };
  await table.create(options);
}

테이블에 행 쓰기

인사말 문자열 배열을 사용하여 테이블의 새 행을 만듭니다. 배열의 map() 메서드를 호출하여 행을 나타내는 새 객체 배열을 만든 다음 테이블의 insert() 메서드를 호출하여 테이블에 이 행을 추가합니다.

console.log('Write some greetings to the table');
const greetings = ['Hello World!', 'Hello Bigtable!', 'Hello Node!'];
const rowsToInsert = greetings.map((greeting, index) => ({
  // Note: This example uses sequential numeric IDs for simplicity, but this
  // pattern can result in poor performance in a production application.
  // Rows are stored in sorted order by key, so sequential keys can result
  // in poor distribution of operations across nodes.
  //
  // For more information about how to design an effective schema for Cloud
  // Bigtable, see the documentation:
  // https://cloud.google.com/bigtable/docs/schema-design
  key: `greeting${index}`,
  data: {
    [COLUMN_FAMILY_ID]: {
      [COLUMN_QUALIFIER]: {
        // Setting the timestamp allows the client to perform retries. If
        // server-side time is used, retries may cause multiple cells to
        // be generated.
        timestamp: new Date(),
        value: greeting,
      },
    },
  },
}));
await table.insert(rowsToInsert);

필터 만들기

작성한 데이터를 읽기 전에 Bigtable이 반환하는 데이터를 제한하는 필터를 생성합니다. 이 필터는 열에 오래된 셀이 포함되어 있더라도 각 열의 최신 셀만 반환하도록 Bigtable에 지시합니다.

const filter = [
  {
    column: {
      cellLimit: 1, // Only retrieve the most recent version of the cell.
    },
  },
];

row key를 통해 행 읽기

테이블의 row() 메서드를 호출하여 특정 row key로 행에 대한 참조를 가져옵니다. 그런 다음 행의 get() 메서드를 호출하고 필터를 전달하여 이 행에서 각 값의 버전 하나를 가져옵니다.

console.log('Reading a single row by row key');
const [singleRow] = await table.row('greeting0').get({filter});
console.log(`\tRead: ${getRowGreeting(singleRow)}`);

모든 테이블 행 검색

테이블의 getRows() 메서드를 호출하고 필터를 전달하여 테이블의 모든 행을 가져옵니다. 필터를 전달했으므로 Bigtable은 각 값별로 버전 1개만 반환합니다.

console.log('Reading the entire table');
// Note: For improved performance in production applications, call
// `Table#readStream` to get a stream of rows. See the API documentation:
// https://cloud.google.com/nodejs/docs/reference/bigtable/latest/Table#createReadStream
const [allRows] = await table.getRows({filter});
for (const row of allRows) {
  console.log(`\tRead: ${getRowGreeting(row)}`);
}

테이블 삭제

테이블의 delete() 메서드를 사용하여 테이블을 삭제합니다.

console.log('Delete the table');
await table.delete();

요약 정리

다음은 주석이 없는 전체 코드 샘플입니다.



const {Bigtable} = require('@google-cloud/bigtable');

const TABLE_ID = 'Hello-Bigtable';
const COLUMN_FAMILY_ID = 'cf1';
const COLUMN_QUALIFIER = 'greeting';
const INSTANCE_ID = process.env.INSTANCE_ID;

if (!INSTANCE_ID) {
  throw new Error('Environment variables for INSTANCE_ID must be set!');
}

const getRowGreeting = row => {
  return row.data[COLUMN_FAMILY_ID][COLUMN_QUALIFIER][0].value;
};

(async () => {
  try {
    const bigtableClient = new Bigtable();
    const instance = bigtableClient.instance(INSTANCE_ID);

    const table = instance.table(TABLE_ID);
    const [tableExists] = await table.exists();
    if (!tableExists) {
      console.log(`Creating table ${TABLE_ID}`);
      const options = {
        families: [
          {
            name: COLUMN_FAMILY_ID,
            rule: {
              versions: 1,
            },
          },
        ],
      };
      await table.create(options);
    }

    console.log('Write some greetings to the table');
    const greetings = ['Hello World!', 'Hello Bigtable!', 'Hello Node!'];
    const rowsToInsert = greetings.map((greeting, index) => ({
      key: `greeting${index}`,
      data: {
        [COLUMN_FAMILY_ID]: {
          [COLUMN_QUALIFIER]: {
            timestamp: new Date(),
            value: greeting,
          },
        },
      },
    }));
    await table.insert(rowsToInsert);

    const filter = [
      {
        column: {
          cellLimit: 1, // Only retrieve the most recent version of the cell.
        },
      },
    ];

    console.log('Reading a single row by row key');
    const [singleRow] = await table.row('greeting0').get({filter});
    console.log(`\tRead: ${getRowGreeting(singleRow)}`);

    console.log('Reading the entire table');
    const [allRows] = await table.getRows({filter});
    for (const row of allRows) {
      console.log(`\tRead: ${getRowGreeting(row)}`);
    }

    console.log('Delete the table');
    await table.delete();
  } catch (error) {
    console.error('Something went wrong:', error);
  }
})();