當(dāng)前位置:首頁>WordPress建站>WordPress開發(fā)>WordPress 5.6新增REST API批處理框架

WordPress 5.6新增REST API批處理框架

WordPress 5.6引入了一個框架,該框架可在對服務(wù)器的一個請求中進(jìn)行一系列REST API調(diào)用。簡單地說,當(dāng)需要進(jìn)行大量的寫操作時,這對性能優(yōu)化很有幫助。它還可以選擇提供基本的并發(fā)控制。

注冊

為了在批處理請求中使用,路由必須在注冊過程中首先聲明對功能的支持。例如下方代碼的第5行

register_rest_route( 'my-ns/v1', 'my-route', array(
    'methods'             => WP_REST_Server::CREATABLE,
    'callback'            => 'my_callback',
    'permission_callback' => 'my_permission_callback',
    'allow_batch'         => array( 'v1' => true ),
) );

如果REST API路由是使用最佳實(shí)踐實(shí)現(xiàn)的,則聲明支持應(yīng)足以使該路由可通過批處理端點(diǎn)寫入。具體來說,這些是要注意的事情:

  1. 路由必須使用該WP_REST_Request對象來獲取所有請求數(shù)據(jù)。換句話說,它不應(yīng)該訪問$_GET$_POST$_SERVER變量得到參數(shù)或頭。
  2. 路線必須返回數(shù)據(jù)。這可以是一個WP_REST_Response對象,一個WP_Error對象或任何類型的JSON可序列化數(shù)據(jù)。這意味著路由一定不能直接回顯響應(yīng)和die()。例如,使用wp_send_json()wp_die()
  3. 路線必須是可重入的。準(zhǔn)備好同一批路由被多次調(diào)用。

發(fā)出請求

要發(fā)送批處理,發(fā)送一個POST請求到?https://yoursite.test/wp-json/batch/v1使用所需的請求數(shù)組。例如,最簡單的批處理請求如下所示。

{
  "requests": [
    {
      "path": "/my-ns/v1/route"
    }
  ]
}

請求格式

每個請求都是一個可以接受以下屬性的對象。

{
  "method": "PUT",
  "path": "/my-ns/v1/route/1?query=param",
  "headers": {
    "My-Header": "my-value",
    "Multi": [ "v1", "v2" ]
  },
  "body": {
    "project": "Gutenberg"
  }
}
  • method是用于請求的HTTP方法。如果省略,則使用POST方法。
  • path是要調(diào)用的REST API路由。可以包含查詢參數(shù)。此屬性是必需的。
  • headers是標(biāo)頭名稱到標(biāo)頭值的對象。如果標(biāo)頭具有多個值,則可以將其作為數(shù)組傳遞。
  • body是傳遞給路線的參數(shù)。填寫POST參數(shù)類型。

發(fā)現(xiàn)最大請求

默認(rèn)情況下,REST API在一個批次中最多接受25個請求。但是,此值是可過濾的,因此可以根據(jù)服務(wù)器資源按比例放大或縮小。

function my_prefix_rest_get_max_batch_size() {
    return 50;
}
 
add_filter( 'rest_get_max_batch_size', 'my_prefix_rest_get_max_batch_size' );

因此,強(qiáng)烈建議客戶提出請求前要求以發(fā)現(xiàn)限制。例如,發(fā)出OPTIONS請求到batch/v1將返回以下響應(yīng)。

