פיתוח נקודות קצה מותאמות אישית של REST API לוורדפרס

כאשר ה-API הסטנדרטי של WordPress אינו מספיק לצרכים מורכבים של שאילתות עם פילטרים ואגרגציה, אנו מפתחים נקודות קצה מותאמות אישית שאוספות נתונים בבקשה אחת ומפחיתות עומס מיותר על השרת. הצוות שלנו מספק את הפרויקט במפתח מלא—מתכנון הארכיטקטורה ועד ליישום ולתמיכה מתמשכת.

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

אלה רק חלק מהסוגים הטכניים של אתרים שאנו עובדים איתם, ולכל אחד מהם יכולים להיות מאפיינים ופונקציונליות ספציפיים משלו, וכן ניתן להתאים אותם לצרכים ולמטרות הספציפיים של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
פיתוח נקודות קצה מותאמות אישית של REST API לוורדפרס
בינוני
~2-3 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אתר חברה B2B ADVANCE
    פיתוח אתר חברה B2B ADVANCE
    1501
  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1344
  • פיתוח אתר עבור BELFINGROUP
    פיתוח אתר עבור BELFINGROUP
    1052
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1306
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1049
  • פיתוח אתר לחברת FIXPER
    פיתוח אתר לחברת FIXPER
    1033

פיתוח נקודות קצה מותאמות אישית של REST API עבור WordPress

במשך יותר מ-5 שנים, ההתמחות שלנו היא פיתוח נקודות קצה מותאמות אישית של REST API עבור WordPress. אפליקציית מובייל או חזית SPA דורשות מ-WordPress לספק נתונים מצטברים עם סינון לפי טקסונומיות ושדות מטא. ה-/wp/v2/posts הסטנדרטי לא יכול להציג סכום כולל של הזמנות של לקוח לאורך תקופה או רשימת פרויקטים עם מיון משולב. מצב טיפוסי: ללא קאש, ב-5,000 בקשות בשעה, השרת קורס. מפתחים לעתים קרובות פונים לשאילתות SQL ישירות, מה שמוביל לבעיות N+1 ולפרצות אבטחה. הניסיון שלנו מראה שנקודת קצה מותאמת אישית מתוכננת היטב פותרת משימות אלה תוך 2–5 ימים, ומפחיתה את עומס מסד הנתונים פי 3–5. במאמר זה, נפרק תרחישים טיפוסיים, ערימת הטכנולוגיות והארכיטקטורה.

כדי להימנע מבעיות כאלה, אנו משתמשים בממשק אחיד לכל הנתונים: נקודת קצה מותאמת אישית של REST API מאגדת פוסטים, שדות מטא וטקסונומיות בבקשה אחת. זה מקצץ קריאות HTTP פי 5–10 ומפשט את תחזוקת החזית. לדוגמה, עבור פרויקט אחד (קטלוג עם 20,000 מוצרים) יישמנו את נקודת הקצה /my-plugin/v1/products עם סינון לפי קטגוריות, מחיר ומאפיינים — זמן התגובה ירד מ-4 ל-1 שנייה.

מגבלות ה-REST API הסטנדרטי של WordPress

המסלולים ברירת המחדל /wp/v2/posts ו-/wp/v2/pages מתאימים לקריאת פוסטים, אך לא עבור:

  • נתונים מצטברים — סכום כולל של הזמנות לקוח בחודש האחרון.
  • מסננים מורכבים — שילוב של שדות מטא וטקסונומיות עם מיון.
  • פעולות מותאמות אישית — יצירת הזמנה עם אימות מלאי ושליחת דוא"ל.

ללא נקודת קצה מותאמת אישית, הלקוח צריך לבצע בקשות מרובות או להשתמש בשאילתות SQL לא בטוחות. נקודת קצה מותאמת אישית עם קאש מאפשרת להפחית את זמן התגובה מ-4 ל-1 שנייה.

רישום נקודת קצה מותאמת אישית של REST API

