iT邦幫忙

2022 iThome 鐵人賽

DAY 3
0
自我挑戰組

laravel+vue 學習系列 第 3

Day3. 路由 Route

  • 分享至 

  • xImage
  •  

一、HTTP 動詞

動詞與常用的方式:

  1. GET: 請求一項資源
  2. HEAD: 請求只有標頭的GET回應
  3. POST: 建立資源
  4. PUT: 覆寫資源
  5. PATCH: 修改資源
  6. DELETE: 刪除資源
  7. OPTIONS: 詢問伺服器這個 URL 可用的 HTTP 動詞有哪些

二、REST

一次圍繞著一個特定資源(e.g. 產品、人員), 使用 URL + HTTP 動詞進行組合,來操作指定的資源動作(CRUD...等,資源為 server 上的 Object, Document, Thing...)

statelessness

server 和 client 不需要知道雙方狀態, 每次都為獨立的請求, 當 Server 和 Client 個別代碼有調整時, 不會互相影響

[Client] Header and Accept parameters

  1. 請求中 client 會在 Headers 內, 給 server 指定可接受的回傳類型, 由 Accept 選項指定
  2. Accept 內容為 MIME(Multipurpose Internet Mail Extensions) 由類型與子類型組合, 以「/」區隔
    • e.g. text/html, appliaction/html
    • e.g. 請求資源 product/21, 指定回傳類型為 Accept text/html 或 appliaction/html
        GET product/21
        Accept text/html, appliaction/html
    

[Server] Response

  1. Content Type
    Server 向 Client 回傳內容時, 需標記內容格式在 content-type 選項上, 提示 Client 接收到的數據類型
  2. Response Code
    • Server 回應的狀態代碼, 提示 Client 請求的結果
    • 常見代碼 200(OK), 201(CREATE), 204(NO CONTENT)...
        HTTP/1.1 200 (OK)
        Content-Type: text/html
    

參考: What is REST?

三、Laravel 路由

如何定義路由?

  1. 路由基本設定位置在 routes 目錄下的檔案, 常見設定檔案
    • routes/web.php (網站路由)
    • routes/api.php (API 路由)
  2. Laravel 5.3 以前版本路由檔只有一個 app/Http/routes.php
  3. 基本設定可用 Closure 函數回傳靜態頁面, 或是指定 Controller 執行要做的動作
        # a. 使用 Closure 回傳 html 頁面
        Route::get('/', function(){
            return view('product.list')
        });
    
        # b. 配合 Controller 回傳內容
        Route::get('/', 'productList@index');
    
        # c. laravel 5.7 以後支援 tuple 語法
        Route::get('/', [PorductController::class, 'index']);
    

配合 HTTP 動詞區分要執行的動作.

相同路由上可使用不同 HTTP 動詞區隔要執行的動作

    # 定義一個 GET 方法取得商品資訊
    Route:get('/product', function(){
        // 取得商品資訊
    });
    
    # 定義一個 POST 方法建立一個商品
    Route::post('/product', function(){
        // 新增一筆商品
    });

路由參數

  1. 基本用法

    • 以大括弧包住 {}, 括住內容為指定的變數名稱, 使用時跟一般變數一樣
        # 取得商品單一頁面內容
        Route::get('/product/{id}', function($id){
            $binding = [
                'id'=> $id
            ];
            return view('product.view', $binding);
        });
    
  2. 選用參數

    • 可在大括弧內最後加上問號 {id?}, 表示這個變數為選用, 要給變數一個預設值
        # 取得商品列表
        Route::get('/productList/{page?}', function($page = 1){
            $binding = [
                'page'=> $page
            ];
            return view('product.list', $binding);
        });
    
  3. 正規式匹配路由參數

    • 當變數沒有符合匹配規則, 則跳過直到匹配到符合的路由, 最後若沒有匹配到結果則會顯示 404 頁面
        # 在路由後方呼叫 where 方法, 檢查 page 是否為數字
        Route::get('/productList/{page}', function($page){
            $binding = [
                'page'=> $page
            ];
            return view('product.list', $binding);
        })->where('id', '[0-9]+');
    
        # 匹配單一商品與商品留言
        Route::get('/product/{id}/{comment_id}', function($id, $comment_id){
            $binding = [
                'id'=> $id,
                'comment_id' => $comment_id
            ];
            return view('product.commentView', $binding);
        })->where([
            'id' => '[0-9]+',
            'comment_id' => '[0-9]+',
        ]);
    

