@mytechtoday/augment-extensions 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/augment-extensions/domain-rules/wordpress/README.md +163 -0
- package/augment-extensions/domain-rules/wordpress/module.json +32 -0
- package/augment-extensions/domain-rules/wordpress/rules/coding-standards.md +617 -0
- package/augment-extensions/domain-rules/wordpress/rules/directory-structure.md +270 -0
- package/augment-extensions/domain-rules/wordpress/rules/file-patterns.md +423 -0
- package/augment-extensions/domain-rules/wordpress/rules/gutenberg-blocks.md +493 -0
- package/augment-extensions/domain-rules/wordpress/rules/performance.md +568 -0
- package/augment-extensions/domain-rules/wordpress/rules/plugin-development.md +510 -0
- package/augment-extensions/domain-rules/wordpress/rules/project-detection.md +251 -0
- package/augment-extensions/domain-rules/wordpress/rules/rest-api.md +501 -0
- package/augment-extensions/domain-rules/wordpress/rules/security.md +564 -0
- package/augment-extensions/domain-rules/wordpress/rules/theme-development.md +388 -0
- package/augment-extensions/domain-rules/wordpress/rules/woocommerce.md +441 -0
- package/augment-extensions/domain-rules/wordpress-plugin/README.md +139 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/ajax-plugin.md +1599 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/custom-post-type-plugin.md +1727 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/gutenberg-block-plugin.md +428 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/gutenberg-block.md +422 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/mvc-plugin.md +1623 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/object-oriented-plugin.md +1343 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/rest-endpoint.md +734 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/settings-page-plugin.md +1350 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/simple-procedural-plugin.md +503 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/singleton-plugin.md +971 -0
- package/augment-extensions/domain-rules/wordpress-plugin/module.json +53 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/activation-hooks.md +770 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/admin-interface.md +874 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/ajax-handlers.md +629 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/asset-management.md +559 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/context-providers.md +709 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/cron-jobs.md +736 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/database-management.md +1057 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/documentation-standards.md +463 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/frontend-functionality.md +478 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/gutenberg-blocks.md +818 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/internationalization.md +416 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/migration.md +667 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/performance-optimization.md +878 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/plugin-architecture.md +693 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/plugin-structure.md +352 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/rest-api.md +818 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/scaffolding-workflow.md +624 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/security-best-practices.md +866 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/testing-patterns.md +1165 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/testing.md +414 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/vscode-integration.md +751 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/woocommerce-integration.md +949 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/wordpress-org-submission.md +458 -0
- package/augment-extensions/examples/gutenberg-block-plugin/README.md +101 -0
- package/augment-extensions/examples/gutenberg-block-plugin/examples/testimonial-block.md +428 -0
- package/augment-extensions/examples/gutenberg-block-plugin/module.json +40 -0
- package/augment-extensions/examples/rest-api-plugin/README.md +98 -0
- package/augment-extensions/examples/rest-api-plugin/examples/task-manager-api.md +1299 -0
- package/augment-extensions/examples/rest-api-plugin/module.json +40 -0
- package/augment-extensions/examples/woocommerce-extension/README.md +98 -0
- package/augment-extensions/examples/woocommerce-extension/examples/product-customizer.md +763 -0
- package/augment-extensions/examples/woocommerce-extension/module.json +40 -0
- package/augment-extensions/workflows/wordpress-plugin/README.md +232 -0
- package/augment-extensions/workflows/wordpress-plugin/ai-prompts.md +839 -0
- package/augment-extensions/workflows/wordpress-plugin/bead-decomposition-patterns.md +854 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/complete-plugin-example.md +540 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/custom-post-type-example.md +1083 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/feature-addition-workflow.md +669 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/plugin-creation-workflow.md +597 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/secure-form-handler-example.md +925 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/security-audit-workflow.md +752 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/wordpress-org-submission-workflow.md +773 -0
- package/augment-extensions/workflows/wordpress-plugin/module.json +49 -0
- package/augment-extensions/workflows/wordpress-plugin/rules/best-practices.md +942 -0
- package/augment-extensions/workflows/wordpress-plugin/rules/development-workflow.md +702 -0
- package/augment-extensions/workflows/wordpress-plugin/rules/submission-workflow.md +728 -0
- package/augment-extensions/workflows/wordpress-plugin/rules/testing-workflow.md +775 -0
- package/cli/dist/cli.js +5 -1
- package/cli/dist/cli.js.map +1 -1
- package/cli/dist/commands/show.d.ts.map +1 -1
- package/cli/dist/commands/show.js +41 -0
- package/cli/dist/commands/show.js.map +1 -1
- package/modules.md +52 -0
- package/package.json +1 -1
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
# WordPress REST API Development Workflow
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This document provides workflows for extending the WordPress REST API with custom endpoints and modifying existing endpoints.
|
|
6
|
+
|
|
7
|
+
## Workflow 1: Register Custom REST API Endpoint
|
|
8
|
+
|
|
9
|
+
### Step 1: Create Basic Endpoint
|
|
10
|
+
|
|
11
|
+
**functions.php** or plugin file:
|
|
12
|
+
```php
|
|
13
|
+
/**
|
|
14
|
+
* Register custom REST API endpoint
|
|
15
|
+
*/
|
|
16
|
+
function register_custom_api_endpoint() {
|
|
17
|
+
register_rest_route( 'my-plugin/v1', '/items', array(
|
|
18
|
+
'methods' => 'GET',
|
|
19
|
+
'callback' => 'get_custom_items',
|
|
20
|
+
'permission_callback' => '__return_true', // Public endpoint
|
|
21
|
+
) );
|
|
22
|
+
}
|
|
23
|
+
add_action( 'rest_api_init', 'register_custom_api_endpoint' );
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Callback function for endpoint
|
|
27
|
+
*/
|
|
28
|
+
function get_custom_items( $request ) {
|
|
29
|
+
$items = array(
|
|
30
|
+
array(
|
|
31
|
+
'id' => 1,
|
|
32
|
+
'title' => 'Item 1',
|
|
33
|
+
'description' => 'First item',
|
|
34
|
+
),
|
|
35
|
+
array(
|
|
36
|
+
'id' => 2,
|
|
37
|
+
'title' => 'Item 2',
|
|
38
|
+
'description' => 'Second item',
|
|
39
|
+
),
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
return new WP_REST_Response( $items, 200 );
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Access endpoint**:
|
|
47
|
+
```
|
|
48
|
+
GET https://example.com/wp-json/my-plugin/v1/items
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Step 2: Add Multiple HTTP Methods
|
|
52
|
+
|
|
53
|
+
```php
|
|
54
|
+
/**
|
|
55
|
+
* Register endpoint with multiple methods
|
|
56
|
+
*/
|
|
57
|
+
function register_crud_endpoint() {
|
|
58
|
+
// GET - Retrieve items
|
|
59
|
+
register_rest_route( 'my-plugin/v1', '/items', array(
|
|
60
|
+
'methods' => 'GET',
|
|
61
|
+
'callback' => 'get_items',
|
|
62
|
+
'permission_callback' => '__return_true',
|
|
63
|
+
) );
|
|
64
|
+
|
|
65
|
+
// POST - Create item
|
|
66
|
+
register_rest_route( 'my-plugin/v1', '/items', array(
|
|
67
|
+
'methods' => 'POST',
|
|
68
|
+
'callback' => 'create_item',
|
|
69
|
+
'permission_callback' => 'check_create_permission',
|
|
70
|
+
'args' => get_item_schema(),
|
|
71
|
+
) );
|
|
72
|
+
|
|
73
|
+
// GET - Retrieve single item
|
|
74
|
+
register_rest_route( 'my-plugin/v1', '/items/(?P<id>\d+)', array(
|
|
75
|
+
'methods' => 'GET',
|
|
76
|
+
'callback' => 'get_item',
|
|
77
|
+
'permission_callback' => '__return_true',
|
|
78
|
+
'args' => array(
|
|
79
|
+
'id' => array(
|
|
80
|
+
'validate_callback' => function( $param ) {
|
|
81
|
+
return is_numeric( $param );
|
|
82
|
+
},
|
|
83
|
+
),
|
|
84
|
+
),
|
|
85
|
+
) );
|
|
86
|
+
|
|
87
|
+
// PUT - Update item
|
|
88
|
+
register_rest_route( 'my-plugin/v1', '/items/(?P<id>\d+)', array(
|
|
89
|
+
'methods' => 'PUT',
|
|
90
|
+
'callback' => 'update_item',
|
|
91
|
+
'permission_callback' => 'check_update_permission',
|
|
92
|
+
'args' => get_item_schema(),
|
|
93
|
+
) );
|
|
94
|
+
|
|
95
|
+
// DELETE - Delete item
|
|
96
|
+
register_rest_route( 'my-plugin/v1', '/items/(?P<id>\d+)', array(
|
|
97
|
+
'methods' => 'DELETE',
|
|
98
|
+
'callback' => 'delete_item',
|
|
99
|
+
'permission_callback' => 'check_delete_permission',
|
|
100
|
+
) );
|
|
101
|
+
}
|
|
102
|
+
add_action( 'rest_api_init', 'register_crud_endpoint' );
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Step 3: Implement Callback Functions
|
|
106
|
+
|
|
107
|
+
**GET single item**:
|
|
108
|
+
```php
|
|
109
|
+
function get_item( $request ) {
|
|
110
|
+
$id = $request['id'];
|
|
111
|
+
|
|
112
|
+
// Retrieve item from database
|
|
113
|
+
$item = get_post( $id );
|
|
114
|
+
|
|
115
|
+
if ( ! $item ) {
|
|
116
|
+
return new WP_Error( 'not_found', __( 'Item not found', 'my-plugin' ), array( 'status' => 404 ) );
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
$data = array(
|
|
120
|
+
'id' => $item->ID,
|
|
121
|
+
'title' => $item->post_title,
|
|
122
|
+
'content' => $item->post_content,
|
|
123
|
+
'date' => $item->post_date,
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
return new WP_REST_Response( $data, 200 );
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**POST - Create item**:
|
|
131
|
+
```php
|
|
132
|
+
function create_item( $request ) {
|
|
133
|
+
$title = sanitize_text_field( $request['title'] );
|
|
134
|
+
$content = sanitize_textarea_field( $request['content'] );
|
|
135
|
+
|
|
136
|
+
$post_id = wp_insert_post( array(
|
|
137
|
+
'post_title' => $title,
|
|
138
|
+
'post_content' => $content,
|
|
139
|
+
'post_status' => 'publish',
|
|
140
|
+
'post_type' => 'post',
|
|
141
|
+
) );
|
|
142
|
+
|
|
143
|
+
if ( is_wp_error( $post_id ) ) {
|
|
144
|
+
return new WP_Error( 'create_failed', __( 'Failed to create item', 'my-plugin' ), array( 'status' => 500 ) );
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
$data = array(
|
|
148
|
+
'id' => $post_id,
|
|
149
|
+
'title' => $title,
|
|
150
|
+
'content' => $content,
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
return new WP_REST_Response( $data, 201 );
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**PUT - Update item**:
|
|
158
|
+
```php
|
|
159
|
+
function update_item( $request ) {
|
|
160
|
+
$id = $request['id'];
|
|
161
|
+
$title = sanitize_text_field( $request['title'] );
|
|
162
|
+
$content = sanitize_textarea_field( $request['content'] );
|
|
163
|
+
|
|
164
|
+
$result = wp_update_post( array(
|
|
165
|
+
'ID' => $id,
|
|
166
|
+
'post_title' => $title,
|
|
167
|
+
'post_content' => $content,
|
|
168
|
+
) );
|
|
169
|
+
|
|
170
|
+
if ( is_wp_error( $result ) ) {
|
|
171
|
+
return new WP_Error( 'update_failed', __( 'Failed to update item', 'my-plugin' ), array( 'status' => 500 ) );
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
$data = array(
|
|
175
|
+
'id' => $id,
|
|
176
|
+
'title' => $title,
|
|
177
|
+
'content' => $content,
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
return new WP_REST_Response( $data, 200 );
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**DELETE - Delete item**:
|
|
185
|
+
```php
|
|
186
|
+
function delete_item( $request ) {
|
|
187
|
+
$id = $request['id'];
|
|
188
|
+
|
|
189
|
+
$result = wp_delete_post( $id, true );
|
|
190
|
+
|
|
191
|
+
if ( ! $result ) {
|
|
192
|
+
return new WP_Error( 'delete_failed', __( 'Failed to delete item', 'my-plugin' ), array( 'status' => 500 ) );
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return new WP_REST_Response( array( 'deleted' => true ), 200 );
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Workflow 2: Permission Callbacks
|
|
200
|
+
|
|
201
|
+
### Public Endpoint (No Authentication)
|
|
202
|
+
|
|
203
|
+
```php
|
|
204
|
+
'permission_callback' => '__return_true',
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Require Authentication
|
|
208
|
+
|
|
209
|
+
```php
|
|
210
|
+
function check_authentication() {
|
|
211
|
+
return is_user_logged_in();
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
'permission_callback' => 'check_authentication',
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Require Specific Capability
|
|
218
|
+
|
|
219
|
+
```php
|
|
220
|
+
function check_admin_permission() {
|
|
221
|
+
return current_user_can( 'manage_options' );
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
'permission_callback' => 'check_admin_permission',
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Custom Permission Logic
|
|
228
|
+
|
|
229
|
+
```php
|
|
230
|
+
function check_custom_permission( $request ) {
|
|
231
|
+
// Check if user is logged in
|
|
232
|
+
if ( ! is_user_logged_in() ) {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Check if user has capability
|
|
237
|
+
if ( ! current_user_can( 'edit_posts' ) ) {
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Check if user owns the resource
|
|
242
|
+
$id = $request['id'];
|
|
243
|
+
$post = get_post( $id );
|
|
244
|
+
|
|
245
|
+
if ( $post && $post->post_author != get_current_user_id() ) {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
'permission_callback' => 'check_custom_permission',
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Workflow 3: Input Validation and Sanitization
|
|
256
|
+
|
|
257
|
+
### Define Argument Schema
|
|
258
|
+
|
|
259
|
+
```php
|
|
260
|
+
function get_item_schema() {
|
|
261
|
+
return array(
|
|
262
|
+
'title' => array(
|
|
263
|
+
'required' => true,
|
|
264
|
+
'type' => 'string',
|
|
265
|
+
'description' => __( 'Item title', 'my-plugin' ),
|
|
266
|
+
'sanitize_callback' => 'sanitize_text_field',
|
|
267
|
+
'validate_callback' => function( $param ) {
|
|
268
|
+
return ! empty( $param ) && strlen( $param ) <= 200;
|
|
269
|
+
},
|
|
270
|
+
),
|
|
271
|
+
'content' => array(
|
|
272
|
+
'required' => false,
|
|
273
|
+
'type' => 'string',
|
|
274
|
+
'description' => __( 'Item content', 'my-plugin' ),
|
|
275
|
+
'sanitize_callback' => 'sanitize_textarea_field',
|
|
276
|
+
),
|
|
277
|
+
'status' => array(
|
|
278
|
+
'required' => false,
|
|
279
|
+
'type' => 'string',
|
|
280
|
+
'description' => __( 'Item status', 'my-plugin' ),
|
|
281
|
+
'enum' => array( 'draft', 'published', 'archived' ),
|
|
282
|
+
'default' => 'draft',
|
|
283
|
+
),
|
|
284
|
+
'count' => array(
|
|
285
|
+
'required' => false,
|
|
286
|
+
'type' => 'integer',
|
|
287
|
+
'description' => __( 'Item count', 'my-plugin' ),
|
|
288
|
+
'minimum' => 0,
|
|
289
|
+
'maximum' => 100,
|
|
290
|
+
'default' => 0,
|
|
291
|
+
),
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Custom Validation
|
|
297
|
+
|
|
298
|
+
```php
|
|
299
|
+
function validate_email( $param, $request, $key ) {
|
|
300
|
+
if ( ! is_email( $param ) ) {
|
|
301
|
+
return new WP_Error( 'invalid_email', __( 'Invalid email address', 'my-plugin' ) );
|
|
302
|
+
}
|
|
303
|
+
return true;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
'args' => array(
|
|
307
|
+
'email' => array(
|
|
308
|
+
'required' => true,
|
|
309
|
+
'validate_callback' => 'validate_email',
|
|
310
|
+
'sanitize_callback' => 'sanitize_email',
|
|
311
|
+
),
|
|
312
|
+
),
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
## Workflow 4: Query Parameters
|
|
316
|
+
|
|
317
|
+
### Accept Query Parameters
|
|
318
|
+
|
|
319
|
+
```php
|
|
320
|
+
function get_items_with_filters( $request ) {
|
|
321
|
+
$params = $request->get_params();
|
|
322
|
+
|
|
323
|
+
$args = array(
|
|
324
|
+
'post_type' => 'post',
|
|
325
|
+
'posts_per_page' => isset( $params['per_page'] ) ? absint( $params['per_page'] ) : 10,
|
|
326
|
+
'paged' => isset( $params['page'] ) ? absint( $params['page'] ) : 1,
|
|
327
|
+
'orderby' => isset( $params['orderby'] ) ? sanitize_text_field( $params['orderby'] ) : 'date',
|
|
328
|
+
'order' => isset( $params['order'] ) ? sanitize_text_field( $params['order'] ) : 'DESC',
|
|
329
|
+
);
|
|
330
|
+
|
|
331
|
+
if ( isset( $params['search'] ) ) {
|
|
332
|
+
$args['s'] = sanitize_text_field( $params['search'] );
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
$query = new WP_Query( $args );
|
|
336
|
+
|
|
337
|
+
$items = array();
|
|
338
|
+
foreach ( $query->posts as $post ) {
|
|
339
|
+
$items[] = array(
|
|
340
|
+
'id' => $post->ID,
|
|
341
|
+
'title' => $post->post_title,
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
$response = new WP_REST_Response( $items, 200 );
|
|
346
|
+
|
|
347
|
+
// Add pagination headers
|
|
348
|
+
$response->header( 'X-WP-Total', $query->found_posts );
|
|
349
|
+
$response->header( 'X-WP-TotalPages', $query->max_num_pages );
|
|
350
|
+
|
|
351
|
+
return $response;
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
**Usage**:
|
|
356
|
+
```
|
|
357
|
+
GET /wp-json/my-plugin/v1/items?per_page=20&page=2&orderby=title&order=ASC&search=keyword
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## Workflow 5: Authentication
|
|
361
|
+
|
|
362
|
+
### Application Passwords (WordPress 5.6+)
|
|
363
|
+
|
|
364
|
+
```php
|
|
365
|
+
// No additional code needed - WordPress handles it
|
|
366
|
+
// Users create application passwords in their profile
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
**Usage**:
|
|
370
|
+
```bash
|
|
371
|
+
curl -X GET https://example.com/wp-json/my-plugin/v1/items \
|
|
372
|
+
--user "username:application-password"
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### JWT Authentication (Plugin Required)
|
|
376
|
+
|
|
377
|
+
Install JWT Authentication plugin, then:
|
|
378
|
+
|
|
379
|
+
```php
|
|
380
|
+
/**
|
|
381
|
+
* Endpoint requiring JWT authentication
|
|
382
|
+
*/
|
|
383
|
+
register_rest_route( 'my-plugin/v1', '/secure-data', array(
|
|
384
|
+
'methods' => 'GET',
|
|
385
|
+
'callback' => 'get_secure_data',
|
|
386
|
+
'permission_callback' => function() {
|
|
387
|
+
return is_user_logged_in();
|
|
388
|
+
},
|
|
389
|
+
) );
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
**Usage**:
|
|
393
|
+
```bash
|
|
394
|
+
# Get token
|
|
395
|
+
curl -X POST https://example.com/wp-json/jwt-auth/v1/token \
|
|
396
|
+
-d "username=admin&password=password"
|
|
397
|
+
|
|
398
|
+
# Use token
|
|
399
|
+
curl -X GET https://example.com/wp-json/my-plugin/v1/secure-data \
|
|
400
|
+
-H "Authorization: Bearer YOUR_TOKEN"
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Custom API Key Authentication
|
|
404
|
+
|
|
405
|
+
```php
|
|
406
|
+
/**
|
|
407
|
+
* Validate API key
|
|
408
|
+
*/
|
|
409
|
+
function validate_api_key( $request ) {
|
|
410
|
+
$api_key = $request->get_header( 'X-API-Key' );
|
|
411
|
+
|
|
412
|
+
if ( ! $api_key ) {
|
|
413
|
+
return false;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
$valid_keys = get_option( 'my_plugin_api_keys', array() );
|
|
417
|
+
|
|
418
|
+
return in_array( $api_key, $valid_keys, true );
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
register_rest_route( 'my-plugin/v1', '/data', array(
|
|
422
|
+
'methods' => 'GET',
|
|
423
|
+
'callback' => 'get_data',
|
|
424
|
+
'permission_callback' => 'validate_api_key',
|
|
425
|
+
) );
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
## Workflow 6: Modify Existing Endpoints
|
|
429
|
+
|
|
430
|
+
### Add Custom Fields to Posts
|
|
431
|
+
|
|
432
|
+
```php
|
|
433
|
+
/**
|
|
434
|
+
* Add custom field to post response
|
|
435
|
+
*/
|
|
436
|
+
function add_custom_field_to_post() {
|
|
437
|
+
register_rest_field( 'post', 'custom_field', array(
|
|
438
|
+
'get_callback' => function( $post ) {
|
|
439
|
+
return get_post_meta( $post['id'], '_custom_field', true );
|
|
440
|
+
},
|
|
441
|
+
'update_callback' => function( $value, $post ) {
|
|
442
|
+
return update_post_meta( $post->ID, '_custom_field', sanitize_text_field( $value ) );
|
|
443
|
+
},
|
|
444
|
+
'schema' => array(
|
|
445
|
+
'description' => __( 'Custom field', 'my-plugin' ),
|
|
446
|
+
'type' => 'string',
|
|
447
|
+
),
|
|
448
|
+
) );
|
|
449
|
+
}
|
|
450
|
+
add_action( 'rest_api_init', 'add_custom_field_to_post' );
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### Modify Response Data
|
|
454
|
+
|
|
455
|
+
```php
|
|
456
|
+
/**
|
|
457
|
+
* Modify post response
|
|
458
|
+
*/
|
|
459
|
+
function modify_post_response( $response, $post, $request ) {
|
|
460
|
+
$data = $response->get_data();
|
|
461
|
+
|
|
462
|
+
// Add custom data
|
|
463
|
+
$data['custom_data'] = array(
|
|
464
|
+
'views' => get_post_meta( $post->ID, 'views', true ),
|
|
465
|
+
'likes' => get_post_meta( $post->ID, 'likes', true ),
|
|
466
|
+
);
|
|
467
|
+
|
|
468
|
+
$response->set_data( $data );
|
|
469
|
+
|
|
470
|
+
return $response;
|
|
471
|
+
}
|
|
472
|
+
add_filter( 'rest_prepare_post', 'modify_post_response', 10, 3 );
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
## Best Practices
|
|
476
|
+
|
|
477
|
+
### DO
|
|
478
|
+
|
|
479
|
+
✅ Use proper HTTP status codes (200, 201, 400, 401, 404, 500)
|
|
480
|
+
✅ Validate all input
|
|
481
|
+
✅ Sanitize all data
|
|
482
|
+
✅ Use permission callbacks
|
|
483
|
+
✅ Return WP_Error for errors
|
|
484
|
+
✅ Use WP_REST_Response for success
|
|
485
|
+
✅ Version your API (v1, v2)
|
|
486
|
+
✅ Document your endpoints
|
|
487
|
+
✅ Use proper HTTP methods (GET, POST, PUT, DELETE)
|
|
488
|
+
✅ Add pagination for large datasets
|
|
489
|
+
|
|
490
|
+
### DON'T
|
|
491
|
+
|
|
492
|
+
❌ Trust user input
|
|
493
|
+
❌ Use `__return_true` for sensitive endpoints
|
|
494
|
+
❌ Forget error handling
|
|
495
|
+
❌ Return raw database data
|
|
496
|
+
❌ Ignore authentication
|
|
497
|
+
❌ Skip input validation
|
|
498
|
+
❌ Use deprecated functions
|
|
499
|
+
❌ Hardcode values
|
|
500
|
+
❌ Forget to sanitize output
|
|
501
|
+
|