[API] Modifying Responses

https://developer.wordpress.org/rest-api/extending-the-rest-api/modifying-responses/

Một trường bổ sung trong phản hồi nhận xét

<?php
add_action('rest_api_init', 'create_api_posts_meta_field');
function create_api_posts_meta_field() {
  register_rest_field('post', 'post-meta-fields', array(
    'get_callback' => 'get_post_meta_for_api',
    'schema'       => null,
  )
  );
}
function get_post_meta_for_api($object) {
  //get the id of the post object array
  $post_id = $object['id'];
  //return the post meta
  return get_post_meta($post_id);
}
?>

Các điểm cuối mặc định của WordPress REST API được thiết kế để trả về dữ liệu theo mặc định cung cấp cho phần lớn các trang web và trường hợp sử dụng, nhưng thường có những trường hợp bạn sẽ cần truy cập hoặc hiển thị dữ liệu bổ sung trong các phản hồi cho các loại đối tượng khác nhau.

Như với phần còn lại của WordPress, API REST được thiết kế để có thể mở rộng cao để phù hợp với những nhu cầu này. Hướng dẫn này trình bày chi tiết cách thêm dữ liệu bổ sung vào phản hồi của các điểm cuối mặc định bằng cách sử dụng các hàm register_rest_field và register_meta. Bạn có thể sử dụng các hàm này để thêm trường vào bất kỳ loại đối tượng nào được API REST hỗ trợ. Các trường tùy chỉnh này có thể hỗ trợ cả thao tác lấy và cập nhật.

API hiển thị nhiều trường trên phản hồi API, bao gồm những thứ bạn có thể không cần hoặc có thể không phù hợp với cách trang web của bạn hoạt động. Mặc dù có khả năng sửa đổi hoặc xóa các trường khỏi phản hồi API REST, nhưng điều này sẽ gây ra sự cố với ứng dụng khách API mong đợi phản hồi tiêu chuẩn. Điều này bao gồm các ứng dụng khách di động, các công cụ của bên thứ ba để giúp bạn quản lý trang web của mình hoặc chính wp-admin.

Bạn có thể chỉ cần một lượng nhỏ dữ liệu, nhưng điều quan trọng cần lưu ý là API là để hiển thị giao diện cho tất cả các ứng dụng khách, không chỉ tính năng bạn đang làm việc. Thay đổi câu trả lời rất nguy hiểm.

Việc thêm trường không nguy hiểm, vì vậy nếu bạn cần sửa đổi dữ liệu, tốt hơn hết là bạn nên sao chép trường đó bằng dữ liệu đã sửa đổi của mình. Loại bỏ các trường không bao giờ được khuyến khích; nếu bạn cần lấy lại một tập con dữ liệu nhỏ hơn, hãy sử dụng tham số _fields hoặc làm việc với các ngữ cảnh.

Nếu bạn phải xóa các trường khỏi ngữ cảnh hiện có, bạn nên đảm bảo rằng hành vi đó được chọn tham gia, ví dụ: bằng cách cung cấp tham số truy vấn tùy chỉnh để kích hoạt việc xóa trường.

API không thể ngăn bạn thay đổi phản hồi, nhưng mã được cấu trúc để thực sự không khuyến khích làm như vậy. Trong nội bộ, đăng ký trường được cung cấp bởi các bộ lọc và chúng có thể được sử dụng nếu bạn hoàn toàn không có lựa chọn nào khác.

Using register_rest_field vs register_meta #

Có hai phương pháp có thể được sử dụng để thêm dữ liệu vào các phản hồi API REST của WordPress, register_rest_field và register_meta.

register_rest_field có thể được sử dụng để thêm các trường tùy ý vào bất kỳ phản hồi API REST nào và có thể được sử dụng để đọc và ghi dữ liệu bằng API. Để đăng ký trường REST mới, bạn phải cung cấp các hàm gọi lại của riêng mình để lấy hoặc đặt giá trị của trường, cũng như chỉ định theo cách thủ công định nghĩa lược đồ của riêng bạn cho trường.

