# 工作的程序員如何成為平均: Express 路由
通過?[Ted Neward](https://msdn.microsoft.com/zh-cn/magazine/mt149362?author=Ted+Neward)?| 2015 年 11 月

歡迎回來,"Nodeists。"(如果出現這種的官方術語,對于那些在定期進行,但對我來說比"Nodeheads"或"Noderati"或"Nodeferatu。"更好的 Nodeists 聲音上使用 Node.js,我有不知道)
在上一期 ([msdn.com/magazine/mt573719](http://msdn.com/magazine/mt573719)),該應用程序的堆棧已經從正在向通過安裝 Express 一起 Node.js"EN"堆棧"N"堆棧 (只是節點)。看起來會跳轉到其他事情上直接,有幾個問題有關快速 — 及其支持的包和庫 —,值得探索和進一步討論。您以前獲得了一種,初步了解到表示路由,如果代碼設置了一個函數以顯示"Hello World"與"/"相對 URL 路徑的 HTTP 請求的響應。現在,我將深入進入 Express 世界并向您展示如何以更有效地使用。
順便說一下,那些有興趣查看在編寫本系列的一部分的最新代碼可以訪問包含最新創建的這一系列代碼 (msdn mean.azurewebsites.net) 的 Microsoft Azure 站點。很可能在本專欄中的信息是同步的與什么是在站點上,提供發布計劃和站點向讀者了解一下。
## 路線、 回顧
App.js 文件中從上一期的概要顯示了已構建到目前為止,如中所示的應用程序的單個終結點性質?圖 1, ,簡單但有必要獻給神靈計算機科學。
圖 1 代碼為快速"Hello World"
~~~
// Load modules
var express = require('express');
var debug = require('debug')('app');
// Create express instance
var app = express();
// Set up a simple route
app.get('/', function (req, res) {
? debug("/ requested");
? res.send('Hello World!');
});
// Start the server
var port = process.env.PORT || 3000;
debug("We picked up",port,"for the port");
var server = app.listen(port, function () {
? var host = server.address().address;
? var port = server.address().port;
? console.log('Example app listening at http://%s:%s', host, port);
});
~~~
問題的部分是代碼標記為"設置簡單的路由 ;"的部分在這里,您要建立一個單一終結點,由 HTTP 謂詞 ("get") 和相對 URL 終結點映射 ("/,"作為"get"方法的第一個參數傳遞)。
它是很容易地推斷出其他 HTTP 謂詞的模式 — 對于"POST"的請求,您將使用 post 方法中 ;對于"PUT,"put;和"刪除,"您可以使用 delete。Express 也支持其他謂詞,但出于相當明顯的原因,這些是您最關心的四個。每個然后還將作為其第二個參數函數,該示例中?圖 1?是文字用于處理傳入的 HTTP 請求的函數。
## 平均值中的"E"
通常,當 Nodeists 編寫基于速成版的應用程序,用戶這樣做相同的方式,我們"。NETers"編寫 ASP.NET 應用程序。服務器會生成一個 HTML 文檔其中包含與數據,并發送回瀏覽器中,在其后用戶填寫窗體和文章輸入的數據回 Express; 混合的演示文稿 (HTML)或者,用戶單擊的鏈接,并生成在速成版進行完整的服務器端周期再次返回 GET。而且,由于在 Node.js 中的手寫 HTML 是因為它是 Visual Basic 或 C# 中只是更有趣,許多工具都源自 Node.js 世界上設計用于滿足的 Razor 語法未在傳統的 ASP.NET 應用程序中的相同的目的。還可以容易地編寫而混合存放數據的表示層和太多代碼。
但是,平均值基于應用程序,AngularJS 將形成完整的客戶端體驗,因此 Express 散射與 ASP.NET MVC 相同的角色 — 它是只需一個傳輸層,從客戶端執行 (通常采用的 JSON 形式) 的原始數據、 對該數據 (通常將其存儲、 修改它,或查找關聯或相關數據) 進行操作和將原始數據 (再次發送通常以 JSON 形式) 返回到客戶端層。為此,我們旅居 Express 中的會避免的主題的模板化框架 (的這幾個在 Node.js 世界、"handlebars"和"jade"正在更受歡迎的兩個),和我將重點介紹顯式只需來回傳送 JSON。一些將調用此 rest 風格的終結點,但,坦白地講,其余部分涉及到的作用遠遠不只是 HTTP 和 JSON,并構建 Fielding 批準的 RESTful 系統是遠遠超出本系列叢書的作用域。
因此,現在,我將討論有關持續想到使用一組任意 JSON 使用客戶端要使用的簡單只讀的終結點。
## 在 JSON 中的 hello,
通常情況下,Web API 遵循一個用于獲取數據相當松散的結構:
* 對給定的資源類型 (例如"persons") 的 GET 請求將產生一個對象,其中包含最小值的唯一標識符 (單獨檢索) 和通常某種類型的簡短的說明性文本,適合在選項列表中顯示每個數組的 JSON 結果。
* 對給定資源的 GET 請求鍵入 URL ("persons/1234,"其中 1234年標識符唯一標識我們感興趣的人) 的一部分將產生 (通常) 是一個描述一定程度的詳細信息中的資源的單個 JSON 對象的 JSON 結果標識符。
Web Api 還將使用 PUT、 POST 和刪除,但現在,我將重點介紹的辦法檢索數據。
因此,假設"persons"資源類型,您將創建兩個終結點,其中一個標記為"/ persons,"和其他"/persons/ 。" 對于初學者而言,您需要一個較小的人員能夠使用"數據庫"— 名字、 姓氏和"status"及其當前 (任何往來奔波現在做) 就足夠了 (請參閱?圖 2)。
圖 2 創建人員的小型數據庫
~~~
var personData = [
? {
??? "id": 1,
??? "firstName": "Ted",
??? "lastName": "Neward",
??? "status": "MEANing"
? },
? {
??? "id": 2,
??? "firstName": "Brian",
??? "lastName": "Randell",
??? "status": "TFSing"
? }
];
~~~
SQL Server,但它將執行不完全現在。
接下來,需要的人員的完整集合終結點:
~~~
var getAllPersons = function(req, res) {
? var response = personData;
? res.send(JSON.stringify(response));
};
app.get('/persons', getAllPersons);
~~~
請注意通過這種情況下,路由映射使用獨立函數 (getAllPersons),這是更常見,因為它有助于保持分離關注點更干凈 — 函數將充當 (在模型-視圖-控制器的意義上) 的控制器。現在,我使用 JSON.stringify 將 JavaScript 對象的數組序列化為 JSON 表示形式,但我將更高版本使用更好的內容。
接下來,您需要一個終結點對于人的對象,但這將花費更多執行操作因為您需要挑選作為參數,人員標識符和 Express 具有執行此操作的特定方式。一種方法 (無疑是更簡便的方法在圖面上的事情) 是用于請求對象 ("必需"給路由映射中使用的函數的參數) 的"params"對象提取的路由中指定的參數但 Node.js 也可以使用參數函數做更多 — 它是一種篩選器,找到特定的命名模式的參數時將調用:
~~~
app.get('/persons/:personId', getPerson);
app.param('personId', function (req, res, next, personId) {
? debug("personId found:",personId);
? var person = _.find(personData, function(it) {
??? return personId == it.id;
? });
? debug("person:", person);
? req.person = person;
? next();
});
~~~
何時調用路由、 任何如下所示"/ persons"(如"/ 人員/1") 就像您可能會發現與 ASP.NET MVC 將綁定到名稱"personId"的參數。但然后使用 param 函數時-任何與路由時將調用其": personId"調用 — 調用相關的函數時,它將查找 (以前的代碼段中所示使用"lodash"包函數查找,) 從微小 personData 數據庫。然后,但是,它添加到"必需"對象 (JavaScript 對象已總是動態類型化,因為它是輕松地執行操作),以便它在某些情況下將可供使用的其余部分調用的這種情況下將成為 getPerson 函數 — 現在變得非常簡單,因為已經提取您想要返回的對象:
~~~
var getPerson = function(req, res) {
? if (req.person) {
??? res.send(200, JSON.stringify(req.person));
? }
? else {
??? res.send(400, { message: "Unrecognized identifier: " + identifier });
? }
};
~~~
請參閱我的"普通"的意思嗎?
## 總結
我稍微添加一點如何處理速成版,但雖的勢頭此處,我還有其他空間對于此示例,因此...祝您編碼愉快 !
* * *
Ted Neward?*是 itrellis 一家咨詢服務公司首席技術官。他已編寫的 100 多篇文章和編寫或與他人合著過十幾本書,包括"Professional F # 2.0 》 (Wrox,2010 年)。他是 F # MVP,經常在世界各地的會議上。他定期擔任顧問和導師,如果您感興趣,請通過?[ted@tedneward.com](mailto:ted@tedneward.com)?或?[ted@itrellis.com](mailto:ted@itrellis.com)?與他聯系。*
- 介紹
- Essential .NET - C# 異常處理
- 崛起 - 具備批判精神
- Windows 10 - 通過搜索索引器加快文件操作速度
- 最前沿的技術 - 利用用戶體驗驅動設計改善體系結構
- 異步編程 - 從頭開始執行異步操作
- 數據點 - Aurelia 與 DocumentDB 結合: 結合之旅
- ASP.NET - 將 ASP.NET 用作高性能文件下載器
- 測試運行 - 使用 C# 執行 t-檢驗
- Microsoft Azure - 通過 SonarQube 和 TFS 管理技術債務
- 孜孜不倦的程序員 - 如何成為 MEAN: Express 路由
- 別讓我打開話匣子 - Alan Turing 和 Ashley Madison
- 編輯寄語 - 歡迎使用 Essential .NET