iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 4
0
Modern Web

30天使用Node.js在AWS上開發後端系列 第 5

30-5 Node.js起手式之專案建立與資料庫串接 (1)

  • 分享至 

  • xImage
  •  

為什麼學Node.js還要使用Express這個框架呢?
其實我自己的想法是, 框架本身畢竟是由一群人維護
身為一般的開發者, 應該專注在開發功能, 其他的只要跟著框架的規則
很多自己做要花很多時間的事情, 幾行之內就結束
不管是Express或是Koa2都可以, 先讓自己專注在功能開發上吧!

使用 Express 應用程式產生器 (Express Generator)

先安裝 Express Generator

打開終端機
輸入
npm install express-generator -g

切換終端機的目錄到桌面
cd Desktop/

接著開始產生Express專案

// myapp 是專案名稱, 你可以自行替換成想要的
express --view=pug myapp

接者會跑一堆字出來之後

   create : myapp
   create : myapp/package.json
   create : myapp/app.js
   create : myapp/public
   create : myapp/public/javascripts
   create : myapp/public/images
   create : myapp/routes
   create : myapp/routes/index.js
   create : myapp/routes/users.js
   create : myapp/public/stylesheets
   create : myapp/public/stylesheets/style.css
   create : myapp/views
   create : myapp/views/index.pug
   create : myapp/views/layout.pug
   create : myapp/views/error.pug
   create : myapp/bin
   create : myapp/bin/www

接下來切換到自己剛剛建立的專案底下

// && 是可以等前面的指令執行完之後, 接著執行後面的
// npm install是幫你把目前這個專案所需要的套件通通安裝
// 專案所需要的套件都會放在package.json內
cd myapp && npm install

接下來就可以直接透過輸入以下指令來啟動Express

node bin/www

建立資料庫相關的程式

通常我會習慣另外開一個models的資料夾在專案內
專門在放處理資料庫相關的程式碼

// 建立models目錄並且進去
// mkdir => make directory, cd => change directory
mkdir models && cd models
// 建立一個 index.js 的檔案
touch index.js

覺得指令麻煩也可以直接用編輯器建立!
只是想說用用指令, 看起來比較帥(?

接著可以用編輯器去編輯這個 index.js
這裡很推薦一定要使用index.js這個檔名
因為之後再引入的時候, 語法寫起來比較好看!
後面會再提到一次不用擔心

/*jslint node: true */
'use strict';

// process.env 是 Node.js 的環境變數
// 通常我會習慣將一些比較機密的東西放在環境變數中
// 這樣就算專案外流, 機密的資料也不會一起外流出去
if (!process.env.mongoHost) {
	console.error('[model]', 'process.env.mongoHost is not set!'); process.exit(0);
}
if (!process.env.mongoAuth) {
	console.error('[model]', 'process.env.mongoAuth is not set!'); process.exit(0);
}

// 引用MongoDB官方自己的程式(library)
const MongoClient = require('mongodb').MongoClient;
// MongoDB在網路上的位址
const host = process.env.mongoHost;
// 驗證資料庫用的字串, 如果不啟用驗證, 每個人都可以連資料庫, 超不安全
const auth = process.env.mongoAuth;
// 資料庫名稱
// process.env.mongodbDatabase || '/fakeig'
// => 就是如果沒有process.env.mongodbDatabase這個值的話, 預設用 'fakeig'
const database = process.env.mongodbDatabase || '/fakeig';

// 連接MongoDB用的URI
// 這是連接MongoDB固定用的格式
// 使用mlab會讓你自己去定義一組帳號密碼, 用來驗證MongoDB
const schema = 'mongodb://' + auth + host + database;

// 設定MongoDB的一些常用設定
const opts = {	
	keepAlive: 1,
	connectTimeoutMS: 30000,
	poolSize: 5,
	native_parser: true,
	autoReconnect: true,
	w: 0
};

// 自己將 MongoClient 的東西額外包裝起來
let mongoNative = {
	_db: null,
	connect: function connect() {
		return MongoClient.connect(schema, opts)
		.catch((err) => {
			console.error('[x] mongodbDatabase:', process.env.mongodbDatabase);
			console.error('[x] host:', host);
			console.error('[x] schema:', schema);
			console.error('[x] Get Database Error:', err);
			process.exit(0);
		});
	}, 
	getDatabase: function getDatabase() {
		return this._db;
	},
	setDatabase: function setDatabase(db) {
		this._db = db;
	}
};

module.exports = mongoNative;

目錄結構會變成以下, 多了models這個目錄

.
├── app.js
├── bin
│   └── www
├── package.json
├── models
    └── index.js
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── users.js
└── views
    ├── error.pug
    ├── index.pug
    └── layout.pug

稍微介紹一下什麼是API(Application Programming Interface)
簡單來說就是你提供一個功能給網頁或是APP呼叫
例如: 註冊會員
我們就可以設計一個API, 網址是http://xxxx.com/api/v1/auth/register 這樣
接下來寫個會員登入的功能吧!
我們會額外多一個路徑叫做ap1/v1
這樣API的網址就會變成 http://xxxx.com/api/v1/auth/facebook/login 這種
會用這樣設計的原因是假如有一天需要重大更新
就可以把v1切換成v2
這樣會比較有彈性!

cd ~/Desktop/myapp/routes
mkdir v1
cd v1
touch index.js

routes/index.js
routes/index.js 是每個進來的API請求都會先經過這隻檔案
這隻檔案再依據api/v1/ 後面不同的路徑, 導向給不同的程式去處理

/*jslint node: true */
'use strict';

const express = require('express');
const router = express.Router();
const cors = require('cors');
const db = require('../models').getDatabase();
// 將v1內的index.js引入
// v1內的index.js用途是將api/v1後面接的路徑, 導向給正確的程式去處理
// ex: api/v1/auth => 導向給v1/auth.js去處理
const v1 = require('./v1');
// 這裡是安全性的考量, 只允許http的GET/POST/PUT/DELETE
const ALLOWED_METHODS = ['GET','POST','PUT','DELETE'];
// 這個是允許跨網域的資源存取
router.use(cors());
router.use((req, res, next) => {
	if (!req.body.hasOwnProperty) req.body.hasOwnProperty = Object.prototype.hasOwnProperty;
	if (ALLOWED_METHODS.indexOf(req.method) === -1) {
		return res.status(405).json({ err: 'Not allowed method' });
	} else {
		console.log(req.method, req.url, "body:", JSON.stringify(req.body), "params:", JSON.stringify(req.params), "headers:", JSON.stringify(req.headers));
		next();
	}
});
// 把網址路徑是api/v1的都導向給v1/index.js去處理
router.use('/api/v1', v1);
module.exports = router;

這篇實在太多東西, 會分成兩至三篇, 會再重新講解一些並總結!


上一篇
30-4 Node.js開發後台之會員相關規劃
下一篇
30-5 Node.js起手式之專案建立與資料庫串接 (2)
系列文
30天使用Node.js在AWS上開發後端6
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言