רישום נקודת קצה עם שיטות GET ו-POST. פרטים נוספים ב-REST API Handbook.

add_action('rest_api_init', function () {
    register_rest_route('my-plugin/v1', '/projects', [
        [
            'methods' => WP_REST_Server::READABLE,
            'callback' => 'my_plugin_get_projects',
            'permission_callback' => '__return_true',
            'args' => [
                'category' => [
                    'type' => 'string',
                    'sanitize_callback' => 'sanitize_title',
                ],
                'tech' => [
                    'type' => 'array',
                    'items' => ['type' => 'string'],
                    'sanitize_callback' => function ($value) {
                        return array_map('sanitize_title', (array) $value);
                    },
                ],
                'per_page' => [
                    'type' => 'integer',
                    'default' => 12,
                    'minimum' => 1,
                    'maximum' => 100,
                    'sanitize_callback' => 'absint',
                ],
                'page' => [
                    'type' => 'integer',
                    'default' => 1,
                    'minimum' => 1,
                    'sanitize_callback' => 'absint',
                ],
            ],
        ],
        [
            'methods' => WP_REST_Server::CREATABLE,
            'callback' => 'my_plugin_create_project',
            'permission_callback' => function () {
                return current_user_can('edit_posts');
            },
        ],
    ]);
    register_rest_route('my-plugin/v1', '/projects/(?P<id>\d+)', [
        'methods' => WP_REST_Server::READABLE,
        'callback' => 'my_plugin_get_project',
        'permission_callback' => '__return_true',
        'args' => [
            'id' => [
                'validate_callback' => function ($param) {
                    return is_numeric($param) && $param > 0;
                },
            ],
        ],
    ]);
});"}

מטפל בקשות GET עם סינון טקסונומיה:

function my_plugin_get_projects(WP_REST_Request $request): WP_REST_Response|WP_Error {
    $per_page = $request->get_param('per_page');
    $page = $request->get_param('page');
    $category = $request->get_param('category');
    $techs = $request->get_param('tech');

    $query_args = [
        'post_type' => 'project',
        'post_status' => 'publish',
        'posts_per_page' => $per_page,
        'paged' => $page,
        'no_found_rows' => false,
    ];

    $tax_queries = [];

    if ($category) {
        $tax_queries[] = [
            'taxonomy' => 'project_category',
            'field' => 'slug',
            'terms' => $category,
        ];
    }

    if (!empty($techs)) {
        $tax_queries[] = [
            'taxonomy' => 'tech_stack',
            'field' => 'slug',
            'terms' => $techs,
            'operator' => 'IN',
        ];
    }

    if (!empty($tax_queries)) {
        $query_args['tax_query'] = array_merge(['relation' => 'AND'], $tax_queries);
    }

    $query = new WP_Query($query_args);

    $projects = [];
    foreach ($query->posts as $post) {
        $projects[] = my_plugin_format_project($post);
    }

    $response = new WP_REST_Response($projects, 200);
    $response->header('X-WP-Total', $query->found_posts);
    $response->header('X-WP-TotalPages', $query->max_num_pages);

    return $response;
}

function my_plugin_format_project(WP_Post $post): array {
    $thumbnail_id = get_post_thumbnail_id($post->ID);
    $thumbnail_url = $thumbnail_id ? wp_get_attachment_image_url($thumbnail_id, 'large') : null;

    return [
        'id' => $post->ID,
        'slug' => $post->post_name,
        'title' => wp_strip_all_tags($post->post_title),
        'excerpt' => wp_strip_all_tags(get_the_excerpt($post)),
        'url' => get_permalink($post->ID),
        'thumbnail' => $thumbnail_url,
        'client' => get_post_meta($post->ID, 'project_client', true),
        'year' => (int) get_post_meta($post->ID, 'project_year', true),
        'categories' => wp_get_post_terms($post->ID, 'project_category', ['fields' => 'slugs']),
        'tech_stack' => wp_get_post_terms($post->ID, 'tech_stack', ['fields' => 'slugs']),
        'modified' => get_post_modified_time('c', true, $post),
    ];
}

