Install
This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/shaik-obydullah/wp-rest-crud/archive/refs/heads/main.zipA unified WordPress REST API plugin that provides full CRUD operations for both Items and Todos. This plugin creates custom database tables and exposes RESTful endpoints under a single namespace.
Features
- Object-Oriented Design: Refactored to use a singleton class for better organization and extensibility
- Dual Resource Support: Manage both menu items and todo tasks in one plugin
- Full CRUD Operations: Create, Read, Update, and Delete for both resources
- RESTful API: Clean, standard REST endpoints under
oby-crud/v1namespace - Authentication Control: Public read access, admin-only write operations (filterable via
orc_required_capability) - Pagination & Filtering: List endpoints support search, filtering, sorting, and pagination
- Sorting Support: Sort by any allowed field in ascending or descending order
- Enhanced Search: Todos can be searched by title or description
- Timestamps: Tracks both
created_atandupdated_atfor all records - Automatic Table Creation: Custom tables are created on plugin activation with sample data
- Convenience Routes: Quick action to mark todos as complete
- REST Schema: Routes include JSON schema for better API documentation and validation
- Clean Uninstall: Tables are removed when the plugin is deleted
Installation
- Copy the
oby-rest-crud.phpanduninstall.phpfiles to your WordPress plugins directory (wp-content/plugins/oby-rest-crud/) - Activate the plugin from the WordPress admin panel
- The plugin will automatically create two tables:
wp_rest_items- for items/productswp_oby_todos- for todos/tasks
- Sample data will be inserted if tables are empty
API Endpoints
Base URL: https://your-site.com/wp-json/oby-crud/v1
Items Endpoints
| Method | Endpoint | Permission | Description |
|---|---|---|---|
GET |
/items |
Public | List all items with optional search, sorting, and pagination |
POST |
/items |
Configurable (default: manage_options) |
Create a new item |
GET |
/items/{id} |
Public | Get a single item by ID |
PUT |
/items/{id} |
Configurable (default: manage_options) |
Update an item (partial update supported) |
DELETE |
/items/{id} |
Configurable (default: manage_options) |
Delete an item |
Query Parameters for GET /items
search(string, optional) - Search items by namepage(integer, optional, default: 1) - Page numberper_page(integer, optional, default: 10, max: 100) - Items per pageorderby(string, optional, default: id) - Sort by:id,name,price,status,created_at,updated_atorder(string, optional, default: desc) - Sort order:ascordesc
Request Body for POST /items
{
"name": "Product Name", // Required
"price": 9.99 // Optional, defaults to 0
}
Request Body for PUT /items/{id}
{
"name": "Updated Name", // Optional
"price": 19.99, // Optional
"status": "inactive" // Optional, values: "active" or "inactive"
}
Response Format:
{
"items": [...],
"pagination": {
"total": 10,
"total_pages": 1,
"page": 1,
"per_page": 10
}
}
Response Headers:
X-WP-Total- Total number of itemsX-WP-TotalPages- Total number of pages
Todos Endpoints
| Method | Endpoint | Permission | Description |
|---|---|---|---|
GET |
/todos |
Public | List all todos with optional search, status filter, sorting, and pagination |
POST |
/todos |
Configurable (default: manage_options) |
Create a new todo |
GET |
/todos/{id} |
Public | Get a single todo by ID |
PUT |
/todos/{id} |
Configurable (default: manage_options) |
Update a todo (partial update supported) |
DELETE |
/todos/{id} |
Configurable (default: manage_options) |
Delete a todo |
POST |
/todos/{id}/complete |
Configurable (default: manage_options) |
Mark a todo as completed (shortcut) |
Query Parameters for GET /todos
search(string, optional) - Search todos by title or descriptionstatus(string, optional) - Filter by status:pendingorcompletedpage(integer, optional, default: 1) - Page numberper_page(integer, optional, default: 10, max: 100) - Todos per pageorderby(string, optional, default: id) - Sort by:id,title,status,created_at,updated_atorder(string, optional, default: desc) - Sort order:ascordesc
Request Body for POST /todos
{
"title": "Task Title", // Required
"description": "Task details", // Optional, defaults to ""
"status": "pending" // Optional, values: "pending" or "completed", defaults to "pending"
}
Request Body for PUT /todos/{id}
{
"title": "Updated Title", // Optional
"description": "New details", // Optional
"status": "completed" // Optional, values: "pending" or "completed"
}
Response Format:
{
"todos": [...],
"pagination": {
"total": 10,
"total_pages": 1,
"page": 1,
"per_page": 10
}
}
Response Headers:
X-WP-Total- Total number of todosX-WP-TotalPages- Total number of pages
Database Schema
Items Table: wp_rest_items
| Column | Type | Description |
|---|---|---|
id |
BIGINT UNSIGNED (AUTO_INCREMENT) | Primary key |
name |
VARCHAR(191) | Item name |
price |
DECIMAL(10,2) | Item price (default: 0.00) |
status |
VARCHAR(20) | Status: active or inactive (default: active) |
created_at |
DATETIME | Creation timestamp |
updated_at |
DATETIME | Last update timestamp |
Todos Table: wp_oby_todos
| Column | Type | Description |
|---|---|---|
id |
BIGINT UNSIGNED (AUTO_INCREMENT) | Primary key |
title |
VARCHAR(191) | Todo title |
description |
TEXT (NULL) | Todo description |
status |
VARCHAR(20) | Status: pending or completed (default: pending) |
created_at |
DATETIME | Creation timestamp |
updated_at |
DATETIME | Last update timestamp |
Usage Examples
Using cURL
List all items (public):
curl https://your-site.com/wp-json/oby-crud/v1/items
List items sorted by price ascending:
curl https://your-site.com/wp-json/oby-crud/v1/items?orderby=price&order=asc
Search todos by title or description:
curl https://your-site.com/wp-json/oby-crud/v1/todos?search=api
Create a new item (admin authentication required):
curl -X POST https://your-site.com/wp-json/oby-crud/v1/items \
-H "Content-Type: application/json" \
-u "username:application_password" \
-d '{"name": "Coffee", "price": 4.50}'
Update a todo:
curl -X PUT https://your-site.com/wp-json/oby-crud/v1/todos/1 \
-H "Content-Type: application/json" \
-u "username:application_password" \
-d '{"status": "completed"}'
Mark todo as complete (shortcut):
curl -X POST https://your-site.com/wp-json/oby-crud/v1/todos/1/complete \
-u "username:application_password"
Delete an item:
curl -X DELETE https://your-site.com/wp-json/oby-crud/v1/items/2 \
-u "username:application_password"
Using JavaScript (Fetch API)
// Get all todos with pagination
fetch('https://your-site.com/wp-json/oby-crud/v1/todos?page=1&per_page=5')
.then(res => res.json())
.then(data => console.log(data.todos, data.pagination));
// Create a todo (requires authentication)
fetch('https://your-site.com/wp-json/oby-crud/v1/todos', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic ' + btoa('username:application_password')
},
body: JSON.stringify({
title: 'New Task',
description: 'Task description'
})
})
.then(res => res.json())
.then(data => console.log(data));
Authentication
For write operations (POST, PUT, DELETE), the plugin requires users with a capability (by default manage_options, typically administrators). You can authenticate using:
- WordPress Application Passwords (recommended for REST API) - Available in WordPress 5.6+
- Cookie authentication (for logged-in users in the same site)
- Basic Auth (with plugins or in development)
Customizing Permissions
You can change the required capability using the orc_required_capability filter:
add_filter('orc_required_capability', function() {
return 'edit_posts'; // Allow editors to manage items and todos
});
Error Responses
| Status Code | Description |
|---|---|
200 |
Success |
201 |
Created successfully |
400 |
Bad request / validation error |
401 |
Unauthorized (missing authentication) |
403 |
Forbidden (insufficient permissions) |
404 |
Resource not found |
Example 404 response:
{
"code": "not_found",
"message": "Todo not found.",
"data": {
"status": 404
}
}
Notes
- Public GET endpoints allow anyone to read data
- All write operations require the configured capability (default: administrator privileges)
- Partial updates are supported for PUT requests (only sent fields are updated)
- The plugin uses
dbDelta()for safe table creation/updates - Sample data is only inserted if the respective table is empty on activation
- When uninstalling the plugin (deleting), both custom tables will be permanently removed
- Pagination data is returned in both the JSON body and response headers for flexibility
- Todos can be searched across both title and description fields
Changelog
Version 1.1.0
- OOP Refactor: Converted to singleton class-based architecture
- Sorting: Added
orderbyandorderparameters to list endpoints - Enhanced Pagination: Pagination metadata now included in JSON response body
- Timestamps: Added
updated_atfield to both tables - Extended Search: Todos now searchable by title and description
- REST Schema: Added JSON schema for routes
- Capability Filter: Added
orc_required_capabilityfilter for flexible permissions - Uninstall Support: Added
uninstall.phpto clean up tables on deletion
Version 1.0.0
- Unified both OBY REST Practice and OBY Todo plugins into single plugin
- Combined namespaces under
oby-crud/v1 - Added support for both items and todos
- Comprehensive documentation