iT邦幫忙

2022 iThome 鐵人賽

DAY 21
0
自我挑戰組

laravel+vue 學習系列 第 21

Day21. RESTful API

  • 分享至 

  • xImage
  •  

一、RESTful 特徵

  1. 以一個 URI 表示一個獨立不重複的資源
    • e.g. /product 商品列表
    • e.g. /product/10 編號為 10 的商品
  2. 使用 HTTP 動詞與資源互動, 常用的動詞與作用
    • GET: 取得資料
    • POST: 新增資料
    • PUT: 修改資料, 會整個覆蓋原本內容, 當有空值時會給 null
    • PATCH: 修改資料, 會依照使用者傳過來的欄位做修改
    • DELETE: 刪除資料
  3. 無狀態, 在各請求間不能延續使用 session 做身分驗證, 也無法保持上一個狀態內容
  4. 可使用快取來儲存請求內容( 需要有身分驗證的沒有快取 )
  5. 回傳格視為 JSON

二、 Laravel 建立 API

  • 使用 artisan 建立
    • 內部方法與一般 Resource 建立的差別在於少了 create(), edit() 兩個方法
    php artisan make:controller ProductApiController --api
  • 註冊到路由 routes/api.php
    Route::namespace('Api')->group(function(){
        Route::apiResource('product', '\App\Http\Controllers\ProductApiController');
    });

https://ithelp.ithome.com.tw/upload/images/20220926/20128127B7mFL1hwW9.png

三、讀取與傳送標頭

  1. 使用 Laravel Request 讀取 header
    // 參數傳入要讀取的 header 名稱
    $request->header('Accept');
  1. 使用 Laravel Response 回傳 header
    response(Product:all())->header('X-ProductCategory-Id', 3);

四、JSON API 規範

規範 提供建立 API 架構時須遵守的內容
可以參考此規範建立 API

  1. 回傳 json 內容

    • 須包含一種以下的頂級成員(top level)
      • data 資料內容
      • errors 發生錯誤時產生的物件、訊息陣列
      • meta 詮譯回傳內容的物件或陣列
      • data 與 errors 不能同時存在於回傳內容
  2. 排序

    • GET 參數名為 sort
    • e.g. ?sort=id
        // 取得 sort 判斷排序方式
        Route::get('product', function(){
            // 接收 request 值或是使用預設值
            $sortCloumn = $request->input('sord', 'id');
            // 判斷是否為倒排序
            $sortDirection = starts_with($sortCloumn, '-') ? 'desc' : 'asc';
            $sortCloumn = lrtim($sortCloumn, '-');
            return Product::orderBy($sortCloumn, $sortDirection)->pageinate(20);
        });
    
  3. 過濾
    * GET 參數名為 filter
    * e.g. ?filter=name:test
    ```php
    Route::get('product', function(){
    $query = Product::query();

            // 判斷當有輸入過濾條件, 進行過濾
            $query->when($request->filled('filter'), function($query){
                [$column, $value] = explode(':', request('filter'));
                return $query->where($column, $value);
            });
    
            return $query->paginate(20);
        });
    ```
    

五、設定 API 資源

  1. 為 API 的轉換器, 提供 API 回傳時所需要的格式

    • 避免回傳資料庫欄位, 造成受到資安攻擊條件
    • 可以調用 Eloquent 的關聯, 取回相關資料, e.g. 商品分類 $this->category->name, 去另一張類別資料表撈分類內容
  2. 建立資源類別

    • 回傳單一筆資料
    • 使用 artisan 建立 Resource
        # Class 會在 app/Http/Resources/ProductResource.php 
        php artisan make:resource ProductResource
    
    • 編輯 Class 內的 toArray() 方法設定回傳格式
        // Class 繼承 Illuminate\Http\Resource\Json\JsonResponse
        public function toArray($request) {
            // $this 指向資料本身( Eloquent 物件 )
            return [
                'p_id' => $this->id,
                'p_name' => $this->name,
                'p_price' => $this->price,
                'p_category' => $this->category->name,
                // 使用嵌套取回規格的集合, 並經過 Resource 處理
                'p_spec' => ProductSpecResource::collection($this->spec)
            ];
        }
    
        // 在 Controller 內使用
        return new ProductResource(Product::findOrFail($id));
    
  3. 建立資源集合

    • API 要傳回多個結果, e.g. 列表頁面
    • 使用 artisan 建立 Resource Collection
        # Class 會在 app/Http/Resources/ProductCollection.php 
        php artisan make:resource ProductCollection
    
    • 編輯 Class 內的 toArray() 方法設定回傳格式
        // Class 繼承 Illuminate\Http\Resource\Json\ResourceCollection
        public function toArray($request) {
            retrun [
                'data' => ProductResource::collection($this->collection)
            ];
        }
    
    • Controller 中使用 Collection
        $products = Product::paginate(20);
        return new ResourceCollection($products);
    

六、分頁

  1. 一般在查詢時用 paginate() 方法可以建立分頁
    // 要求以 20 筆為範圍取回一個 collection
    // 主要目的限制資源, 減少資料庫負擔
    $product_paginate = Product::paginate(20);
  1. 在 Resource Collection 中使用 paginate()
    return new ResourceCollection(Product::paginate(20));
  1. 產生分頁後物件回提供頁碼、當前頁面、頁面連結等相關內容, 在模板中可以呼叫使用

上一篇
Day20. 網站後台建立之五(建立使用者登入流程)
下一篇
Day22. 前台 API 與頁面之一 (建立 API 資源)
系列文
laravel+vue 學習32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言