WordPress REST API

目次

WordPress REST API とは?

WordPress REST APIは、WordPressに標準で付いてるAPI!
何ができる?
✅ 投稿の取得・作成・更新・削除
✅ カテゴリー・タグの管理
✅ メディア(画像)のアップロード
✅ ユーザー情報の取得
✅ コメントの管理
つまり、WordPressでできることは、ほぼ全部APIでできる! 🎉

WordPress REST API の構造

https://your-site.com/wp-json/

これにアクセスすると、利用可能なAPIの一覧が見られます!

エンドポイント何ができる?
/wp/v2/posts投稿
/wp/v2/pages固定ページ
/wp/v2/categoriesカテゴリー
/wp/v2/tagsタグ
/wp/v2/mediaメディア(画像)
/wp/v2/usersユーザー
/wp/v2/commentsコメント

事前の準備

アプリケーションパスワードを作成

WordPress管理画面:

  1. ユーザー → プロフィール
  2. 下にスクロール → 「アプリケーションパスワード」
  3. 名前を入力(例: “Concert Manager App”)
  4. 「新しいアプリケーションパスワードを追加」
  5. 表示されたパスワードをコピー(xxxx xxxx xxxx xxxx)

これで認証の準備完了! 🔑

投稿の操作GET)

投稿一覧を取得

import 'package:http/http.dart' as http;
import 'dart:convert';

class WordPressService {
  static const String baseUrl = 'https://your-site.com';
  
  // ========================================
  // 投稿一覧を取得
  // ========================================
  Future<List<dynamic>> getPosts() async {
    // エンドポイント
    final url = Uri.parse('$baseUrl/wp-json/wp/v2/posts');
    
    // GET リクエスト
    final response = await http.get(url);
    
    if (response.statusCode == 200) {
      // JSON をデコード
      return json.decode(response.body);
    } else {
      throw Exception('投稿取得失敗: ${response.statusCode}');
    }
  }
}

// ========================================
// 使い方
// ========================================
final service = WordPressService();
final posts = await service.getPosts();

for (var post in posts) {
  print('タイトル: ${post['title']['rendered']}');
  print('内容: ${post['content']['rendered']}');
  print('日付: ${post['date']}');
  print('---');
}
```

**出力:**
```
タイトル: 春のコンサート
内容: <p>今年も素晴らしいコンサートを...</p>
日付: 2026-01-15T10:00:00
---
タイトル: ピアノリサイタル
内容: <p>クラシック音楽の...</p>
日付: 2026-01-10T14:30:00
---

パラメータ付きで取得

class WordPressService {
  // ========================================
  // パラメータ付きで投稿を取得
  // ========================================
  Future<List<dynamic>> getPostsWithParams({
    int perPage = 10,        // 1ページあたりの件数
    int page = 1,            // ページ番号
    String orderBy = 'date', // 並び順の基準
    String order = 'desc',   // 昇順/降順
    int? categoryId,         // カテゴリーID
    String? search,          // 検索キーワード
  }) async {
    // パラメータを作成
    Map<String, String> params = {
      'per_page': perPage.toString(),
      'page': page.toString(),
      'orderby': orderBy,
      'order': order,
    };
    
    // カテゴリーで絞り込み
    if (categoryId != null) {
      params['categories'] = categoryId.toString();
    }
    
    // 検索
    if (search != null && search.isNotEmpty) {
      params['search'] = search;
    }
    
    // URLを作成
    final url = Uri.https(
      'your-site.com',
      '/wp-json/wp/v2/posts',
      params,
    );
    
    final response = await http.get(url);
    
    if (response.statusCode == 200) {
      return json.decode(response.body);
    } else {
      throw Exception('取得失敗');
    }
  }
}

// ========================================
// 使い方
// ========================================

// 最新5件を取得
final latest = await service.getPostsWithParams(perPage: 5);

// カテゴリー3の投稿を取得
final category3 = await service.getPostsWithParams(categoryId: 3);

// "コンサート"で検索
final concerts = await service.getPostsWithParams(search: 'コンサート');

// 古い順に10件
final oldest = await service.getPostsWithParams(
  perPage: 10,
  order: 'asc',
);

特定の投稿を取得(ID指定)

