WordPress REST API入门:从零开始构建你的第一个API接口

· 阅读约需33分钟

引言

WordPress REST API 是 WordPress 4.7 版本引入的重要功能,它为 WordPress 提供了强大的 RESTful 接口支持。通过 REST API,你可以使用 HTTP 请求来获取、创建、更新和删除 WordPress 内容,这为构建现代 Web 应用、移动应用和单页应用(SPA)提供了无限可能。本文将带你从零开始,学习如何使用 WordPress REST API。

一、REST API 基础

什么是 REST API?

REST(Representational State Transfer)是一种软件架构风格,它定义了一组约束和原则,用于设计网络应用程序接口。WordPress REST API 允许你通过发送 HTTP 请求来与 WordPress 站点交互,返回 JSON 格式的数据。

REST API 的优势

  • 前后端分离:可以使用现代前端框架(React、Vue、Angular)构建用户界面
  • 移动应用开发:为 iOS、Android 应用提供数据接口
  • 跨平台集成:与其他系统和服务集成
  • 灵活的数据获取:只获取需要的数据,减少带宽消耗

二、REST API 核心概念

端点(Endpoints)

端点是 REST API 中可以访问的特定 URL,每个端点对应特定的功能:

# 获取文章列表
GET /wp-json/wp/v2/posts

# 获取单篇文章
GET /wp-json/wp/v2/posts/{id}

# 创建文章
POST /wp-json/wp/v2/posts

# 更新文章
PUT /wp-json/wp/v2/posts/{id}

# 删除文章
DELETE /wp-json/wp/v2/posts/{id}

路由(Routes)

路由是端点的路径,WordPress REST API 使用以下格式:

/wp-json/{namespace}/{route}
  • wp-json:REST API 的基础路径
  • wp/v2:WordPress 核心的命名空间和版本
  • posts:具体的资源路由

请求方法

REST API 使用标准的 HTTP 请求方法:

  • GET:获取资源
  • POST:创建资源
  • PUT/PATCH:更新资源
  • DELETE:删除资源

三、使用 REST API 获取数据

1. 获取文章列表

使用 JavaScript 获取文章列表:

// 获取最新的10篇文章
fetch('https://your-site.com/wp-json/wp/v2/posts')
  .then(response => response.json())
  .then(posts => {
    console.log('文章列表:', posts);
    posts.forEach(post => {
      console.log(`标题: ${post.title.rendered}`);
      console.log(`作者: ${post.author}`);
      console.log(`发布时间: ${post.date}`);
    });
  });

2. 获取指定文章

// 获取ID为1的文章
fetch('https://your-site.com/wp-json/wp/v2/posts/1')
  .then(response => response.json())
  .then(post => {
    console.log('文章标题:', post.title.rendered);
    console.log('文章内容:', post.content.rendered);
    console.log('文章摘要:', post.excerpt.rendered);
  });

3. 查询参数

使用查询参数过滤和排序数据:

// 获取分类ID为3的文章,按标题排序,每页5篇
fetch('https://your-site.com/wp-json/wp/v2/posts?categories=3&orderby=title&per_page=5')
  .then(response => response.json())
  .then(posts => {
    console.log('分类文章:', posts);
  });

// 搜索包含"WordPress"的文章
fetch('https://your-site.com/wp-json/wp/v2/posts?search=WordPress')
  .then(response => response.json())
  .then(posts => {
    console.log('搜索结果:', posts);
  });

四、常用资源端点

文章(Posts)

// 获取文章
GET /wp-json/wp/v2/posts

// 参数说明
// - page: 页码
// - per_page: 每页数量(默认10,最大100)
// - search: 搜索关键词
// - categories: 分类ID,逗号分隔
// - tags: 标签ID,逗号分隔
// - author: 作者ID
// - orderby: 排序字段(date, title, author, etc.)
// - order: 排序方式(asc, desc)
// - status: 文章状态(publish, draft, pending, etc.)

页面(Pages)

// 获取页面列表
GET /wp-json/wp/v2/pages

// 获取单个页面
GET /wp-json/wp/v2/pages/{id}

分类(Categories)