路由名稱

  1. 替路由取名子, 方便其他地方可以簡單使用取得路徑, e.g. url(), route() 方法
  2. 設定名子的方法
        # 常見的命名方式 物件 + 動作, e.g. product.view
        Route::get('/product/{id}', function($id){
            $binding = [
                'id'=> $id
            ];
            return view('product.view', $binding);
        })->name('product.view');
    
        # 5.1 以前的版本設定
        Route::get('/product/{id}', [
            'as' => 'product.view',
            'uses' => 'ProductController@show'
        ]);
    
  3. 如何使用?
        # 可在 HTML 模板裡面或 PHP 內呼叫方法 url() 或 route() 取得路徑url
        # url() 需明確指示路徑
        url('/product/'.$id);
    
        # route 可以使用路由名稱與參數配合
        # 第一種用法 /product/1
        route('product.view', [1]);
    
        # 第二種用法, 此用法參數順序可以調整
        route('product.view', ['id' => 1];
    
        # 第三種用法, 多的參數會放在 query 參數內 
        # /product/1?opt=a
        route('product.view', ['id' => 1, 'opt' => 'a']);
    

路由群組

  • 將同一功能的路由分組, 可依前綴詞、命名空間、middleware 分類

    1. 基本使用
     Route::group(function(){
         Route::get('/product/{id}', function($id){
             return view('product.view');
         });
         Route::get('/porductList', function(){
             return view('product.list');
         });
     });
    
    1. middleware
     Route::middleware('auth')->group(function(){
         Route::get('managerProduct', function(){
             return view('managerProduct');
         });
     });
    
     # 5.4 之前的版本
     Route::group(['middleware' => 'auth'], function(){
         Route::get('managerProduct', function(){
             return view('managerProduct');
         });
     });
    
    1. 路徑前綴詞
     # /manager/Porduct
     Route::prefix('manager')->group([function(){
         Route::get('Product', function(){
             return view('manager.product');
         });
     });
    
    1. 後備路由
     # 在路由檔最後定義一個後備路由, 來捕捉所有匹配不到的路徑
     Route::any('{anything}', 'NotFoundController')->where('anything', '*');
    
     # Laravel 5.6 以上可以改為 fallback
     Route::fallback(function(){
         // ...
     });
    
    1. 子網域路由
     # 不同網域代表應用程式的不同區域
     # 像是 slcak 每間公司會有自己的子網域
     Route::domain('{account}.myapp.com')->group(function(){
         Route::get('/', function($account){
            // ... 
         });
     });
    
    1. 命名空間前綴詞
      當 Controller 在某個命名空間下(e.g. Manager/Product@list), 可以簡化指定 Controller 路徑
     Route::namespace('Manager')->group(function(){
         Route::get('manager/Product', 'Product@list');
     });
    
    1. 名詞前綴詞
      搭配路由的名稱設定名稱前綴詞進行分類
     # 可以使用 route('manager.comments.show', [1]) 來得到 url
     Route::name('manager.')->prefix('manager')->group(function(){
         Route::name('comments.')->prefix('comments')->group(function(){
             Route::get('{id}', function($id){
                 // ...
             })->name('show');
         });
     });
    

上一篇
Day2. 目錄結構
下一篇
Day4. Controller
系列文
laravel+vue 學習32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言