register_meta được sử dụng để đưa vào danh sách trắng một giá trị meta tùy chỉnh hiện có để truy cập thông qua API REST. Bằng cách đặt thông số show_in_rest của trường meta thành true, giá trị của trường đó sẽ được hiển thị trên khóa .meta trong phản hồi điểm cuối và WordPress sẽ xử lý việc thiết lập lệnh gọi lại để đọc và ghi vào khóa meta đó. Điều này đơn giản hơn nhiều so với register_rest_field, với một lưu ý:

Adding Custom Fields to API Responses

Using register_rest_field

hàm register_rest_field là cách linh hoạt nhất để thêm trường vào các đối tượng phản hồi API REST. Nó chấp nhận ba tham số:

  1. $ object_type: Tên của đối tượng, dưới dạng một chuỗi hoặc một mảng tên của các đối tượng mà trường đang được đăng ký. Đây có thể là một loại cốt lõi như “bài đăng”, “điều khoản”, “meta”, “người dùng” hoặc “nhận xét”, nhưng cũng có thể là tên chuỗi của loại bài đăng tùy chỉnh.

  2. Thuộc tính $: Tên của trường. Tên này sẽ được sử dụng để xác định khóa trong đối tượng phản hồi.

  3. $ args: Một mảng có các khóa xác định các hàm gọi lại được sử dụng để truy xuất giá trị của trường (‘get_callback’), để cập nhật giá trị của trường (‘update_callback’) và xác định lược đồ của nó (‘schema’).

Mỗi khóa của mảng $ args là tùy chọn, nhưng nếu không được sử dụng, khả năng đó sẽ không được thêm vào. Điều này có nghĩa là bạn có thể chỉ định một hàm gọi lại để đọc giá trị và bỏ qua lệnh gọi lại cập nhật để làm cho trường đó ở chế độ chỉ đọc nếu muốn.

Các trường phải được đăng ký tại hành động rest_api_init. Sử dụng hành động này thay vì init sẽ ngăn việc đăng ký trường xảy ra trong các yêu cầu tới WordPress không sử dụng API REST.

Đọc và viết một trường bổ sung trong phản hồi nhận xét

<?php
// Part 1
add_action('rest_api_init', function () {
  register_rest_field('comment', 'karma', array(
    'get_callback'    => function ($comment_arr) {
      $comment_obj = get_comment($comment_arr['id']);
      return (int) $comment_obj->comment_karma;
    },
    'update_callback' => function ($karma, $comment_obj) {
      $ret = wp_update_comment(array(
        'comment_ID'    => $comment_obj->comment_ID,
        'comment_karma' => $karma,
      ));
      if (false === $ret) {
        return new WP_Error(
          'rest_comment_karma_failed',
          __('Failed to update comment karma.'),
          array('status' => 500)
        );
      }
      return true;
    },
    'schema'          => array(
      'description' => __('Comment karma.'),
      'type'        => 'integer',
    ),
  ));
});
?>

Ví dụ này minh họa việc thêm một trường có tên là karma vào phản hồi cho các bài đăng. Nó hoạt động vì trường comment_karma tồn tại, nhưng không được sử dụng bởi lõi. Lưu ý rằng một triển khai thực tế của nghiệp bình luận sẽ cần sử dụng một điểm cuối riêng biệt.

Đây là một ví dụ cơ bản; xem xét cẩn thận những kiểm tra quyền hoặc xử lý lỗi nào có thể được yêu cầu cho trường cụ thể của bạn.

How register_rest_field Works

Biến toàn cục $ wp_rest_additional_fields được sử dụng nội bộ bởi cơ sở hạ tầng API REST để giữ các trường phản hồi sẽ được thêm vào từng loại đối tượng. API REST cung cấp register_rest_field như một hàm tiện ích để thêm vào biến toàn cục này. Nên tránh thêm trực tiếp vào biến toàn cục để đảm bảo khả năng tương thích chuyển tiếp.