מטפל POST עם אימות:

function my_plugin_create_project(WP_REST_Request $request): WP_REST_Response|WP_Error {
    $body = $request->get_json_params();
    if (empty($body['title'])) {
        return new WP_Error('missing_title', 'Заголовок обязателен', ['status' => 422]);
    }
    $post_id = wp_insert_post([
        'post_type' => 'project',
        'post_title' => sanitize_text_field($body['title']),
        'post_content' => wp_kses_post($body['content'] ?? ''),
        'post_status' => 'draft',
        'post_author' => get_current_user_id(),
    ], true);
    if (is_wp_error($post_id)) {
        return new WP_Error('insert_failed', $post_id->get_error_message(), ['status' => 500]);
    }
    if (!empty($body['client'])) {
        update_post_meta($post_id, 'project_client', sanitize_text_field($body['client']));
    }
    return new WP_REST_Response(
        ['id' => $post_id, 'url' => get_permalink($post_id)],
        201
    );
}

באיזו שיטת אימות לבחור?

עבור נקודות קצה GET, גישה ציבורית מספיקה. עבור יצירה או שינוי נתונים, יש צורך בבדיקת הרשאות. השווה בין השיטות:

שיטה תרחיש מורכבות
עוגיות (Cookie) בקשות מאזור הניהול אפס (מובנה)
סיסמאות יישום (Application Passwords) לקוחות חיצוניים בצד השרת נמוכה (תוסף רשמי)
JWT SPA, אפליקציות מובייל בינונית (תוסף או קוד מותאם אישית)

דוגמה ליירוט טוקן Bearer:

add_filter('rest_authentication_errors', function ($result) {
    if (!empty($result)) return $result;
    $auth_header = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
    if (!str_starts_with($auth_header, 'Bearer ')) {
        return $result;
    }
    $token = substr($auth_header, 7);
    $user_id = my_plugin_validate_jwt($token);
    if (is_wp_error($user_id)) {
        return $user_id;
    }
    wp_set_current_user($user_id);
    return true;
});

קאש לתגובות REST API

עבור בקשות כבדות, אנו משתמשים ב-Transients API. זה מפחית את עומס מסד הנתונים פי 3–5. דוגמה:

function my_plugin_get_projects(WP_REST_Request $request): WP_REST_Response {
    $cache_key = 'projects_' . md5(serialize($request->get_params()));
    $cached = get_transient($cache_key);
    if ($cached !== false) {
        $response = new WP_REST_Response($cached['data'], 200);
        $response->header('X-WP-Total', $cached['total']);
        $response->header('X-Cache', 'HIT');
        return $response;
    }
    // ... основная логика ...
    set_transient($cache_key, ['data' => $projects, 'total' => $total], 5 * MINUTE_IN_SECONDS);
    return $response;
}

add_action('save_post_project', function (int $post_id): void {
    global $wpdb;
    $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_projects_%'");
});

מה כלול בפיתוח נקודת קצה

שלב תוצאה
ניתוח קביעת נקודות קצה, סוגי נתונים, שיטות אימות
עיצוב סכמת מסלולים, מבנה תגובה, אימות פרמטרים
יישום כתיבת קוד, רישום מסלולים, מטפלים, קאש
בדיקות בדיקות יחידה (PHPUnit), בדיקות ידניות עם curl
פריסה פריסה לשרת ייצור, הגדרת ניטור
תיעוד סכמת OpenAPI או הוראות למפתחים

אנו מבטיחים עמידה בלוח הזמנים ומספקים תמיכה לאחר השחרור למשך 30 יום. צרו קשר להערכת הפרויקט שלכם — נייעץ בנושא ארכיטקטורה והיקף עבודה. הזמינו פיתוח נקודת קצה מותאמת אישית החל מ-$2,000 וקצרו את זמן האינטגרציה פי 2.

