2020年から始めるAzure Cosmos DB - JavaScript SDK (SQL API)を見てみる (Part.2)


この記事について

本記事は、2020年3月6日 (米国時間) にて、Azure Cosmos DB に新しく Free Tier (無償利用枠) が登場したことに伴い、改めて Azure Cosmos DB を色々と触っていく試みの 4 回目です。
今回も、
前回記事 同様、 Microsoft Azure Cosmos JavaScript SDK について見ていきたいと思います。

対象読者

  • Azure Cosmos DB について学習したい方
  • Node.js で Azure Cosmos DB への CRUD 操作を行いたい方
  • Microsoft Azure Cosmos JavaScript SDK の動作について理解したい方
  • TypeScript のパラメータプロパティ宣言を知らない方

Microsoft Azure Cosmos JavaScript SDK

実際に、Microsoft Docs の内容を元に、JavaScript SDK (SQL API) の中身を見ていきます。
今回はデータベースの読み取り、または削除を行う Database について確認します。

Database

TypeDoc の記載は、以下の通りです。

Operations for reading or deleting an existing database.
既存のデータベースの読み取りまたは削除の操作。

const client: CosmosClient = new CosmosClient({ endpoint, key });
const database: Database = client.database(databaseId);

実際に使用する際は、CosmosClient クラスを生成した後、CosmosClient クラス内にあるdatabaseメソッドを使用して、Database クラスを生成する手順が必要になります。
CosmosClient クラスのdatabaseメソッドは、どうなっているのか、実際に中身を確認してみます。

Azure/azure-sdk-for-js/sdk/cosmosdb/cosmos/src/CosmosClient.ts
public database(id: string): Database {
  return new Database(this, id, this.clientContext);
}

はい、Database クラスのコンストラクタが動いています。
まあ Database 型の定数(const)に値を代入しているのだから当たり前ですよね。

このコンストラクタ、プログラミング初心者にとってはすごく理解が難しい引数thisがありますが、一旦置いておいて、実際のコンストラクタの中身を見ていきます。

Azure/azure-sdk-for-js/sdk/cosmosdb/cosmos/src/client/Database/Database.ts
export class Database {
  public readonly containers: Containers;
  public readonly users: Users;

  constructor(
    public readonly client: CosmosClient,
    public readonly id: string,
    private clientContext: ClientContext
  ) {
    this.containers = new Containers(this, this.clientContext);
    this.users = new Users(this, this.clientContext);
  }

コンストラクタの第一引数にCosmosClientがあります。
つまり、先ほどの this とは、このコンストラクタの引数に自分自身への参照(CosmosClient)を渡していた、ということです。
ところで、 (私みたいな) TypeScript 初心者がこのコードをみた際、きっと下記のような疑問を持つのではないかと思います。(実は前回の内容の中にも同じものがあったんですけどね、、)

あれ、、先ほど引数で渡してきた CosmosClinet と databaseId、全然使われていないように見えるけど、どうなっているの...!?

安心してください、もちろん渡した引数には意味があります。ここで注目するのはコンストラクタの引数に public/private/readonly の修飾子がついているところです。

TypeScript には、パラメータプロパティ宣言というものがあります。これは、コンストラクタの引数の中でプロパティの作成および初期化が行えるようになるというものです。

つまり、上記で記載した Database クラスのコンストラクタの内容は

export class Database {
  public readonly client: CosmosClient;
  public readonly id: string;
  private clientContext: ClientContext;
  public readonly containers: Containers;
  public readonly users: Users;

  constructor(
    client: CosmosClient,
    id: string,
    clientContext: ClientContext
  ) {
    this.client = client;
    this.id = id;
    this.clientContext = clientContext;
    this.containers = new Containers(this, this.clientContext);
    this.users = new Users(this, this.clientContext);
  }

と同じ内容ということになります。
実際にコンパイルされた後の JavaScript ファイルも見てみます。

Azure/azure-sdk-for-js/sdk/cosmosdb/cosmos/dist/index.js(5988行目付近)
class Database {
  constructor(client, id, clientContext) {
    this.client = client;
    this.id = id;
    this.clientContext = clientContext;
    this.containers = new Containers(this, this.clientContext);
    this.users = new Users(this, this.clientContext);
  }
}

内容が同じであることを確認できました。
TypeScript って本当に便利ですね。

さて、本題のコンストラクタ処理に戻ります。

Azure/azure-sdk-for-js/sdk/cosmosdb/cosmos/src/client/Database/Database.ts(再掲)
export class Database {
  public readonly containers: Containers;
  public readonly users: Users;

  constructor(
    public readonly client: CosmosClient,
    public readonly id: string,
    private clientContext: ClientContext
  ) {
    this.containers = new Containers(this, this.clientContext);
    this.users = new Users(this, this.clientContext);
  }

コンストラクタのパラメータプロパティ宣言を除くと、ContainersUsersのクラスを生成する処理があります。
実際に、この 2 つのコンストラクタの中身をみていきます。

Azure/azure-sdk-for-js/sdk/cosmosdb/cosmos/src/client/Container/Containers.ts
export class Containers {
  constructor(public readonly database: Database, private readonly clientContext: ClientContext) {}
}
Azure/azure-sdk-for-js/sdk/cosmosdb/cosmos/src/client/User/Users.ts
export class Users {
  constructor(public readonly database: Database, private readonly clientContext: ClientContext) {}

また出たな!パラメータプロパティ! ※決してどこかの企業のフレーズを真似したわけではありません笑

ここでもコンストラクタのパラメータプロパティ宣言を使い、ContainersクラスとUsersクラスを生成していますね。このあたりのクラスについては、次回以降、確認していきたいと思います。

さいごに

今回は、Azure Cosmos DB に JavaScript/Node.js で接続する際に CosmosClient クラスを使って生成する Database クラスについて、中身を確認してみました。
今回の内容も、以前、実際に CRUD アプリを作成 (Qiita 記事) した時はたったの 1 行で終わってしまった内容です。

前回、

普段のアプリ開発では、あまり意識しない世界なのかもしれませんが、実際にコンストラクタの中で何が行われているのかを確認することは、Azure Cosmos DB の仕組みや使用するライブラリへの深い知見を得る ためには必要な事かな、と思いました。

と思っていた自分ですが、Microsoft Azure Cosmos JavaScript SDK の中身を見ていくことは、ライブラリの理解だけでなく、TypeScript の勉強もできるという一石二鳥なことではないか、と感じました。他のライブラリについてもこれは同じように言えることだと思います。

次回は、Container/Containersクラスについて見ていこうと思います。

関連リンク

前回記事

参考資料

Microsoft Docs

TypeScript Handbook

Qiita