Đối với mỗi loại đối tượng - bài đăng hoặc người dùng, điều khoản, nhận xét, v.v. - $ wp_rest_additional_fields chứa một mảng định nghĩa trường chứa các lệnh gọi lại được sử dụng để truy xuất hoặc cập nhật giá trị của trường.

Working with registered meta in the REST API

Hàm register_meta đơn giản hóa quá trình xác định trường meta cho một loại đối tượng cụ thể. Bằng cách đặt 'show_in_rest' => true khi đăng ký một khóa meta mới, khóa đó sẽ có thể truy cập được thông qua REST API.

Read and write a post meta field in post responses

<?php
$object_type = 'post';
$meta_args = array( // Validate and sanitize the meta value.
    // Note: currently (4.7) one of 'string', 'boolean', 'integer',
    // 'number' must be used as 'type'. The default is 'string'.
    'type'         => 'string',
    // Shown in the schema for the meta key.
    'description'  => 'A meta key associated with a string meta value.',
    // Return a single value of the type.
    'single'       => true,
    // Show in the WP REST API response. Default: false.
    'show_in_rest' => true,
);
register_meta( $object_type, 'my_meta_key', $meta_args );
?>

Ví dụ này cho thấy cách cho phép đọc và ghi một trường meta bài đăng. Điều này sẽ cho phép trường đó được cập nhật thông qua yêu cầu POST tới wp-json / wp / v2 / posts / hoặc được tạo cùng với một bài đăng qua yêu cầu POST tới wp-json / wp / v2 / posts /.

Lưu ý rằng đối với các trường meta được đăng ký trên các loại bài đăng tùy chỉnh, loại bài đăng phải có hỗ trợ trường tùy chỉnh. Nếu không, các trường meta sẽ không xuất hiện trong API REST.

Post Type Specific Meta

WordPress 4.9.8 thêm hỗ trợ đăng ký meta cho một loại bài đăng cụ thể hoặc phân loại bằng cách sử dụng các hàm register_post_meta và register_term_meta. Chúng tuân theo các quy tắc tương tự như register_meta nhưng chấp nhận một loại bài đăng hoặc phân loại làm tham số đầu tiên của chúng thay vì một loại đối tượng. Đoạn mã sau sẽ đăng ký ví dụ my_meta_key ở trên, nhưng chỉ cho trang custom post type.

<?php
// The object type. For custom post types, this is 'post';
// for custom comment types, this is 'comment'. For user meta,
// this is 'user'.
$meta_args = array( // Validate and sanitize the meta value.
    // Note: currently (4.7) one of 'string', 'boolean', 'integer',
    // 'number' must be used as 'type'. The default is 'string'.
    'type'         => 'string',
    // Shown in the schema for the meta key.
    'description'  => 'A meta key associated with a string meta value.',
    // Return a single value of the type.
    'single'       => true,
    // Show in the WP REST API response. Default: false.
    'show_in_rest' => true,
);
register_meta('post', 'my_meta_key', $meta_args );
register_post_meta( 'page', 'my_meta_key', $meta_args );
?>

Kết quả lần lượt cho post && page lằn lượt bên dưới hình

Object Meta Type

WordPress 5.3 thêm hỗ trợ sử dụng loại đối tượng khi đăng ký meta. Đối tượng quan trọng đề cập đến một đối tượng JSON, điều này tương đương với một mảng kết hợp trong PHP.

Khi đăng ký meta đối tượng, việc đặt loại thành đối tượng là không đủ, bạn cũng cần thông báo cho WordPress về những thuộc tính nào được phép. Điều này được thực hiện bằng cách viết một Lược đồ JSON khi đăng ký siêu dữ liệu.

Ví dụ: mẫu mã sau đăng ký một trường meta bài đăng được gọi là “phát hành” chấp nhận dữ liệu JSON đã cho.