// 获取分类列表
GET /wp-json/wp/v2/categories

// 获取单个分类
GET /wp-json/wp/v2/categories/{id}

// 创建分类(需要认证)
POST /wp-json/wp/v2/categories

标签(Tags)

// 获取标签列表
GET /wp-json/wp/v2/tags

// 获取单个标签
GET /wp-json/wp/v2/tags/{id}

用户(Users)

// 获取用户列表
GET /wp-json/wp/v2/users

// 获取单个用户
GET /wp-json/wp/v2/users/{id}

// 获取当前用户(需要认证)
GET /wp-json/wp/v2/users/me

媒体(Media)

// 获取媒体列表
GET /wp-json/wp/v2/media

// 获取单个媒体项
GET /wp-json/wp/v2/media/{id}

// 上传媒体(需要认证)
POST /wp-json/wp/v2/media

五、认证与权限

1. Cookie 认证

对于 WordPress 站点内的请求,可以使用 Cookie 认证:

// 在 WordPress 主题或插件中使用
fetch('/wp-json/wp/v2/posts', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-WP-Nonce': wpApiSettings.nonce // WordPress 提供的 nonce
  },
  body: JSON.stringify({
    title: '新文章标题',
    content: '文章内容',
    status: 'publish'
  })
})
.then(response => response.json())
.then(post => {
  console.log('文章已创建:', post);
});

2. 应用密码认证

对于外部应用,可以使用应用密码:

// 使用应用密码进行基本认证
const username = 'your-username';
const applicationPassword = 'xxxx xxxx xxxx xxxx xxxx xxxx';

// 编码凭据
const credentials = btoa(`${username}:${applicationPassword}`);

fetch('https://your-site.com/wp-json/wp/v2/posts', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Basic ${credentials}`
  },
  body: JSON.stringify({
    title: '通过API创建的文章',
    content: '这是通过REST API创建的文章内容',
    status: 'publish'
  })
})
.then(response => response.json())
.then(post => {
  console.log('文章已创建:', post);
});

3. JWT 认证

对于更复杂的应用,可以使用 JWT(JSON Web Token)认证:

// 首先获取令牌
fetch('https://your-site.com/wp-json/jwt-auth/v1/token', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    username: 'your-username',
    password: 'your-password'
  })
})
.then(response => response.json())
.then(data => {
  const token = data.token;

  // 使用令牌进行请求
  return fetch('https://your-site.com/wp-json/wp/v2/posts', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    },
    body: JSON.stringify({
      title: 'JWT认证创建的文章',
      content: '使用JWT令牌认证',
      status: 'publish'
    })
  });
})
.then(response => response.json())
.then(post => {
  console.log('文章已创建:', post);
});

六、实战案例:创建文章

使用 JavaScript 创建文章

// 创建新文章
async function createPost(title, content, categoryId) {
  try {
    const response = await fetch('https://your-site.com/wp-json/wp/v2/posts', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-WP-Nonce': wpApiSettings.nonce
      },
      body: JSON.stringify({
        title: title,
        content: content,
        status: 'publish', // publish, draft, pending
        categories: [categoryId],
        tags: [1, 2, 3],
        excerpt: '这是文章摘要'
      })
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const post = await response.json();
    console.log('文章创建成功:', post);
    return post;
  } catch (error) {
    console.error('创建文章失败:', error);
    throw error;
  }
}

// 使用示例
createPost(
  '我的第一篇API文章',
  '这是通过REST API创建的文章内容,包含丰富的格式和样式。',
  3 // 分类ID
);

更新文章

// 更新现有文章
async function updatePost(postId, updates) {
  try {
    const response = await fetch(`https://your-site.com/wp-json/wp/v2/posts/${postId}`, {
      method: 'PUT',
      headers: {
        'Content-Type': 'application/json',
        'X-WP-Nonce': wpApiSettings.nonce
      },
      body: JSON.stringify(updates)
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const post = await response.json();
    console.log('文章更新成功:', post);
    return post;
  } catch (error) {
    console.error('更新文章失败:', error);
    throw error;
  }
}

// 使用示例
updatePost(123, {
  title: '更新后的文章标题',
  content: '更新后的文章内容',
  status: 'publish'
});