// ========================================
// IDで1つの投稿を取得
// ========================================
Future<Map<String, dynamic>> getPostById(int postId) async {
  final url = Uri.parse('$baseUrl/wp-json/wp/v2/posts/$postId');
  
  final response = await http.get(url);
  
  if (response.statusCode == 200) {
    return json.decode(response.body);
  } else if (response.statusCode == 404) {
    throw Exception('投稿が見つかりません');
  } else {
    throw Exception('取得失敗');
  }
}

// 使い方
final post = await service.getPostById(123);
print(post['title']['rendered']);

特定の投稿を取得(ID指定)対して何をするかを指定!

// ========================================
// IDで1つの投稿を取得
// ========================================
Future<Map<String, dynamic>> getPostById(int postId) async {
  final url = Uri.parse('$baseUrl/wp-json/wp/v2/posts/$postId');
  
  final response = await http.get(url);
  
  if (response.statusCode == 200) {
    return json.decode(response.body);
  } else if (response.statusCode == 404) {
    throw Exception('投稿が見つかりません');
  } else {
    throw Exception('取得失敗');
  }
}

// 使い方
final post = await service.getPostById(123);
print(post['title']['rendered']);

投稿を作成(POST)

認証が必要!

class WordPressService {
  static const String baseUrl = 'https://your-site.com';
  static const String username = 'your-username';
  static const String appPassword = 'xxxx xxxx xxxx xxxx';
  
  // ========================================
  // 認証ヘッダー
  // ========================================
  Map<String, String> get authHeaders {
    String credentials = '$username:$appPassword';
    String encoded = base64Encode(utf8.encode(credentials));
    
    return {
      'Content-Type': 'application/json',
      'Authorization': 'Basic $encoded',
    };
  }
  
  // ========================================
  // 投稿を作成
  // ========================================
  Future<Map<String, dynamic>> createPost({
    required String title,
    required String content,
    String status = 'draft',  // draft, publish, private
    List<int>? categories,
    List<int>? tags,
  }) async {
    final url = Uri.parse('$baseUrl/wp-json/wp/v2/posts');
    
    // 送信するデータ
    Map<String, dynamic> data = {
      'title': title,
      'content': content,
      'status': status,
    };
    
    if (categories != null) {
      data['categories'] = categories;
    }
    
    if (tags != null) {
      data['tags'] = tags;
    }
    
    // POST リクエスト
    final response = await http.post(
      url,
      headers: authHeaders,  // ← 認証ヘッダー
      body: json.encode(data),
    );
    
    if (response.statusCode == 201) {
      return json.decode(response.body);
    } else {
      throw Exception('投稿作成失敗: ${response.statusCode}');
    }
  }
}

// ========================================
// 使い方
// ========================================
final result = await service.createPost(
  title: '春のコンサート2026',
  content: '<p>今年も素晴らしいコンサートを開催します!</p>',
  status: 'publish',  // 公開
  categories: [3, 5],  // カテゴリーID
);

print('作成した投稿ID: ${result['id']}');
print('タイトル: ${result['title']['rendered']}');

投稿を更新(PUT)

// ========================================
// 投稿を更新
// ========================================
Future<Map<String, dynamic>> updatePost({
  required int postId,
  String? title,
  String? content,
  String? status,
  List<int>? categories,
}) async {
  final url = Uri.parse('$baseUrl/wp-json/wp/v2/posts/$postId');
  
  // 更新するデータ(null以外のみ)
  Map<String, dynamic> data = {};
  
  if (title != null) data['title'] = title;
  if (content != null) data['content'] = content;
  if (status != null) data['status'] = status;
  if (categories != null) data['categories'] = categories;
  
  final response = await http.put(
    url,
    headers: authHeaders,
    body: json.encode(data),
  );
  
  if (response.statusCode == 200) {
    return json.decode(response.body);
  } else {
    throw Exception('更新失敗: ${response.statusCode}');
  }
}

// 使い方
final updated = await service.updatePost(
  postId: 123,
  title: '【更新】春のコンサート2026',
  status: 'publish',
);

投稿を削除(DELETE)