register_post_meta(
    'post',
    'release',
    array(
        'single'       => true,
        'type'         => 'object',
        'show_in_rest' => array(
            'schema' => array(
                'type'       => 'object',
                'properties' => array(
                    'version' => array(
                        'type' => 'string',
                    ),
                    'artist'  => array(
                        'type' => 'string',
                    ),
                ),
            ),
        ),
    )
);

Lưu ý rằng show_in_rest trở thành một mảng thay vì true và một Lược đồ Json được chỉ định cho khóa lược đồ. Mỗi thuộc tính sau đó được liệt kê trong mảng thuộc tính. Ở mức tối thiểu, mỗi thuộc tính phải chỉ định một loại nhưng bất kỳ từ khóa Lược đồ JSON nào mà rest_validate_value_from_schema hiểu đều có thể được sử dụng. (Chưa hiểu đoạn này)

Additional Properties

Theo mặc định, danh sách các thuộc tính là một danh sách trắng nghiêm ngặt. Nếu một thuộc tính được gửi trong yêu cầu không được liệt kê, REST API sẽ trả về lỗi: your_property không phải là thuộc tính hợp lệ của Object .. Nếu bạn không biết trước tên thuộc tính, bạn có thể sử dụng từ khóa addProperties. addProperties chấp nhận một Lược đồ JSON được sử dụng để xác thực các thuộc tính không xác định. Ví dụ: để thực thi bất kỳ thuộc tính bổ sung nào là số, có thể sử dụng mã sau.

{
  "meta": {
    "release": {
      "version": "5.2",
      "artist": "Jaco",
      "unknown_field": 5.3
    }
  }
}
register_post_meta(
    'post',
    'version',
    array(
        'single'       => true,
        'type'         => 'object',
        'show_in_rest' => array(
            'schema' => array(
                'type'                 => 'object',
                'properties'           => array(
                    'version' => array(
                        'type' => 'string',
                    ),
                    'artist'  => array(
                        'type' => 'string',
                    ),
                ),
                'additionalProperties' => array(
                    'type' => 'number',
                ),
            ),
        ),
    )
);

addProperties có thể được đặt thành true để cho phép các thuộc tính không xác định của bất kỳ định dạng nào, nhưng điều này không được khuyến khích.

Array Meta Type

WordPress 5.3 cũng hỗ trợ thêm cho việc sử dụng kiểu mảng. Quan trọng là mảng đề cập đến một mảng JSON, điều này tương đương với một mảng số trong PHP.

Khi đăng ký meta mảng, việc đặt kiểu thành mảng là không đủ, bạn cần thông báo cho WordPress về định dạng mong đợi của các mục trong mảng. Điều này được thực hiện bằng cách viết mục nhập Lược đồ JSON khi đăng ký siêu dữ liệu.

Nếu bạn không cung cấp giá trị này, register_meta sẽ trả về false và đưa ra cảnh báo sau: Khi đăng ký loại meta "mảng" để hiển thị trong REST API, bạn phải chỉ định lược đồ cho từng mục mảng trong "show_in_rest.schema.items" .

Mẫu mã sau đăng ký một trường meta bài đăng được gọi là “các dự án” chứa danh sách các tên dự án. Nó chấp nhận dữ liệu JSON đã cho.

{
  "meta": {
    "projects": [
      "WordPress",
      "BuddyPress"
    ]
  }
}
register_post_meta(
    'post',
    'projects',
    array(
        'single'       => true,
        'type'         => 'array',
        'show_in_rest' => array(
            'schema' => array(
                'type'  => 'array',
                'items' => array(
                    'type' => 'string',
                ),
            ),
        ),
    )
);

Lưu ý rằng show_in_rest lại trở thành một mảng thay vì true và một Lược đồ JSON được chỉ định cho khóa lược đồ. Từ khóa items được sử dụng để xác định lược đồ JSON nhằm xác thực từng thành viên mảng. Nó có thể là một kiểu vô hướng như chuỗi hoặc một kiểu phức tạp như đối tượng.

Ví dụ: để chấp nhận dữ liệu JSON đã cho, đăng ký meta sau sẽ được sử dụng.

