Dart-Aqueduct框架開發(四)
- 2019 年 10 月 6 日
- 筆記
聲明:本文首發於微信訂閱號:Dart客棧 文章為原創,如需轉載請註明出處,並告知作者,謝謝!
1.介紹
這篇文章將詳細介紹URL、路由,前幾篇有小夥伴私信留言說講得有點快,感覺跟不上,所以,接下來的文章中,將詳細介紹Aqueduct
的相關內容.
2.什麼是URL?
每個http
請求都有一個URl,可以作為客戶端訪問伺服器的一個訪問路徑,例如:http://xxxx.com/image/xxx.jpg
,當客戶端請求該路徑地址時,服務端將返回對應的圖片資源給客戶端,URL是Web
應用程式提供的,客戶端可以通過web
應用程式提供的URL來操作web
應用程式的資源,例如:資料庫中的數據增刪改和查詢,文件的創建和刪除等
3.URL的組成
URL由許多部分組成,其中一部分是可選的,例如https://www.baidu.com/index.html
,當瀏覽器訪問這個URL時,將顯示百度的index.html
頁面,這個頁面包含三個必要組件:scheme(https)
、host(www.baidu.com)
、path(/index.html)
,其中,path
是可選的而且可以是多個,並且Aqueduct
框架只關心path
,也就是Aqueduct
中的訪問路由
4.匹配路由
如上一節的程式碼中:
@override Controller get entryPoint { //定義路由、請求鏈接等,在啟動期間調用 router.route('/queryArticle').linkFunction((request) async{ final query = Query<Article>(context); final List<Article> articles=await query.fetch(); return Response.ok(articles); }); return router; }
當客戶端訪問的path
為/queryArticle
時,將會匹配到路由,並獲取到程式碼中Response.ok
裡面參數的內容,path
可以有多段,路由路徑規範為每個段與請求的每個段相匹配,每個段的數量也必須相同,才能訪問到,下面是一個反面例子:/queryArticle/1
,這個路徑將訪問不了上面的資源
路由路徑上的變數/:id
路徑規範中,可以擁有變數,最經常用於獲取唯一標識的資源,例如:/queryArticle/1
,/queryArticle/2
,通常的,我們以:
冒號開頭的path
作為變數,添加如下程式碼,根據id
訪問文章
```dart @override Controller get entryPoint { //定義路由、請求鏈接等,在啟動期間調用 router.route('/queryArticle/:id').linkFunction((request) async { final id = request.path.variables['id']; //獲取路徑上的id變數 if (int.tryParse(id) != null) {//判斷是否為int類型 final query = Query<Article>(context) ..where((a) => a.id).equalTo(int.parse(id));//查詢id對應的文章 final articles = await query.fetchOne();//查詢第一條 if(articles!=null){ //判斷是否存在 return Response.ok(articles); //查詢成功,返迴文章 }else{ return Response.ok({"msg":"no exist"});//不存在該文章 } }else{ return Response.badRequest(body:{"msg":"error"});//查詢失敗,id不是int類型 } }); return router; }
在啟動伺服器之前,我們插入幾條數據到資料庫中

然後訪問




?很棒!程式都按照我們的預想成功了
可選路徑變數/[:id]
或[/:id]
當前,我們的路徑在訪問文章的時候,我們之前已經有一個訪問路徑了,現在我們又加了一個,等於程式碼冗餘了,這不是我們想看到的,那麼這個時候,可以使用可選路徑,當存在id
的時候,就去訪問對應的id,當不存在id時,我們就查詢所有文章,所以,將之前的程式碼合併到/queryArticle
路徑來,使用中括弧
把:id
括起來,說明這個是可選變數,程式碼如下:
@override Controller get entryPoint { //可選變數[:id] router.route('/queryArticle/[:id]').linkFunction((request) async { final id = request.path.variables['id']; if(id==null){ final query = Query<Article>(context); final List<Article> articles = await query.fetch(); return Response.ok(articles); }else if (int.tryParse(id) != null) { final query = Query<Article>(context) ..where((a) => a.id).equalTo(int.parse(id)); final articles = await query.fetchOne(); if(articles!=null){ return Response.ok(articles); }else{ return Response.ok({"msg":"no exist"}); } }else{ return Response.badRequest(body:{"msg":"error"}); } }); return router; }
這樣就可以實現了,感興趣的小夥伴可以運行一下,這裡就不一一展示了,路徑規範中,可以包含多個可選路徑變數,例如:/a/[b/[:c]]
將匹配/a
、/a/b
、a/b/c
,不匹配/a/c
限制路徑變數(可使用正則表達式)/:id([0-9]+)
一般的,我們可以使用變數後接括弧,把正則表達式括起來/:變數(正則表達式)
,讓我們限制一下上面請求的id只能為整數,不匹配將返回404
,然後程式碼判斷部分就可以直接去掉
@override Controller get entryPoint { //正則限制變數/:變數(正則) router.route('/queryArticle/[:id([0-9]+)]').linkFunction((request) async { final id = request.path.variables['id']; if(id==null){ final query = Query<Article>(context); final List<Article> articles = await query.fetch(); return Response.ok(articles); }else{ final query = Query<Article>(context) ..where((a) => a.id).equalTo(int.parse(id)); final articles = await query.fetchOne(); if(articles!=null){ return Response.ok(articles); }else{ return Response.ok({"msg":"no exist"}); } } }); return router; }
匹配路徑下的所有路徑/*
當我們需要做一系列的匹配時,我們可以在路徑的最後一段加上/*
,例如:/user/*
,當請求/user/12
或者/user/12/34
等,都將匹配,一般用於一個大系的URL路由處理
404的處理
一般我們的web
伺服器都需要對404做訂製處理,下面是自帶的404
頁面

這樣的頁面肯定不能滿足我們的請求要求,所以需要訂製,訂製也很簡單,Aqueduct
框架為我們在構造路由時,特意留下一個參數設置404
頁面,因為我的是API
伺服器,所以返回一個json
@override Controller get entryPoint { //edit final router = Router(notFoundHandler: (request) async { Response response=Response.notFound();//404的狀態碼 response.contentType=ContentType.json;//內容類型 response.body={'code': -1, 'msg': '404'};//內容 await request.respond(response);//把內容相應出去 logger.info("${request.toDebugString()}");//列印日誌 }); //路由對象 //edit return router; }
然後再請求404就會看到對應的內容
以上就是這一節的所有內容,如果小夥伴們覺得有收穫,不妨點一下再看,讓我能看到你跟我一起學習Dart伺服器,也是對我寫作的一種肯定?!