תהליך עבודה לפיתוח REST API מותאם אישית

  1. ביקורת — קביעת רשימת נקודות הקצה, שיטות (GET/POST/PUT/DELETE) ומבני תגובה.
  2. עיצוב סכמת מסלולים — גרסאות (add_action('rest_api_init', function () { register_rest_route('my-plugin/v1', '/projects', [ [ 'methods' => WP_REST_Server::READABLE, 'callback' => 'my_plugin_get_projects', 'permission_callback' => '__return_true', 'args' => [ 'category' => [ 'type' => 'string', 'sanitize_callback' => 'sanitize_title', ], 'tech' => [ 'type' => 'array', 'items' => ['type' => 'string'], 'sanitize_callback' => function ($value) { return array_map('sanitize_title', (array) $value); }, ], 'per_page' => [ 'type' => 'integer', 'default' => 12, 'minimum' => 1, 'maximum' => 100, 'sanitize_callback' => 'absint', ], 'page' => [ 'type' => 'integer', 'default' => 1, 'minimum' => 1, 'sanitize_callback' => 'absint', ], ], ], [ 'methods' => WP_REST_Server::CREATABLE, 'callback' => 'my_plugin_create_project', 'permission_callback' => function () { return current_user_can('edit_posts'); }, ], ]); register_rest_route('my-plugin/v1', '/projects/(?P<id>\d+)', [ 'methods' => WP_REST_Server::READABLE, 'callback' => 'my_plugin_get_project', 'permission_callback' => '__return_true', 'args' => [ 'id' => [ 'validate_callback' => function ($param) { return is_numeric($param) && $param > 0; }, ], ], ]); }); ), ארגומנטים, אימות פרמטרים.
  3. יישום מטפלים — כתיבת פונקציות callback, עיצוב נתונים, טיפול בשגיאות.
  4. הגדרת אימות — עוגיות (לניהול), סיסמאות יישום או JWT (ל-SPA/מובייל).
  5. קאש — Transients API או Redis, ביטול קאש בעת שינוי נתונים.
  6. בדיקות עם curl ו-PHPUnit, תיעוד בפורמט OpenAPI.
כיצד לנפות באגים ב-REST API מותאם אישית של WordPress?

