1. ภาพรวม
ใน Codelab นี้ คุณสร้างฟรอนท์เอนด์ของเว็บบน Google App Engine ซึ่งช่วยให้ผู้ใช้สามารถอัปโหลดภาพจากเว็บแอปพลิเคชัน ตลอดจนเรียกดูรูปภาพที่อัปโหลดและภาพขนาดย่อได้
เว็บแอปพลิเคชันนี้จะใช้เฟรมเวิร์ก CSS ชื่อ Bulma เพื่อให้มีอินเทอร์เฟซผู้ใช้ที่ดูดีและเฟรมเวิร์กฟรอนท์เอนด์ของ JavaScript Vue.JS เพื่อเรียกใช้ API ของแอปพลิเคชันที่คุณจะสร้าง
แอปพลิเคชันนี้จะประกอบด้วยแท็บ 3 แท็บดังนี้
- หน้าแรกซึ่งแสดงภาพขนาดย่อของรูปภาพทั้งหมดที่อัปโหลด พร้อมกับรายการป้ายกำกับที่อธิบายรูปภาพ (รูปที่ Cloud Vision API ตรวจพบในห้องทดลองก่อนหน้านี้)
- หน้าภาพคอลลาจที่จะแสดงภาพคอลลาจจากรูปภาพ 4 ภาพล่าสุดที่อัปโหลด
- หน้าอัปโหลดที่ผู้ใช้สามารถอัปโหลดรูปภาพใหม่ๆ ได้
ส่วนหน้าที่ได้จะมีลักษณะดังนี้
ทั้ง 3 หน้านั้นเป็นหน้า HTML แบบง่ายดังนี้
- หน้าแรก (
index.html
) เรียกใช้โค้ดแบ็กเอนด์ของ Node App Engine เพื่อรับรายการภาพขนาดย่อและป้ายกำกับผ่านการเรียกใช้ AJAX ไปยัง URL ของ/api/pictures
หน้าแรกใช้ Vue.js เพื่อดึงข้อมูลนี้ - หน้าภาพต่อกัน (
collage.html
) จะชี้ไปที่รูปภาพcollage.png
ซึ่งประกอบด้วยรูปภาพล่าสุด 4 รูป - หน้าอัปโหลด (
upload.html
) มีแบบฟอร์มง่ายๆ ให้อัปโหลดรูปภาพผ่านคำขอ POST ไปยัง URL ของ/api/pictures
สิ่งที่คุณจะได้เรียนรู้
- App Engine
- Cloud Storage
- Cloud Firestore
2. การตั้งค่าและข้อกำหนด
การตั้งค่าสภาพแวดล้อมตามเวลาที่สะดวก
- ลงชื่อเข้าใช้ Google Cloud Console และสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่ซ้ำ หากยังไม่มีบัญชี Gmail หรือ Google Workspace คุณต้องสร้างบัญชี
- ชื่อโครงการคือชื่อที่แสดงของผู้เข้าร่วมโปรเจ็กต์นี้ เป็นสตริงอักขระที่ Google APIs ไม่ได้ใช้และคุณอัปเดตได้ทุกเมื่อ
- รหัสโปรเจ็กต์ต้องไม่ซ้ำกันในโปรเจ็กต์ Google Cloud ทั้งหมดและจะเปลี่ยนแปลงไม่ได้ (เปลี่ยนแปลงไม่ได้หลังจากตั้งค่าแล้ว) Cloud Console จะสร้างสตริงที่ไม่ซ้ำกันโดยอัตโนมัติ คือคุณไม่สนว่าอะไรเป็นอะไร ใน Codelab ส่วนใหญ่ คุณจะต้องอ้างอิงรหัสโปรเจ็กต์ (ซึ่งปกติระบุไว้ว่าเป็น
PROJECT_ID
) ดังนั้นหากไม่ชอบ ให้สร้างรหัสแบบสุ่มขึ้นมาอีกรหัสหนึ่ง หรือคุณจะลองใช้รหัสโปรเจ็กต์ของคุณเองแล้วดูว่ารหัสโปรเจ็กต์พร้อมใช้งานหรือไม่ แล้วก็ "แช่แข็ง" หลังจากสร้างโปรเจ็กต์แล้ว - มีค่าที่ 3 คือหมายเลขโปรเจ็กต์ที่ API บางตัวใช้ ดูข้อมูลเพิ่มเติมเกี่ยวกับค่าทั้ง 3 ค่าเหล่านี้ในเอกสารประกอบ
- ถัดไป คุณจะต้องเปิดใช้การเรียกเก็บเงินใน Cloud Console เพื่อใช้ทรัพยากร/API ของระบบคลาวด์ การใช้งาน Codelab นี้น่าจะไม่มีค่าใช้จ่ายใดๆ หากมี หากต้องการปิดทรัพยากรเพื่อไม่ให้มีการเรียกเก็บเงินนอกเหนือจากบทแนะนำนี้ ให้ทำตาม "การล้าง" ดูได้ที่ตอนท้ายของ Codelab ผู้ใช้ใหม่ของ Google Cloud จะมีสิทธิ์เข้าร่วมโปรแกรมทดลองใช้ฟรี$300 USD
เริ่มต้น Cloud Shell
แม้ว่าคุณจะดำเนินการ Google Cloud จากระยะไกลได้จากแล็ปท็อป แต่คุณจะใช้ Google Cloud Shell ซึ่งเป็นสภาพแวดล้อมแบบบรรทัดคำสั่งที่ทำงานในระบบคลาวด์ใน Codelab นี้
จากคอนโซล Google Cloud ให้คลิกไอคอน Cloud Shell ในแถบเครื่องมือด้านขวาบน ดังนี้
การจัดสรรและเชื่อมต่อกับสภาพแวดล้อมนี้ควรใช้เวลาเพียงครู่เดียว เมื่อเสร็จแล้ว คุณจะเห็นข้อมูลต่อไปนี้
เครื่องเสมือนนี้เต็มไปด้วยเครื่องมือการพัฒนาทั้งหมดที่คุณต้องการ โดยมีไดเรกทอรีหลักขนาด 5 GB ที่ใช้งานได้ต่อเนื่องและทำงานบน Google Cloud ซึ่งช่วยเพิ่มประสิทธิภาพของเครือข่ายและการตรวจสอบสิทธิ์ได้อย่างมาก งานทั้งหมดใน Lab นี้สามารถทำได้โดยใช้เบราว์เซอร์
3. เปิดใช้ API
App Engine ต้องใช้ API ของ Compute Engine ตรวจสอบว่าได้เปิดใช้แล้ว โดยทำดังนี้
gcloud services enable compute.googleapis.com
คุณควรเห็นการดำเนินการเสร็จสมบูรณ์แล้ว
Operation "operations/acf.5c5ef4f6-f734-455d-b2f0-ee70b5a17322" finished successfully.
4. โคลนโค้ด
ดูรหัส ถ้ายังไม่ได้ดำเนินการ
git clone https://github.com/GoogleCloudPlatform/serverless-photosharing-workshop
จากนั้นคุณจะไปที่ไดเรกทอรีที่มีฟรอนท์เอนด์ได้โดยทำดังนี้
cd serverless-photosharing-workshop/frontend
คุณจะได้เลย์เอาต์ไฟล์ต่อไปนี้สำหรับฟรอนท์เอนด์
frontend | ├── index.js ├── package.json ├── app.yaml | ├── public | ├── index.html ├── collage.html ├── upload.html | ├── app.js ├── script.js ├── style.css
ที่รากของโครงการของเรา คุณมีไฟล์ 3 ไฟล์ ได้แก่
index.js
มีโค้ด Node.jspackage.json
กำหนดทรัพยากร Dependency ของไลบรารีapp.yaml
เป็นไฟล์การกำหนดค่าสำหรับ Google App Engine
โฟลเดอร์ public
มีทรัพยากรแบบคงที่:
index.html
คือหน้าที่แสดงภาพขนาดย่อและป้ายกำกับทั้งหมดcollage.html
แสดงภาพต่อกันของรูปภาพล่าสุดupload.html
มีแบบฟอร์มสำหรับอัปโหลดรูปภาพใหม่app.js
กำลังใช้ Vue.js เพื่อเติมข้อมูลในหน้าindex.html
script.js
จัดการเมนูการนำทางและ "แฮมเบอร์เกอร์" ไอคอนบนหน้าจอขนาดเล็กstyle.css
กำหนดคำสั่ง CSS บางรายการ
5. สำรวจโค้ด
การขึ้นต่อกัน
ไฟล์ package.json
จะกำหนดทรัพยากร Dependency ของไลบรารีที่ต้องการดังนี้
{
"name": "frontend",
"version": "0.0.1",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"@google-cloud/firestore": "^3.4.1",
"@google-cloud/storage": "^4.0.0",
"express": "^4.16.4",
"dayjs": "^1.8.22",
"bluebird": "^3.5.0",
"express-fileupload": "^1.1.6"
}
}
ใบสมัครของเราขึ้นอยู่กับปัจจัยต่อไปนี้
- firestore: เข้าถึง Cloud Firestore ที่มีข้อมูลเมตาของรูปภาพ
- พื้นที่เก็บข้อมูล: เพื่อเข้าถึง Google Cloud Storage ซึ่งเก็บรูปภาพไว้
- express: เฟรมเวิร์กเว็บสำหรับ Node.js
- dayjs: ไลบรารีขนาดเล็กที่แสดงวันที่ในลักษณะที่มนุษย์เข้าใจ
- bluebird: ไลบรารี JavaScript ที่มีสัญญา
- express-fileupload: ไลบรารีสำหรับจัดการการอัปโหลดไฟล์ได้อย่างง่ายดาย
ฟรอนท์เอนด์ Express
ในตอนต้นของตัวควบคุม index.js
คุณจะต้องมีทรัพยากร Dependency ทั้งหมดที่กำหนดไว้ใน package.json
ก่อนหน้านั้น
const express = require('express');
const fileUpload = require('express-fileupload');
const Firestore = require('@google-cloud/firestore');
const Promise = require("bluebird");
const {Storage} = require('@google-cloud/storage');
const storage = new Storage();
const path = require('path');
const dayjs = require('dayjs');
const relativeTime = require('dayjs/plugin/relativeTime')
dayjs.extend(relativeTime)
จากนั้นจึงสร้างอินสแตนซ์แอปพลิเคชัน Express ขึ้น
มิดเดิลแวร์ Express จำนวน 2 รายการที่ใช้ ได้แก่
- การเรียก
express.static()
ระบุว่าทรัพยากรแบบคงที่จะมีให้บริการในไดเรกทอรีย่อยpublic
- และ
fileUpload()
กำหนดค่าการอัปโหลดไฟล์เพื่อจำกัดขนาดไฟล์ไว้ที่ 10 MB เพื่ออัปโหลดไฟล์ในระบบไฟล์ภายในหน่วยความจำในไดเรกทอรี/tmp
const app = express();
app.use(express.static('public'));
app.use(fileUpload({
limits: { fileSize: 10 * 1024 * 1024 },
useTempFiles : true,
tempFileDir : '/tmp/'
}))
หนึ่งในแหล่งข้อมูลแบบคงที่ ได้แก่ ไฟล์ HTML สำหรับหน้าแรก หน้าภาพคอลลาจ และหน้าอัปโหลด หน้าเว็บเหล่านั้นจะเรียก API แบ็กเอนด์ API นี้จะมีปลายทางต่อไปนี้
POST /api/pictures
ผ่านแบบฟอร์มใน upload.html รูปภาพจะได้รับการอัปโหลดผ่านคำขอ POSTGET /api/pictures
ปลายทางนี้จะแสดงเอกสาร JSON ที่มีรายการรูปภาพและป้ายกำกับของรูปภาพGET /api/pictures/:name
URL นี้เปลี่ยนเส้นทางไปยังตำแหน่งพื้นที่เก็บข้อมูลระบบคลาวด์ของรูปภาพขนาดเต็มGET /api/thumbnails/:name
URL นี้เปลี่ยนเส้นทางไปยังตำแหน่งพื้นที่เก็บข้อมูลระบบคลาวด์ของภาพขนาดย่อGET /api/collage
URL ล่าสุดนี้เปลี่ยนเส้นทางไปยังตำแหน่งพื้นที่เก็บข้อมูลระบบคลาวด์ของภาพคอลลาจที่สร้างขึ้น
การอัปโหลดรูปภาพ
ก่อนที่จะสำรวจการอัปโหลดภาพโค้ด Node.js โปรดดูที่ public/upload.html
อย่างรวดเร็ว
...
<form method="POST" action="/api/pictures" enctype="multipart/form-data">
...
<input type="file" name="pictures">
<button>Submit</button>
...
</form>
...
องค์ประกอบแบบฟอร์มจะชี้ไปยังปลายทาง /api/pictures
พร้อมเมธอด HTTP POST และรูปแบบที่มีหลายส่วน ตอนนี้ index.js
จะต้องตอบสนองต่อปลายทางและเมธอดดังกล่าว และแตกไฟล์ดังนี้
app.post('/api/pictures', async (req, res) => {
if (!req.files || Object.keys(req.files).length === 0) {
console.log("No file uploaded");
return res.status(400).send('No file was uploaded.');
}
console.log(`Receiving files ${JSON.stringify(req.files.pictures)}`);
const pics = Array.isArray(req.files.pictures) ? req.files.pictures : [req.files.pictures];
pics.forEach(async (pic) => {
console.log('Storing file', pic.name);
const newPicture = path.resolve('/tmp', pic.name);
await pic.mv(newPicture);
const pictureBucket = storage.bucket(process.env.BUCKET_PICTURES);
await pictureBucket.upload(newPicture, { resumable: false });
});
res.redirect('/');
});
ก่อนอื่นให้คุณตรวจสอบว่ามีการอัปโหลดไฟล์อยู่จริงหรือไม่ จากนั้นดาวน์โหลดไฟล์ในเครื่องผ่านเมธอด mv
ที่มาจากโมดูลโหนดการอัปโหลดไฟล์ของเรา เมื่อไฟล์พร้อมใช้งานในระบบไฟล์ในเครื่องแล้ว คุณจึงอัปโหลดรูปภาพไปยังที่เก็บข้อมูล Cloud Storage ขั้นตอนสุดท้าย ให้คุณเปลี่ยนเส้นทางผู้ใช้กลับไปยังหน้าจอหลักของแอปพลิเคชัน
แสดงรายการรูปภาพ
ได้เวลาแสดงรูปภาพสวยๆ แล้ว
ในเครื่องจัดการ /api/pictures
ให้ดูคอลเล็กชัน pictures
ของฐานข้อมูล Firestore เพื่อเรียกดูรูปภาพทั้งหมด (ที่มีการสร้างภาพขนาดย่อ) โดยเรียงลำดับตามวันที่สร้างจากมากไปหาน้อย
พุชรูปภาพแต่ละรูปในอาร์เรย์ JavaScript โดยใช้ชื่อและป้ายกำกับที่อธิบาย (มาจาก Cloud Vision API), สีที่โดดเด่น และวันที่สร้าง (ด้วย dayjs
เราจะปรับการชดเชยเวลาเช่น "3 วันนับจากนี้")
app.get('/api/pictures', async (req, res) => {
console.log('Retrieving list of pictures');
const thumbnails = [];
const pictureStore = new Firestore().collection('pictures');
const snapshot = await pictureStore
.where('thumbnail', '==', true)
.orderBy('created', 'desc').get();
if (snapshot.empty) {
console.log('No pictures found');
} else {
snapshot.forEach(doc => {
const pic = doc.data();
thumbnails.push({
name: doc.id,
labels: pic.labels,
color: pic.color,
created: dayjs(pic.created.toDate()).fromNow()
});
});
}
console.table(thumbnails);
res.send(thumbnails);
});
ตัวควบคุมนี้จะแสดงผลลัพธ์ของรูปร่างต่อไปนี้:
[
{
"name": "IMG_20180423_163745.jpg",
"labels": [
"Dish",
"Food",
"Cuisine",
"Ingredient",
"Orange chicken",
"Produce",
"Meat",
"Staple food"
],
"color": "#e78012",
"created": "a day ago"
},
...
]
ข้อมูลโค้ด Vue.js ขนาดเล็กจากหน้า index.html
จะใช้โครงสร้างข้อมูลนี้ นี่คือมาร์กอัปเวอร์ชันแบบง่ายจากหน้าดังกล่าว
<div id="app">
<div class="container" id="app">
<div id="picture-grid">
<div class="card" v-for="pic in pictures">
<div class="card-content">
<div class="content">
<div class="image-border" :style="{ 'border-color': pic.color }">
<a :href="'/api/pictures/' + pic.name">
<img :src="'/api/thumbnails/' + pic.name">
</a>
</div>
<a class="panel-block" v-for="label in pic.labels" :href="'/?q=' + label">
<span class="panel-icon">
<i class="fas fa-bookmark"></i>
</span>
{{ label }}
</a>
</div>
</div>
</div>
</div>
</div>
</div>
รหัสของ div จะระบุ Vue.js ว่าเป็นส่วนหนึ่งของมาร์กอัปที่จะแสดงผลแบบไดนามิก การทำซ้ำเป็นไปโดยใช้คำสั่ง v-for
รูปภาพจะมีเส้นขอบที่มีสีดี ซึ่งสอดคล้องกับสีเด่นในภาพ ตามที่ Cloud Vision API พบ และเราจะชี้ไปที่ภาพขนาดย่อและรูปภาพขนาดเต็มในลิงก์และแหล่งที่มาของรูปภาพ
สุดท้าย เราแสดงป้ายกำกับที่อธิบายรูปภาพ
โค้ด JavaScript สำหรับข้อมูลโค้ด Vue.js (ในไฟล์ public/app.js
ที่นำเข้าด้านล่างของหน้า index.html
) มีดังนี้
var app = new Vue({
el: '#app',
data() {
return { pictures: [] }
},
mounted() {
axios
.get('/api/pictures')
.then(response => { this.pictures = response.data })
}
})
โค้ด Vue ใช้ไลบรารี Axios เพื่อเรียก AJAX ไปยังปลายทาง /api/pictures
ของเรา จากนั้นข้อมูลที่ส่งคืนจะถูกเชื่อมโยงกับโค้ดข้อมูลพร็อพเพอร์ตี้ในมาร์กอัปที่คุณเห็นก่อนหน้านี้
การดูรูปภาพ
จาก index.html
ผู้ใช้ของเราสามารถดูภาพขนาดย่อของรูปภาพ และคลิกภาพเพื่อดูภาพขนาดเต็ม และสำหรับ collage.html
ผู้ใช้สามารถดูภาพ collage.png
ในมาร์กอัป HTML ของหน้าเหล่านั้น รูปภาพ src
และลิงก์ href
จะชี้ไปที่ปลายทาง 3 จุดดังกล่าว ซึ่งจะเปลี่ยนเส้นทางไปยังตำแหน่ง Cloud Storage ของรูปภาพ ภาพขนาดย่อ และภาพต่อกัน ไม่จำเป็นต้องฮาร์ดโค้ดเส้นทางในมาร์กอัป HTML
app.get('/api/pictures/:name', async (req, res) => {
res.redirect(`https://storage.cloud.google.com/${process.env.BUCKET_PICTURES}/${req.params.name}`);
});
app.get('/api/thumbnails/:name', async (req, res) => {
res.redirect(`https://storage.cloud.google.com/${process.env.BUCKET_THUMBNAILS}/${req.params.name}`);
});
app.get('/api/collage', async (req, res) => {
res.redirect(`https://storage.cloud.google.com/${process.env.BUCKET_THUMBNAILS}/collage.png`);
});
การเรียกใช้แอปพลิเคชันโหนด
เมื่อกำหนดปลายทางทั้งหมดแล้ว แอปพลิเคชัน Node.js ของคุณก็จะพร้อมเปิดใช้งาน แอปพลิเคชัน Express จะรอฟังพอร์ต 8080 โดยค่าเริ่มต้น และพร้อมที่จะให้บริการคำขอที่เข้ามาใหม่
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`Started web frontend service on port ${PORT}`);
console.log(`- Pictures bucket = ${process.env.BUCKET_PICTURES}`);
console.log(`- Thumbnails bucket = ${process.env.BUCKET_THUMBNAILS}`);
});
6. ทดสอบในเครื่อง
ทดสอบโค้ดภายในเครื่องเพื่อให้แน่ใจว่าโค้ดใช้งานได้ก่อนทำให้ใช้งานได้บนระบบคลาวด์
คุณต้องส่งออกตัวแปรสภาพแวดล้อม 2 รายการที่สอดคล้องกับที่เก็บข้อมูล Cloud Storage 2 รายการ ดังนี้
export BUCKET_THUMBNAILS=thumbnails-${GOOGLE_CLOUD_PROJECT} export BUCKET_PICTURES=uploaded-pictures-${GOOGLE_CLOUD_PROJECT}
ภายในโฟลเดอร์ frontend
ให้ติดตั้งการอ้างอิง npm และเริ่มต้นเซิร์ฟเวอร์:
npm install; npm start
หากทุกอย่างเป็นไปอย่างถูกต้อง เซิร์ฟเวอร์ควรเริ่มที่พอร์ต 8080:
Started web frontend service on port 8080 - Pictures bucket = uploaded-pictures-${GOOGLE_CLOUD_PROJECT} - Thumbnails bucket = thumbnails-${GOOGLE_CLOUD_PROJECT}
ชื่อจริงของที่เก็บข้อมูลจะปรากฏในบันทึกเหล่านั้น ซึ่งจะเป็นประโยชน์ในการแก้ไขข้อบกพร่อง
คุณใช้ฟีเจอร์แสดงตัวอย่างเว็บจาก Cloud Shell เพื่อเรียกดูแอปพลิเคชันที่ทำงานอยู่ในเครื่องได้โดยทำดังนี้
ใช้ CTRL-C
เพื่อออก
7. ทำให้ใช้งานได้กับ App Engine
แอปพลิเคชันของคุณพร้อมติดตั้งใช้งานแล้ว
กำหนดค่า App Engine
ตรวจสอบไฟล์การกำหนดค่า app.yaml
สำหรับ App Engine โดยทำดังนี้
runtime: nodejs16 env_variables: BUCKET_PICTURES: uploaded-pictures-GOOGLE_CLOUD_PROJECT BUCKET_THUMBNAILS: thumbnails-GOOGLE_CLOUD_PROJECT
บรรทัดแรกประกาศว่ารันไทม์จะอิงตาม Node.js 10 มีการกำหนดตัวแปรสภาพแวดล้อม 2 ตัวให้ชี้ไปที่ที่เก็บข้อมูล 2 ส่วน ได้แก่ รูปภาพต้นฉบับและภาพขนาดย่อ
หากต้องการแทนที่ GOOGLE_CLOUD_PROJECT
ด้วยรหัสโปรเจ็กต์จริง คุณสามารถเรียกใช้คำสั่งต่อไปนี้
sed -i -e "s/GOOGLE_CLOUD_PROJECT/${GOOGLE_CLOUD_PROJECT}/" app.yaml
ทำให้ใช้งานได้
ตั้งค่าภูมิภาคที่ต้องการสำหรับ App Engine โปรดตรวจสอบว่าได้ใช้ภูมิภาคเดียวกันในห้องทดลองก่อนหน้านี้แล้ว
gcloud config set compute/region europe-west1
และทำให้ใช้งานได้:
gcloud app deploy
หลังจากผ่านไป 1-2 นาที ระบบจะแจ้งให้ทราบว่าแอปพลิเคชันกำลังให้บริการรับส่งข้อมูล ดังนี้
Beginning deployment of service [default]... ╔════════════════════════════════════════════════════════════╗ ╠═ Uploading 8 files to Google Cloud Storage ═╣ ╚════════════════════════════════════════════════════════════╝ File upload done. Updating service [default]...done. Setting traffic split for service [default]...done. Deployed service [default] to [https://GOOGLE_CLOUD_PROJECT.appspot.com] You can stream logs from the command line by running: $ gcloud app logs tail -s default To view your application in the web browser run: $ gcloud app browse
นอกจากนี้ คุณยังไปที่ส่วน App Engine ของ Cloud Console เพื่อดูว่าแอปใช้งานได้หรือไม่ และสำรวจฟีเจอร์ของ App Engine เช่น การกำหนดเวอร์ชันและการแยกการรับส่งข้อมูล ดังนี้
8. ทดสอบแอป
หากต้องการทดสอบ ให้ไปที่ URL เริ่มต้นของ App Engine สำหรับแอป (https://<YOUR_PROJECT_ID>.appspot.com/
) และคุณควรจะเห็น UI ฟรอนท์เอนด์พร้อมทำงาน
9. ล้างข้อมูล (ไม่บังคับ)
หากไม่ต้องการใช้แอปนี้ต่อ คุณสามารถล้างทรัพยากรเพื่อประหยัดค่าใช้จ่ายและเป็นพลเมืองระบบคลาวด์ที่ดีโดยรวมโดยการลบโปรเจ็กต์ทั้งหมด โดยทำดังนี้
gcloud projects delete ${GOOGLE_CLOUD_PROJECT}
10. ยินดีด้วย
ยินดีด้วย เว็บแอปพลิเคชัน Node.js ที่โฮสต์บน App Engine นี้จะเชื่อมโยงบริการทั้งหมดของคุณเข้าด้วยกัน และทำให้ผู้ใช้ของคุณสามารถอัปโหลดและแสดงภาพได้
หัวข้อที่ครอบคลุม
- App Engine
- Cloud Storage
- Cloud Firestore