Node.js Hello World

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

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

인증 설정

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

  1. Google Cloud CLI를 설치합니다.
  2. gcloud CLI를 초기화하려면 다음 명령어를 실행합니다.

    gcloud init
  3. Google 계정의 로컬 인증 사용자 인증 정보를 만듭니다.

    gcloud auth application-default login

자세한 내용은 로컬 개발 환경의 인증 설정를 참조하세요.

샘플 실행

이 코드 샘플에서는 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);
  }
})();