删除文章

// 删除文章
async function deletePost(postId, forceDelete = false) {
  try {
    const response = await fetch(`https://your-site.com/wp-json/wp/v2/posts/${postId}?force=${forceDelete}`, {
      method: 'DELETE',
      headers: {
        'X-WP-Nonce': wpApiSettings.nonce
      }
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const result = await response.json();
    console.log('文章删除成功:', result);
    return result;
  } catch (error) {
    console.error('删除文章失败:', error);
    throw error;
  }
}

// 使用示例
deletePost(123, true); // 永久删除
deletePost(123, false); // 移到回收站

七、自定义 REST API 端点

1. 创建自定义端点

在主题或插件中创建自定义 API 端点:

<?php
// 注册自定义 REST 路由
add_action('rest_api_init', function () {
    // 获取热门文章的自定义端点
    register_rest_route('my-plugin/v1', '/popular-posts', array(
        'methods' => 'GET',
        'callback' => 'my_plugin_get_popular_posts',
        'permission_callback' => '__return_true' // 允许公开访问
    ));

    // 获取用户统计的自定义端点(需要认证)
    register_rest_route('my-plugin/v1', '/user-stats', array(
        'methods' => 'GET',
        'callback' => 'my_plugin_get_user_stats',
        'permission_callback' => function () {
            return current_user_can('read');
        }
    ));
});

// 热门文章回调函数
function my_plugin_get_popular_posts($request) {
    // 获取参数
    $count = $request->get_param('count') ?: 5;

    // 查询热门文章
    $args = array(
        'post_type' => 'post',
        'posts_per_page' => $count,
        'meta_key' => 'post_views_count',
        'orderby' => 'meta_value_num',
        'order' => 'DESC'
    );

    $posts = get_posts($args);

    // 准备响应数据
    $data = array();
    foreach ($posts as $post) {
        $data[] = array(
            'id' => $post->ID,
            'title' => $post->post_title,
            'views' => get_post_meta($post->ID, 'post_views_count', true),
            'link' => get_permalink($post->ID)
        );
    }

    return new WP_REST_Response($data, 200);
}

// 用户统计回调函数
function my_plugin_get_user_stats($request) {
    $user_id = get_current_user_id();

    $stats = array(
        'user_id' => $user_id,
        'post_count' => count_user_posts($user_id),
        'comment_count' => get_comments(array(
            'user_id' => $user_id,
            'count' => true
        )),
        'registration_date' => get_the_author_meta('user_registered', $user_id)
    );

    return new WP_REST_Response($stats, 200);
}
?>

2. 使用自定义端点

// 调用自定义端点
fetch('https://your-site.com/wp-json/my-plugin/v1/popular-posts?count=10')
  .then(response => response.json())
  .then(posts => {
    console.log('热门文章:', posts);
  });

// 获取用户统计(需要认证)
fetch('https://your-site.com/wp-json/my-plugin/v1/user-stats', {
  headers: {
    'X-WP-Nonce': wpApiSettings.nonce
  }
})
.then(response => response.json())
.then(stats => {
  console.log('用户统计:', stats);
});

八、REST API 最佳实践

1. 缓存优化

// 使用缓存减少 API 请求
const cache = new Map();

async function fetchWithCache(url) {
  if (cache.has(url)) {
    console.log('从缓存获取:', url);
    return cache.get(url);
  }

  const response = await fetch(url);
  const data = await response.json();

  // 缓存5分钟
  cache.set(url, data);
  setTimeout(() => cache.delete(url), 5 * 60 * 1000);

  return data;
}

// 使用示例
fetchWithCache('https://your-site.com/wp-json/wp/v2/posts')
  .then(posts => {
    console.log('文章列表:', posts);
  });

2. 错误处理

// 完善的错误处理
async function safeFetch(url, options = {}) {
  try {
    const response = await fetch(url, options);

    if (!response.ok) {
      const error = await response.json();
      throw new Error(error.message || `HTTP error! status: ${response.status}`);
    }

    return await response.json();
  } catch (error) {
    console.error('API 请求失败:', error);

    // 根据错误类型进行不同处理
    if (error.message.includes('401')) {
      console.log('需要重新认证');
    } else if (error.message.includes('403')) {
      console.log('权限不足');
    } else if (error.message.includes('404')) {
      console.log('资源不存在');
    }

    throw error;
  }
}

3. 分页处理

// 处理分页数据
async function getAllPosts() {
  let allPosts = [];
  let page = 1;
  const perPage = 100;

  while (true) {
    const response = await fetch(
      `https://your-site.com/wp-json/wp/v2/posts?page=${page}&per_page=${perPage}`
    );

    // 获取总页数
    const totalPages = parseInt(response.headers.get('X-WP-TotalPages'), 10);
    const posts = await response.json();

    allPosts = allPosts.concat(posts);

    if (page >= totalPages) {
      break;
    }

    page++;
  }

  return allPosts;
}

九、安全注意事项

1. 权限检查

<?php
// 始终进行权限检查
register_rest_route('my-plugin/v1', '/delete-post', array(
    'methods' => 'POST',
    'callback' => 'my_plugin_delete_post',
    'permission_callback' => function ($request) {
        // 检查用户是否登录
        if (!is_user_logged_in()) {
            return new WP_Error(
                'rest_not_logged_in',
                '您需要登录才能执行此操作',
                array('status' => 401)
            );
        }

        // 检查用户权限
        if (!current_user_can('delete_posts')) {
            return new WP_Error(
                'rest_forbidden',
                '您没有权限执行此操作',
                array('status' => 403)
            );
        }

        return true;
    }
));
?>

2. 数据验证和清理

<?php
function my_plugin_create_post($request) {
    // 验证和清理输入数据
    $title = sanitize_text_field($request->get_param('title'));
    $content = wp_kses_post($request->get_param('content'));

    if (empty($title)) {
        return new WP_Error(
            'rest_invalid_param',
            '文章标题不能为空',
            array('status' => 400)
        );
    }

    // 创建文章
    $post_id = wp_insert_post(array(
        'post_title' => $title,
        'post_content' => $content,
        'post_status' => 'publish'
    ));

    if (is_wp_error($post_id)) {
        return $post_id;
    }

    return new WP_REST_Response(array(
        'message' => '文章创建成功',
        'post_id' => $post_id
    ), 200);
}
?>

3. 速率限制

<?php
// 添加速率限制
add_action('rest_api_init', function () {
    // 简单的速率限制实现
    register_rest_route('my-plugin/v1', '/action', array(
        'methods' => 'POST',
        'callback' => 'my_plugin_rate_limited_action',
        'permission_callback' => '__return_true'
    ));
});

function my_plugin_rate_limited_action($request) {
    $user_id = get_current_user_id() ?: $_SERVER['REMOTE_ADDR'];
    $transient_key = 'rate_limit_' . md5($user_id);

    // 检查是否在限制期内
    if (get_transient($transient_key)) {
        return new WP_Error(
            'rest_too_many_requests',
            '请求过于频繁,请稍后再试',
            array('status' => 429)
        );
    }

    // 设置1分钟的限制
    set_transient($transient_key, true, 60);

    // 执行实际操作
    return new WP_REST_Response(array('message' => '操作成功'), 200);
}
?>

十、总结与扩展

你已经学会了:

  1. ✅ WordPress REST API 的基础概念
  2. ✅ 使用 REST API 获取和操作数据
  3. ✅ 认证和权限管理
  4. ✅ 创建自定义 API 端点
  5. ✅ REST API 最佳实践
  6. ✅ 安全注意事项

下一步可以学习:

  • GraphQL 集成:使用 WPGraphQL 插件提供 GraphQL API
  • WebSockets:实现实时数据更新
  • OAuth 2.0:实现更复杂的认证流程
  • API 版本管理:管理 API 的版本演进
  • API 文档:使用 Swagger/OpenAPI 生成 API 文档

推荐资源:


希望这篇教程能帮助你入门 WordPress REST API。REST API 是现代 WordPress 开发的重要工具,掌握它将为你的开发工作带来极大的灵活性和可能性。

Happy Coding! 🚀