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

![th.jpeg](https://www.bing.com/th?id=OIP.yovZnkelJ4W3sSoRk-oQtwHaD4&pid=Api&rs=1)

# この記事について

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

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


# 対象読者

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


# Microsoft Azure Cosmos JavaScript SDK

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

## Database

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

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

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

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

```typescript: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`がありますが、一旦置いておいて、実際のコンストラクタの中身を見ていきます。

```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);
  }
```

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

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

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

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

- [TypeScript Handbook - Classes: Parameter properties][TSHandbook]

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

```typescript:
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 ファイルも見てみます。

```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 って本当に便利ですね。*

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

```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);
  }
```

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

```typescript: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) {}
}
```

```typescript: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 記事][PrevLink2]) した時はたったの 1 行で終わってしまった内容です。

前回、

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

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

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


# 関連リンク

## 前回記事

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


# 参考資料

## Microsoft Docs

- [Azure Cosmos DB のデータを管理する例 (Node.js)][MSDocs]

## TypeScript Handbook

- [Classes: Parameter properties][TSHandbook]

## Qiita

- [TypeScript初心者が知っておくと嬉しいこと][Qiita1]


[PrevLink1]:https://qiita.com/ymasaoka/items/18ec24f29fd2a90af4a4
[PrevLink2]:https://qiita.com/ymasaoka/items/0b0b726354c3cfd38021
[MSDocs]:https://docs.microsoft.com/ja-jp/azure/cosmos-db/sql-api-nodejs-samples
[TSHandbook]:https://www.typescriptlang.org/docs/handbook/classes.html#parameter-properties
[Qiita1]:https://qiita.com/kotaonaga/items/13bec787769d6e8efc52