השתמשו ב-function my_plugin_get_projects(WP_REST_Request $request): WP_REST_Response|WP_Error { $per_page = $request->get_param('per_page'); $page = $request->get_param('page'); $category = $request->get_param('category'); $techs = $request->get_param('tech'); $query_args = [ 'post_type' => 'project', 'post_status' => 'publish', 'posts_per_page' => $per_page, 'paged' => $page, 'no_found_rows' => false, ]; $tax_queries = []; if ($category) { $tax_queries[] = [ 'taxonomy' => 'project_category', 'field' => 'slug', 'terms' => $category, ]; } if (!empty($techs)) { $tax_queries[] = [ 'taxonomy' => 'tech_stack', 'field' => 'slug', 'terms' => $techs, 'operator' => 'IN', ]; } if (!empty($tax_queries)) { $query_args['tax_query'] = array_merge(['relation' => 'AND'], $tax_queries); } $query = new WP_Query($query_args); $projects = []; foreach ($query->posts as $post) { $projects[] = my_plugin_format_project($post); } $response = new WP_REST_Response($projects, 200); $response->header('X-WP-Total', $query->found_posts); $response->header('X-WP-TotalPages', $query->max_num_pages); return $response; } function my_plugin_format_project(WP_Post $post): array { $thumbnail_id = get_post_thumbnail_id($post->ID); $thumbnail_url = $thumbnail_id ? wp_get_attachment_image_url($thumbnail_id, 'large') : null; return [ 'id' => $post->ID, 'slug' => $post->post_name, 'title' => wp_strip_all_tags($post->post_title), 'excerpt' => wp_strip_all_tags(get_the_excerpt($post)), 'url' => get_permalink($post->ID), 'thumbnail' => $thumbnail_url, 'client' => get_post_meta($post->ID, 'project_client', true), 'year' => (int) get_post_meta($post->ID, 'project_year', true), 'categories' => wp_get_post_terms($post->ID, 'project_category', ['fields' => 'slugs']), 'tech_stack' => wp_get_post_terms($post->ID, 'tech_stack', ['fields' => 'slugs']), 'modified' => get_post_modified_time('c', true, $post), ]; } לבדיקות בסיסיות. הפעילו WP_DEBUG ו-WP_DEBUG_LOG ב-function my_plugin_create_project(WP_REST_Request $request): WP_REST_Response|WP_Error { $body = $request->get_json_params(); if (empty($body['title'])) { return new WP_Error('missing_title', 'Заголовок обязателен', ['status' => 422]); } $post_id = wp_insert_post([ 'post_type' => 'project', 'post_title' => sanitize_text_field($body['title']), 'post_content' => wp_kses_post($body['content'] ?? ''), 'post_status' => 'draft', 'post_author' => get_current_user_id(), ], true); if (is_wp_error($post_id)) { return new WP_Error('insert_failed', $post_id->get_error_message(), ['status' => 500]); } if (!empty($body['client'])) { update_post_meta($post_id, 'project_client', sanitize_text_field($body['client'])); } return new WP_REST_Response( ['id' => $post_id, 'url' => get_permalink($post_id)], 201 ); } — שגיאות PHP יופיעו ב-add_filter('rest_authentication_errors', function ($result) { if (!empty($result)) return $result; $auth_header = $_SERVER['HTTP_AUTHORIZATION'] ?? ''; if (!str_starts_with($auth_header, 'Bearer ')) { return $result; } $token = substr($auth_header, 7); $user_id = my_plugin_validate_jwt($token); if (is_wp_error($user_id)) { return $user_id; } wp_set_current_user($user_id); return true; }); . תוסף Query Monitor מציג את כל שאילתות ה-SQL שבוצעו במהלך קריאת נקודת הקצה ועוזר לזהות בעיות N+1. בדקו כותרות תגובה: function my_plugin_get_projects(WP_REST_Request $request): WP_REST_Response { $cache_key = 'projects_' . md5(serialize($request->get_params())); $cached = get_transient($cache_key); if ($cached !== false) { $response = new WP_REST_Response($cached['data'], 200); $response->header('X-WP-Total', $cached['total']); $response->header('X-Cache', 'HIT'); return $response; } // ... основная логика ... set_transient($cache_key, ['data' => $projects, 'total' => $total], 5 * MINUTE_IN_SECONDS); return $response; } add_action('save_post_project', function (int $post_id): void { global $wpdb; $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_projects_%'"); }); צריך להכיל את מספר הרשומות, /my-plugin/v1/. בשגיאת 401, ודאו ש-curl -X GET https://site.com/wp-json/my-plugin/v1/projects -v מחזיר wp-config.php או בודק כראוי הרשאות משתמש.

למה נקודות קצה מותאמות אישית עדיפות על שאילתות SQL ישירות

נקודת קצה מותאמת אישית של REST API מבטיחה אבטחה (סינון דרך WP API), קאש (Transients/Redis) וגרסאות. לפי הנתונים שלנו, מעבר לנקודות קצה מותאמות אישית מקצר את זמן האינטגרציה פי 2 ומפחית שגיאות ב-60%. אנו מפתחים פתרונות WordPress כבר יותר מ-5 שנים, עם יותר מ-30 פרויקטים הכוללים REST API מותאם אישית. קבלו ייעוץ — נעריך את הפרויקט שלכם ונציע את הפתרון האופטימלי. ההשקעה הטיפוסית נעה בין $1,500 ל-$5,000 לכל סט נקודות קצה, עם חיסכון ממוצע של $3,000 בחודש בעלויות שרת לאחר המעבר.