AMP for E-commerce Mobile Application 第3回: アプリケーション全体をAlibaba Cloud ApsaraDB for MongoDBと統合する 

この3部構成のチュートリアルでは、**AMP**を使用して完全に機能するEコマースモバイルアプリケーションを作成する方法を探ります。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/amp-for-e-commerce-part-3-integrating-the-entire-application-with-alibaba-cloud-apsaradb-for-mongodb_589989)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

[Alibaba Cloud Tech Share](https://www.alibabacloud.com/campaign/techshare?spm=a2c65.11461447.0.0.751238b35RUJHp) 執筆、Sai Sarath Chandra。

今回のブログ記事は、「[AMP for E-Commerce 第2回](https://www.alibabacloud.com/blog/amp-for-e-commerce-part-2-creating-backend-with-alibaba-cloud-apsaradb-for-mongodb_588411)」の続きです。

前回は、AMPフレームワーク、[ECSインスタンス](https://www.alibabacloud.com/product/ecs?spm=a2c65.11461447.0.0.751238b35x9pLu)、Alibaba Cloud [ApsaraDB for MongoDB](https://www.alibabacloud.com/product/apsaradb-for-mongodb?spm=a2c65.11461447.0.0.751238b35x9pLu)について多くのことを学びました。必要とされるすべての製品に精通している今、私たちは、利用可能なすべての驚くべき情報のすべてのピースを使用して実際にソリューションを作成し、実際に実世界のシナリオを解決していきます。

###全体的なアーキテクチャ
これらは、以下のアーキテクチャを実現するためのソリューションの一部です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/d90476d9-1be7-0ed6-a61b-251652b24849.png)

上記は非常にシンプルなアーキテクチャで、顧客がブラウザ経由でAMPページへのリクエストを行い、それがウェブサイトやウェブページをホストしているウェブサーバを実行している[ECSインスタンス](https://www.alibabacloud.com/product/ecs?spm=a2c65.11461447.0.0.751238b3BmKrpH)にヒットします。Alibaba Cloud [ApsaraDB for MongoDB](https://www.alibabacloud.com/product/apsaradb-for-mongodb?spm=a2c65.11461447.0.0.751238b3BmKrpH)に接続して、クライアントの要求に応じて読み取り要求を行い、非常に迅速にデータを返してから、ノードがホストされているAPIは、AMPページに戻って情報を渡し、それが処理され、関連する情報を表示するためにWebページで使用されるようになります。

1、[最初のチュートリアル](https://www.alibabacloud.com/blog/amp-for-e-commerce-part-2-creating-backend-with-alibaba-cloud-apsaradb-for-mongodb_588411)で見たように、すでにAlibaba Cloud [ApsaraDB for MongoDB](https://www.alibabacloud.com/product/apsaradb-for-mongodb?spm=a2c65.11461447.0.0.751238b35x9pLu)を作成しました。
2、これからは、[ApsaraDB for MongoDB](https://www.alibabacloud.com/product/apsaradb-for-mongodb?spm=a2c65.11461447.0.0.751238b35x9pLu)から情報を取得するためのNodeベースのAPIを作成していきます。
3、既存のオープンソースのApache 2.0 AMPテンプレートも、こちらの要望に合わせて修正していきます。なぜこのようなことをするかというと、 チュートリアルで全体のデザインを完成させるのに時間がかかってしまい、目的を果たせていないからです。
4、[ApsaraDB for MongoDB](https://www.alibabacloud.com/product/apsaradb-for-mongodb?spm=a2c65.11461447.0.0.751238b3BmKrpH)をAMPサイトと統合して、本当に動的なものにしていき、同じようにテストしていきます。

さて、いよいよスタートです。

###データベースへのデータの挿入
作成とテストを始める前に、DBにデータを挿入する必要があります。

**ECSにダウンロードするソフトウェア**
1、Visual Studioコード(できれば最新版)

- これは私が使用するエディタです、あなたの好きなエディタに切り替えることができます。

2、Google Chrome

- デモではこれを高速化するためにChromeのプラグインを使っています。

3、Chrome用のWebサーバープラグイン

- [https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?hl=en](https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?spm=a2c65.11461447.0.0.751238b35x9pLu&hl=en)
- POCに最適なプラグインです。


4、ROBO 3T's - Studio 3T製品。

- これは私の意見では、クエリを作成したりテストしたりする能力を損なうことなく、MongoDBとのGUIインタラクションを提供する非常に良い製品です。

**MongoDB用のApsaraDBにデータをアップロードする**
1、ECSインスタンスへのログオン

2、Open Studio 3T製品です。以下のスクリーンショットに関連するものが表示されます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/dea87e0f-2cd6-9e8d-edff-beb11e74ec58.png)

接続をクリックすると、次のウィンドウが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/d32f1645-a51b-8c75-0b00-a42ce8361e04.png)

私はすでにサーバーを追加していますが、私は1つを追加する方法を紹介しますが、あなたは[ApsaraDB for MongoDB](https://www.alibabacloud.com/product/apsaradb-for-mongodb?spm=a2c65.11461447.0.0.751238b35x9pLu)コンソールから "接続文字列のURI "を確認してください。我々は、この文字列を使用して接続されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/d2758ca7-470f-5e9e-a800-adf7360db52a.png)

「New Connection」をクリックして「From URI...」を選択すると、ポップアップから接続URI文字列を入力する入力ボックスが表示されます。

接続URI文字列を入力する際には、**** でルートパスワードを置き換えた状態で入力していることを確認してください。正しく行えば、これに関連したものが表示されるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/7edf27e5-b664-89bf-dae0-da3911c07df3.png)

上記のスクリーンショットのようなものが表示されたら、おめでとうございます。これでデータベースに接続できました。

では、MongoDBにデータを挿入してみましょう。

クローンしたコードの「[ExpressJSベースのAPI](https://github.com/saichandu415/AMP-Ecommerce-Apsara/tree/master/ExpressJS%20based%20API?spm=a2c65.11461447.0.0.751238b35x9pLu)/json/」に移動します。Studio 3Tを使ってデータベースに挿入するサンプルを表示します。

例では、私は "high-low-accessories-products.json"を選択します。

```
{
"name": "Chain set",
"description": "Silver alloy construction for durability.",
"price": 867,
"image": "/img/e-commerce/product/product-3.jpg",
"category": "accessories"
},
{
"name": "Red Cruiser",
"description": "Smooth ride for enjoyable cruising.",
"price": 688,
"image": "/img/e-commerce/product/product-6.jpg",
"category": "accessories"
},
{
"name": "Road Bike",
"description": "Built with lightweight aluminum for speed.",
"price": 644,
"image": "/img/e-commerce/product/product-9.jpg",
"category": "accessories"
},
{
"name": "Fixie Blue",
"description": "Designed to get you there.",
"price": 643,
"image": "/img/e-commerce/product/product-2.jpg",
"category": "accessories"
},
{
"name": "16-Speed",
"description": "Smooth shifting through all gears for city riding.",
"price": 524,
"image": "/img/e-commerce/product/product-5.jpg",
"category": "accessories"
},
{
"name": "Leather Saddle",
"description": "Firm, yet comfortable for long leisurely rides.",
"price": 476,
"image": "/img/e-commerce/product/product-4.jpg",
"category": "accessories"
}
```

Studio 3T に移動し、"admin "データベースを展開し、コレクションを右クリックして、"Add Collection "を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/3d7ff639-353e-c833-7b87-63549515aeb2.png)

繰り返しになりますが、コレクションとは情報の集合体であり、この場合はこのjson構造体を配置します。以下のような画面が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/fdbe442d-3c10-5b48-7384-68e3fe144334.png)

拡張子.jsonを付けずに「high-low-accessories-products」という名前を付けて「作成」をクリックします。次に、コレクションに移動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/48eb5104-7315-927e-8feb-8fc409cdef47.png)

JSONビューに切り替えて、提供されたJSONをコピーペーストします。ポップアップが表示されますので、クリックしてください。すべてが正常に行われると、次のような画面が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/9e6df737-f620-cd06-25c9-60a4d1f2cba7.png)

同じようにすべての.jsonドキュメントをアップロードすると、上の画像のように8つのコレクションが表示されるはずです。

###ApsaraDB for MongoDBにアクセスする、ノードベースのExpressAPIの作成とテスト
Alibaba Cloudの[ApsaraDB for MongoDB](https://www.alibabacloud.com/product/apsaradb-for-mongodb?spm=a2c65.11461447.0.0.751238b35x9pLu)と連携して、フロントエンドにサーブしながらデータを取得するAPIをデプロイする作業を行います。

時間の都合上、次のリンクにアクセスしてコードのクローンを作成してください。

[https://github.com/saichandu415/AMP-Ecommerce-Apsara/tree/master/ExpressJS%20based%20API](https://github.com/saichandu415/AMP-Ecommerce-Apsara/tree/master/ExpressJS%20based%20API?spm=a2c65.11461447.0.0.751238b35x9pLu)

これは非常にシンプルなAPIで、データベースからデータを取得することにのみ焦点を当てています。

コードが何なのか、何をするのかを説明します。コード全体は実際には "app.js "の中にあります。

```
'use strict'

var express = require('express');
var formidable = require('formidable');
var uuid = require('node-uuid');
var https = require('https');
var fs = require('fs');
var sprintf = require("sprintf-js").sprintf;
var mongoClient = require('mongodb').MongoClient;
var dummyJson = require('./json/dummyvalue.json');

var app = express();


//code to enable https
var sslOptions = {
key: fs.readFileSync('./cert/key.pem'),
cert: fs.readFileSync('./cert/cert.pem'),
passphrase: 'saisarath'
};

//Mongo DB Instance Details
var host1 = "dds-6gj54086e0c157941.mongodb.ap-south-1.rds.aliyuncs.com";
var port1 = 3717;
var host2 = "dds-6gj54086e0c157942.mongodb.ap-south-1.rds.aliyuncs.com";
var port2 = 3717;
var username = "root";
var password = "Mongodb123";
var replSetName = "mgset-1050000641";
var demoDb = "admin";

var url = sprintf("mongodb://%s:%d,%s:%d/%s?replicaSet=%s", host1, port1, host2, port2, demoDb, replSetName);

console.info("url generated:", url);

app.get('/ampdemo/getData', function (req, res) {

//Headers to make AMP Accept
res.setHeader('AMP-Access-Control-Allow-Source-Origin','http://127.0.0.1:8000');
res.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:8000');

console.log(JSON.stringify(req.query));

if (req.query && req.query.selection) {
//call promise and fetch data
var getData = fetchFromMongo(req.query.selection);
getData.then(function (dataFrmDB) {
//create response object
var response = {};
response.items = dataFrmDB;
res.status(200).json(response);
}, function (err) {
res.status(400).json(err);
});
} else {
res.status(400).json({ error: 'Please choose a selection' });
}
});


app.use('/', express.static('static'));

https.createServer(sslOptions, app).listen(443, function () {
console.log('Server for "Advanced Interactivity in AMP" codelab listening on port 443!');
});


function fetchFromMongo(collection) {

var coll2Fetch = collection;

return new Promise(function (resolve, reject) {
// Logic to fetch from the MongoDB
mongoClient.connect(url, function (err, db) {
//if error console error
console.log(err);
if (err) {
// Database not connected : error thrown
console.error("connect err:", err);
reject(err);
} else {
//Database connected successfully, get the DB Object
var adminDb = db.admin();
//Authenticate Database
adminDb.authenticate(username, password, function (err, result) {
if (err) {
console.log("authenticate err:", JSON.stringyfy(err));
reject(err);
} else {
console.log('Authenticated : ', JSON.stringify(result));
// Get the Collection handle.
var collection = db.collection(coll2Fetch);
collection.find({}).toArray(function (err, items) {
if (err) {
console.error('Unable to find data' + JSON.stringify(err));
} else {
console.info('data Fetched from MongoDB');
resolve(items);
}
});
}
});
}
});
});
}
```

**sslOptions** - AMPはhttpプロトコルの使用を厳密に禁止しているので、httpプロトコルで話をすることはできないことを覚えておく必要があります。自分自身で証明書を作成し、httpsが有効になるようにしました。

**MongoDBインスタンスの詳細** - 我々は、すべての詳細を持つコードを介してDBインスタンスに接続されて取得するために、ここでmongoDBの詳細を更新します。

Port - ノードのポート番号

Host - ノードのホスト名

Username - ReplicaSetのユーザー名

Password  - デプロイ時に設定されたレプリカに割り当てられたパスワード

replicasetname - MongoDB インスタンスのデプロイ後に生成されるレプリカセット名。

DemoDb - アクセスしたいDB名、おそらくこのデモの管理者と思われるDB名です。

**ヘッダー**：

```
res.setHeader('AMP-Access-Control-Allow-Source-Origin','http://127.0.0.1:8000');
res.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:8000');
```

これらのヘッダは、クロスドメインリクエストにアクセスするためにAPIに言っていることを意味するので、非常に重要です。実際のシナリオでは、localhost の IP を実際の IP に置き換えてください。

**FetchFromMongo() **：

このメソッドは、いくつかのステップを経てMongoDBからデータを取得します。Alibaba Cloud [ApsaraDB for MongoDB](https://www.alibabacloud.com/product/apsaradb-for-mongodb?spm=a2c65.11461447.0.0.751238b35x9pLu)用の情報を取得する手順を見てみましょう。

1、リクエストからクエリパラメータを取得する

- 1つのエンドポイントを使用し、クエリパラメータに基づいて情報を変化させることで、APIエンドから複数のURIを使用しないようにしています。

2、mongoClientオブジェクトの取得

- 認証などの基本的な機能を実行するために、mongoClientオブジェクトのインスタンスを取得しなければなりません。

3、データベースの取得

- DBが接続されたら 操作したいデータベースをポイントします。

4、DBの認証

- 認証ステップを実行して、データベースの完全な権利を取得します。

5、コレクションを識別する

- 操作を行いたいコレクションを特定する必要があるので、クエリパラメータに基づいてコレクションを選択しています。

6、Operate および構造のコレクション データ

- データを見つけたら、データの操作を行い、要件に基づいてデータを再構築する必要があります。

**ＵＲＩ形式**
URIは "https://<host>:<port>/ampdemo/getData?select=<collectionname>>"でなければなりません。

選択パラメータがない場合は、次のようなエラーが発生します。

400 Bad Request - 選択してください。

**HTTPSを使用する**
AMP は https プロトコルしか受け付けないので、デプロイする API が https で公開されていることを確認してください。この現在の API は、ポート 443 の https を有効にした場合に動作します。

###APIの実行方法
visual studioを使用している場合、エディタに移動して "CTRL + SHIFT + C "を押すと、コマンドプロンプトが表示されるので、コマンド "node app.js "を実行する必要があります。

visual studioを使用していない場合は、スタートメニューからコマンドプロンプトを開き、"cd "コマンドを使用して対応するフォルダに移動し、"node app.js "コマンドを実行する必要があります。あなたが正しく行われている場合は、両方のケースでは、以下のようなものが表示されるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/387ab13a-305c-bfec-ff2a-99687877e48a.png)


その後、ブラウザに進んでAPIの呼び出しを開始します。変数ECS_Internet_IPを実際のIPアドレスに合わせて変更します。

https://<ECS_Internet_IP>:443/ampdemo/getdata?select=high-low-accessories-products

自己生成された証明書を使用しているので、ブラウザで少なくとも一度はヒットして、例外の追加をクリックして、システムで証明書を受け入れる必要があります。現実世界の生産シナリオでは、あなたの証明書が適切に登録されるため、これは問題ではないことがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/8b59ef0e-6721-037a-3028-6f4e0f135517.png)

セキュリティ例外を追加したら、ブラウザで情報を確認できるようになるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/32f11fdd-e0ba-e257-f44c-1a05df116d6e.png)

おめでとうございます。[Alibaba Cloud ECSインスタンス](https://www.alibabacloud.com/product/ecs?spm=a2c65.11461447.0.0.751238b35x9pLu)に最初のAPIをデプロイしました。

###AMP E-Commerce UI
これで完全なチュートリアルになります。既存のリポジトリのクローンを作成して、それがどのように行われるか、およびこれまでに学習したコンポーネントの知識をどのように適用するかについて調査を開始していきます。

以下のリンク先のリポジトリをクローンしてください。

[https://github.com/saichandu415/AMP-Ecommerce-Apsara/tree/master/Website](https://github.com/saichandu415/AMP-Ecommerce-Apsara/tree/master/Website?spm=a2c65.11461447.0.0.751238b35x9pLu)

コードのスニペットを説明します。

```
<div class="commerce-select-wrapper inline-block ">
<label for="price" class="bold caps h6 md-h7">Sort by:</label>
<select name="price" id="price" class="commerce-select h6 md-h7" on="change: AMP.setState({products: {filter: event.value}})">
<option value="high-low">Price: High-Low</option>
<option value="low-high">Price: Low-High</option>
</select>
</div>
</div>
</div>

<amp-list class="mx1 md-mxn1" [src]="'https://149.129.130.26:443/ampdemo/getData?selection=' + products.filter + '-' + products.category + '-products'" src="https://149.129.130.26:443/ampdemo/getData?selection=high-low-all-products" height="1000" width="300" layout="responsive">
<template type="amp-mustache">
<a href="product-details.amp.html" target="_self" class="commerce-listing-product text-decoration-none inline-block col-6 md-col-4 lg-col-3 px1 mb2 md-mb4 relative">
<div class="flex flex-column justify-between">
<div>
<amp-img class="commerce-listing-product-image mb2" src="{{image}}" width="340" height="340" layout="responsive" alt="{{ name }}" noloading=""><div placeholder="" class="commerce-loader"></div></amp-img>
<h2 class="commerce-listing-product-name h6">{{ name }}</h2>
{{ description }}
</div>
<div class="h6 mt1">&#163;{{ price }}</div>
</div>
</a>
</template>
</amp-list>
```

＜select＞ に次のコード行が表示されている場合：`change:AMP.setState（{products：{filter：event.value}}）`これは、AMPでのイベントリスナーの使用法を示しています。ここでは、変更イベントをリッスンしています。 AMP.setStateコンストラクトを使用して、event.valueをproducts products.filterキーに割り当てます。これをさらに使用して、動的クエリを作成します。

`<amp-list class="mx1 md-mxn1" [src]="'https://149.129.130.26:443/ampdemo/getData?selection=' + products.filter + '-' + products.category + '-products'" src="https://149.129.130.26:443/ampdemo/getData?selection=high-low-all-products" height="1000" width="300" layout="responsive”>`

**amp-list **
CORS JSON エンドポイントから動的にコンテンツを取得し、提供されたテンプレートを使用してレンダリングします。

REST ベースのエンドポイントを呼び出し、ユーザーのドロップダウン選択に基づいて動的にそれを割り当て、テンプレートに基づいて全体のコードを生成する amp-list に割り当てます。
`<amp-img class="commerce-listing-product-image mb2" src="{{image}}" width="340" height="340" layout="responsive" alt="{{ name }}" noloading=""><div placeholder="" class="commerce-loader"></div></amp-img>`

**amp-img **：
ここでは、レスポンスの値/パスを使用してテンプレートにレンダリングする amp-img を使用します。

先ほどの例でもう一つ注意すべきことは、テンプレートを動作させるためには、ECSインスタンスのIP int eh [src]とsrcタグを保持しておく必要があるということです。

また、"Webserver for chrome "を使用してウェブサイトをホストすることができます。

これは、クロームのプラグインのダウンロードリンクです。

[https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb/related?hl=en](https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb/related?spm=a2c65.11461447.0.0.751238b35x9pLu&hl=en)

クロームでアプリを開くと、これに関連するものが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/b389662f-3f87-7422-3f8f-83bdbbdf5461.png)

ウェブ上でサービスを提供したいフォルダを選択する必要があります。そうすると、ウェブサーバは自動的に再起動し、テストや進捗状況を確認できるエンドポイントを提供します。これはリアルタイムの生産シナリオには理想的ではありませんが、プロトタイピングをより速くすることができます。

以下のスクリーンショットは、エンドポイントに到達したときにウェブサイトがどのように見えるかを示しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/cfad3ae8-1948-c541-12c7-17ff6241aa13.png)

そして、これが商品一覧ページです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/931a4451-de27-3caf-174c-a804baab1fb4.png)

おめでとうございます。定義されたアーキテクチャでアプリケーションをデプロイしました。

###結論
チュートリアルをたくさん行ったので、疑問や不明点が出てくるかもしれません。その場合はgithubリポジトリに疑問点を挙げてください。できる限り回答します。時間をかけて読んで、必要なコンポーネントを学習してください。あなたの仕事がよりスムーズに進んでいくことでしょう。以下のgithubリンクを見てください：

[https://github.com/saichandu415/AMP-Ecommerce-Apsara](https://github.com/saichandu415/AMP-Ecommerce-Apsara?spm=a2c65.11461447.0.0.751238b35x9pLu)

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*