{
  "meta": {
    "projects": [
      {
        "name": "WordPress",
        "website": "https://wordpress.org"
      },
      {
        "name": "BuddyPress",
        "website": "https://buddypress.org"
      }
    ]
  }
}
register_post_meta(
    'post',
    'projects',
    array(
        'single'       => true,
        'type'         => 'array',
        'show_in_rest' => array(
            'schema' => array(
                'items' => array(
                    'type'       => 'object',
                    'properties' => array(
                        'name'    => array(
                            'type' => 'string',
                        ),
                        'website' => array(
                            'type'   => 'string',
                            'format' => 'uri',
                        ),
                    ),
                ),
            ),
        ),
    )
);

Non-Single Metadata

Các trường meta không đơn lẻ có một mảng giá trị cho mỗi đối tượng, thay vì một giá trị cho mỗi đối tượng. Mỗi giá trị đó được lưu trữ trong một hàng riêng biệt trong bảng meta.

Các kiểu mảng và đối tượng cũng có thể được sử dụng với các trường meta không đơn lẻ. Ví dụ: nếu khóa meta “phát hành” trước đó có một lần được đặt thành sai, thì dữ liệu JSON sau có thể được chấp nhận.

{
  "meta": {
    "release": [
      {
        "version": "5.2",
        "artist": "Jaco"
      },
      {
        "version": "5.1",
        "artist": "Betty"
      }
    ]
  }
}

Điều này sẽ dẫn đến hai hàng cơ sở dữ liệu meta. Đầu tiên chứa 
{
  "version": "5.2", 
"artist": "Jaco"
}
 và thứ hai chứa 
{
 "version": "5.1", 
 "artist": "Betty"
}.

Tương tự, dữ liệu sau sẽ được chấp nhận cho ví dụ "các dự án" nếu nó được đặt đơn thành false.

{
  "meta": {
    "projects": [
      [
        "WordPress",
        "BuddyPress"
      ],
      [
        "bbPress"
      ]
    ]
  }
}

Điều này sẽ dẫn đến hai hàng cơ sở dữ liệu meta. Đầu tiên chứa ["WordPress", "BuddyPress"] và thứ hai chứa ["bbPress"].

Invalid Stored Values

Nếu giá trị hiện có cho trường meta không xác thực với kiểu và lược đồ đã đăng ký, giá trị cho trường meta đó sẽ được trả về là null. Nếu giá trị null đó được chuyển trở lại API khi thực hiện yêu cầu cập nhật, bạn sẽ nhận được lỗi rest_invalid_stored_value: Thuộc tính% s có giá trị được lưu trữ không hợp lệ và không thể cập nhật thành null .. Để khắc phục điều này, hãy cập nhật thẻ meta khóa có giá trị hợp lệ hoặc bỏ qua thuộc tính đó khỏi yêu cầu của bạn.

Default Metadata Values

WordPress 5.5 bổ sung hỗ trợ chính thức để chỉ định giá trị mặc định cho siêu dữ liệu nếu không có giá trị nào được xác định. Ví dụ: với đoạn mã này, trường meta giá sẽ được đặt thành 0,00 trong phản hồi API REST nếu chưa có giá trị.

register_post_meta(
     'product',
     'price',
     array(
         'single'  => true,
         'type'    => 'string',
         'default' => '0.00',
     )
 );

WordPress tạo danh sách các liên kết được liên kết với tài nguyên được truy vấn để giúp điều hướng đến các tài nguyên liên quan dễ dàng hơn.