// ========================================
// 投稿を削除
// ========================================
Future<void> deletePost(int postId) async {
  final url = Uri.parse('$baseUrl/wp-json/wp/v2/posts/$postId');
  
  final response = await http.delete(
    url,
    headers: authHeaders,
  );
  
  if (response.statusCode == 200) {
    print('削除成功');
  } else {
    throw Exception('削除失敗: ${response.statusCode}');
  }
}

// 使い方
await service.deletePost(123);

モデルクラスを作る

class WPPost {
  final int id;
  final String title;
  final String content;
  final DateTime date;
  final String status;
  final List<int> categories;
  
  WPPost({
    required this.id,
    required this.title,
    required this.content,
    required this.date,
    required this.status,
    this.categories = const [],
  });
  
  // ========================================
  // WordPress JSON → WPPost
  // ========================================
  factory WPPost.fromJson(Map<String, dynamic> json) {
    return WPPost(
      id: json['id'],
      title: json['title']['rendered'],  // ← WordPressの形式
      content: json['content']['rendered'],
      date: DateTime.parse(json['date']),
      status: json['status'],
      categories: (json['categories'] as List<dynamic>?)
              ?.map((e) => e as int)
              .toList() ??
          [],
    );
  }
  
  // ========================================
  // WPPost → JSON
  // ========================================
  Map<String, dynamic> toJson() {
    return {
      'title': title,
      'content': content,
      'status': status,
      'categories': categories,
    };
  }
  
  // ========================================
  // HTMLタグを削除
  // ========================================
  String get plainContent {
    return content.replaceAll(RegExp(r'<[^>]*>'), '');
  }
}

// ========================================
// 使い方
// ========================================
final posts = await service.getPosts();
final wpPosts = posts.map((json) => WPPost.fromJson(json)).toList();

for (var post in wpPosts) {
  print(post.title);
  print(post.plainContent);
}

画像のアップロード

import 'dart:io';

class MediaService {
  static const String baseUrl = 'https://your-site.com';
  static const String username = 'your-username';
  static const String appPassword = 'xxxx xxxx xxxx xxxx';
  
  Map<String, String> get authHeaders {
    String credentials = '$username:$appPassword';
    String encoded = base64Encode(utf8.encode(credentials));
    
    return {
      'Authorization': 'Basic $encoded',
    };
  }
  
  // ========================================
  // 画像をアップロード
  // ========================================
  Future<Map<String, dynamic>> uploadImage(File imageFile) async {
    final url = Uri.parse('$baseUrl/wp-json/wp/v2/media');
    
    // multipart リクエストを作成
    var request = http.MultipartRequest('POST', url);
    
    // 認証ヘッダー
    request.headers.addAll(authHeaders);
    
    // ファイルを追加
    request.files.add(
      await http.MultipartFile.fromPath(
        'file',
        imageFile.path,
      ),
    );
    
    // 送信
    final streamedResponse = await request.send();
    final response = await http.Response.fromStream(streamedResponse);
    
    if (response.statusCode == 201) {
      final data = json.decode(response.body);
      return data;
    } else {
      throw Exception('アップロード失敗: ${response.statusCode}');
    }
  }
}

// ========================================
// 使い方
// ========================================
final mediaService = MediaService();
final imageFile = File('/path/to/image.jpg');

final result = await mediaService.uploadImage(imageFile);
print('画像URL: ${result['source_url']}');
print('メディアID: ${result['id']}');

// 投稿に画像を設定
await eventService.createEvent(
  title: 'コンサート',
  content: '...',
  featuredMedia: result['id'],  // ← アップロードした画像のID
);

まとめ

WordPress REST APIの基本:

エンドポイントメソッド説明
/wp/v2/postsGET投稿一覧
/wp/v2/postsPOST投稿作成
/wp/v2/posts/123PUT投稿更新
/wp/v2/posts/123DELETE投稿削除

認証:

アプリケーションパスワードを作成
Basic認証でヘッダーに追加
GET は認証不要、POST/PUT/DELETE は認証必須

REST APIはURLでデータを操作する仕組み!
エンドポイント(住所)にHTTPメソッド(GET/POST/PUT/DELETE)でアクセス。
WordPress REST APIは標準搭載で、投稿・カテゴリー・メディアなど全部操作できる!
アプリケーションパスワード+Basic認証で安全に! 🌐✨

目次