{
  "namespace": "",
  "methods": [ "POST" ],
  "endpoints": [
    {
      "methods": [ "POST" ],
      "args": {
        "validation": {
          "type": "string",
          "enum": [ "require-all-validate", "normal" ],
          "default": "normal",
          "required": false
        },
        "requests": {
          "type": "array",
          "maxItems": 25,
          "items": {
            "type": "object",
            "properties": {
              "method": {
                "type": "string",
                "enum": [ "POST", "PUT", "PATCH", "DELETE" ],
                "default": "POST"
              },
              "path": {
                "type": "string",
                "required": true
              },
              "body": {
                "type": "object",
                "properties": [],
                "additionalProperties": true
              },
              "headers": {
                "type": "object",
                "properties": [],
                "additionalProperties": {
                  "type": [ "string", "array" ],
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "required": true
        }
      }
    }
  ],
  "_links": {
    "self": [
      {
        "href": "http://trunk.test/wp-json/batch/v1"
      }
    ]
  }
}

該限制在endpoints[0].args.requests.maxItems屬性中指定。

回應(yīng)格式

批處理端點(diǎn)將以與請求相同的順序返回207狀態(tài)碼和每個請求的響應(yīng)。例如:

{
  "responses": [
    {
      "body": {
        "id": 1,
        "_links": {
          "self": [
            {
              "href": "http://trunk.test/wp-json/my-ns/v1/route/1"
            }
          ]
        }
      },
      "status": 201,
      "headers": {
        "Location": "http://trunk.test/wp-json/my-n1/v1/route/1",
        "Allow": "GET, POST"
      }
    }
  ]
}

在內(nèi)部,REST API信封包括它中之前每個響應(yīng)responses陣列。

驗證方式

默認(rèn)情況下,每個請求都是獨(dú)立處理的。這意味著批處理響應(yīng)可以包含一些成功的請求和一些失敗的請求。有時希望僅在所有請求均有效的情況下處理批處理。例如,在古騰堡(Gutenberg),我們不想保存某些菜單項,理想情況下將保存所有菜單項,或者不保存任何菜單項。

為此,REST API允許傳遞的validation模式require-all-validate。設(shè)置此選項后,REST API將根據(jù)WP_REST_Request::has_valid_params()WP_REST_Request::sanitize_params()首先檢查每個請求是否有效。如果有任何請求未通過驗證,則整個批次都將被拒絕。

在此示例中,發(fā)出了兩個請求的批處理,第二個請求驗證失敗。由于responses的順序仍與requests的順序相同,因此用null表示請求未通過驗證。

{
  "failed": "validation",
  "responses": [
    null,
    {
      "body": {
        "code": "error_code",
        "message": "Invalid request data",
        "data": { "status": 400 }
      },
      "status": 400,
      "headers": {}
    }
  ]
}

注意:使用require-all-validate不能保證所有請求都會成功。路由回調(diào)仍可能返回錯誤。

驗證回調(diào)

在注冊路由時,這些WP_REST_Request方法使用validate_callbacksanitize_callback為每個參數(shù)指定。在大多數(shù)情況下,這將意味著基于架構(gòu)的驗證。

路線內(nèi)部完成的任何驗證(例如在prepare_item_for_database方法中)都不會導(dǎo)致批次被拒絕。如果這是一個令人擔(dān)憂的問題,建議將盡可能多的驗證移到validate_callback每個單獨(dú)的參數(shù)中。例如,這可以建立在基于現(xiàn)有架構(gòu)的驗證之上。

'post' => array(
    'type'        => 'integer',
    'minimum'     => 1,
    'required'    => true,
    'arg_options' => array(
        'validate_callback' => function ( $value, $request, $param ) {
            $valid = rest_validate_request_arg( $value, $request, $param );
 
            if ( is_wp_error( $valid ) ) {
                return $valid;
            }
 
            if ( ! get_post( $value ) || ! current_user_can( 'read_post', $value ) ) {
                return new WP_Error( 'invalid_post', __( 'That post does not exist.' ) );
            }
 
            return true;
        }
    )
)

有時在執(zhí)行驗證時,需要請求的完整上下文。通常,此驗證將在prepare_item_for_database中完成,但WordPress 5.6引入了替代方法。注冊路線時,現(xiàn)在可以指定validate_callback頂層。它將接收完整的WP_REST_Request對象,并可以返回WP_Error實(shí)例或false。如果參數(shù)級驗證未成功,則不會執(zhí)行該回調(diào)。

register_rest_route( 'my-ns/v1', 'route', array(
    'callback'            => '__return_empty_array',
    'permission_callback' => '__return_true',
    'validate_callback'   => function( $request ) {
        if ( $request['pass1'] !== $request['pass2'] ) {
            return new WP_Error(
                'passwords_must_match',
                __( 'Passwords must match.' ),
                array( 'status' => 400 )
            );
        }
 
        return true;
    }
) );

注意:請求驗證權(quán)限檢查之前進(jìn)行。在考慮是否將邏輯移至validate_callback時要牢記這一點(diǎn)。

局限性

當(dāng)前沒有內(nèi)置路由允許批處理。這將在將來的版本中添加,最有可能立即從WordPress 5.7開始。

不支持GET?請求。相反,鼓勵開發(fā)人員暫時使用鏈接和嵌入或利用并行請求。

進(jìn)一步閱讀

參見#50244[49252][48947][48945]

聲明:本站所有文章,如無特殊說明或標(biāo)注,均為本站原創(chuàng)發(fā)布。任何個人或組織,在未征得本站同意時,禁止復(fù)制、盜用、采集、發(fā)布本站內(nèi)容到任何網(wǎng)站、書籍等各類媒體平臺。如若本站內(nèi)容侵犯了原著者的合法權(quán)益,可聯(lián)系我們進(jìn)行處理。

給TA打賞
共{{data.count}}人
人已打賞
歡迎關(guān)注WordPress大學(xué)公眾號 WPDAXUE
WordPress資訊

Gutenberg 9.4.0 可設(shè)置按鈕和社交圖標(biāo)大小、列表文字大小等

2020-11-20 8:32:05

WordPress開發(fā)WordPress資訊

WordPress 5.6 新增動作鉤子 wp_after_insert_post

2020-11-22 10:41:10

0 條回復(fù) A文章作者 M管理員
    暫無討論,說說你的看法吧
?
個人中心
購物車
優(yōu)惠劵
今日簽到
有新私信 私信列表
搜索

泗水县| 洮南市| 东乌| 五原县| 天镇县| 焦作市| 馆陶县| 平武县| 旅游| 乐陵市| 都兰县| 旌德县| 八宿县| 阳曲县| 呼玛县| 东台市| 乌海市| 繁峙县| 静安区| 扶余县| 界首市| 汝州市| 屯昌县| 泊头市| 烟台市| 中山市| 贺州市| 陇川县| 微博| 宁蒗| 额尔古纳市| 顺义区| 新宾| 喜德县| 得荣县| 赫章县| 临泽县| 江达县| 东莞市| 临沧市| 万山特区|