{
 "_links": {
    "self": [
      {
        "href": "https://make.wordpress.org/core/wp-json/wp/v2/posts/28312"
      }
    ],
    "collection": [
      {
        "href": "https://make.wordpress.org/core/wp-json/wp/v2/posts"
      }
    ],
    "author": [
      {
        "embeddable": true,
        "href": "https://make.wordpress.org/core/wp-json/wp/v2/users/8670591"
      }
    ],
    "replies": [
      {
        "embeddable": true,
        "href": "https://make.wordpress.org/core/wp-json/wp/v2/comments?post=28312"
      }
    ],
    "wp:term": [
      {
        "taxonomy": "category",
        "embeddable": true,
        "href": "https://make.wordpress.org/core/wp-json/wp/v2/categories?post=28312"
      },
      {
        "taxonomy": "post_tag",
        "embeddable": true,
        "href": "https://make.wordpress.org/core/wp-json/wp/v2/tags?post=28312"
      }
    ]
  }
}

Một mẫu liên kết từ bài đăng trên Make.WordPress.org

Mặc dù các liên kết này sẽ xuất hiện dưới thuộc tính _links trong đối tượng phản hồi JSON, nhưng nó không được lưu trữ trong WP_REST_Response :: $ data hoặc có thể truy cập qua WP_REST_Response :: get_data (). Thay vào đó, máy chủ sẽ nối dữ liệu liên kết vào phản hồi ngay trước khi gửi lại dữ liệu phản hồi.

Các liên kết tùy chỉnh có thể được thêm vào phản hồi bằng cách sử dụng phương thức WP_REST_Response :: add_link (). Phương thức này chấp nhận ba tham số, quan hệ liên kết, URL và tùy chọn danh sách các thuộc tính liên kết. Ví dụ: để thêm tác giả và liên kết wp: term.

<?php
$response->add_link( 'author', rest_url( "/wp/v2/users/{$post->post_author}" ) );
$response->add_link( 'https://api.w.org/term', add_query_arg( 'post', $post->ID, rest_url( "/wp/v2/{$tax_base}" ) ) );
?>

author.r là một quan hệ liên kết đã đăng ký được mô tả là “tác giả của ngữ cảnh”, chúng tôi sử dụng điều đó để trỏ đến người dùng WordPress đã viết bài đăng. Không tồn tại mối quan hệ liên kết mô tả các điều khoản liên quan đến một bài đăng, vì vậy WordPress sử dụng URL https://api.w.org/term. Điều này được chuyển đổi thành wp: thuật ngữ khi tạo phản hồi bằng cách sử dụng CURIE.

Tham số thứ ba của add_link () là danh sách các thuộc tính tùy chỉnh. Thuộc tính nhúng có thể được sử dụng để bao gồm tài nguyên được liên kết xuất hiện trong phần _embedded của phản hồi khi sử dụng tham số truy vấn _embed. Nếu nhiều liên kết được thêm vào với cùng một mối quan hệ, thì các phản hồi được nhúng sẽ theo cùng thứ tự mà các liên kết đã được thêm vào.

$response->add_link('author', rest_url("/wp/v2/users/{$post->post_author}"), array(
  'embeddable' => true,
));

A sample implementation of linking to multi-author posts.

{
  "_links": {
    "author": [
      {
        "embeddable": true,
        "href": "https://yourwebsite.com/wp-json/wp/v2/users/1"
      },
      {
        "embeddable": true,
        "href": "https://yourwebsite.com/wp-json/wp/v2/users/2"
      }
    ]
  },
  "_embedded": {
    "author": [
      {
        "id": 1,
        "name": "Primary Author"
      },
      {
        "id": 2,
        "name": "Secondary Author"
      }
    ]
  }
}

Registering a CURIE

Phiên bản WordPress 4.5 đã giới thiệu hỗ trợ cho các URI nhỏ gọn hoặc CURIE. Điều này làm cho nó có thể tham chiếu các liên kết bằng một số nhận dạng đơn giản hơn nhiều so với URL đầy đủ có thể dễ dàng khá dài.

CURIE được đăng ký bằng bộ lọc rest_response_link_curies. Ví dụ.

<?php
function my_plugin_prefix_register_curie( $curies ) {
 
    $curies[] = array(
        'name'      => 'my_plugin',
        'href'      => 'https://api.mypluginurl.com/{rel}',
        'templated' => true,
    );
 
    return $curies;
}
?>

Last updated