WordPress & JS

WordPress & JS

При разработке приложений на JavaScript, будь то чиcтый js или один из многочисленных фреймворков, рано или поздно возникает вопрос — как наладить общение с базой данных?

Варианты ответа вроде элементарны:

  • используем Node.js для разработки серверной части приложения (это ведь тоже JavaScript);
  • используем Python / Django для той же цели;
  • используем классический вариант — PHP.

Хорошо, когда вы работаете в команде и есть back-end разработчик, который все эти вопросы возьмёт на себя, вам же выдаст инструкцию — куда какие запросы посылать, чтобы получить данные из базы.

Но иногда приходится косплеить fullstack-разработчика. Данная статья как раз об этом.

Здесь мы не будем рассматривать очевидные и популярные варианты (Node.js и Python), а сделаем своё собственное API на PHP, и поможет нам в этом старый-добрый WordPress.

В этой статье мы в общем виде и кратко, но ёмко рассмотрим, как можно организовать этакий middle-end. Здесь мы не будем рассматривать подробно разработку на javascript, только в общем виде покажем части некоего абстрактного приложения.

Перед самым началом

Прежде всего установим сам WordPress и создадим в нем простую тему, в которой и будет размещено наше приложение. Для нашего сегодняшнего урока я разработал специальную техническую тему, с помощью которой мы будем учиться работать с API. Скачать её можно по этой ссылке.

Также рекомендую — если вдруг у вас ещё в арсенале не присутствует — классную программу Postman, с помощью которой очень удобно отлаживать работу API.

Подготовка

Для начала разберёмся, что за приложение мы будем создавать — это поможет нам разобраться, какую именно информацию мы будем запрашивать из базы данных через WordPress.

Допустим, мы решили сделать приложение, которое имеет следующий функционал:

  • Авторизует пользователя — просто проверим, есть ли такой пользователь вообще. Регистрацию / восстановление мы вынесенем за рамки статьи, ибо по прочтении её такое вы сможете сделать уже самостоятельно (пусть будет домашкой).
  • Выводит авторизованному пользователю записи из базы данных.

Да, функционал очень простой, но не будем заморачиваться — у нас только учебный проект.

Итак, соответственно нам необходимо создать 2 энд-поинта, с помощью которых мы будем общаться со всей системой. Предлагаю их назвать кратко и лаконично — auth и post.

Забегая немного вперед, скажу что мы не будем пользоваться стандартными роутами WordPress для получения постов / записей, а сделаем все ручками.

Поехали!

Создаём роуты

Итак, мы договорились, что никаким образом не будем пользоваться стандартными средствами. Поэтому наш путь — в functions.php.

Нам необходимо создать новый action для для хука rest_api_init, который поможет нам создать новый маршрут для REST API:

// Энд-поинты приложенияadd_action('rest_api_init', function() {});

Как видите, к хуку ‘rest_api_init’ я добавил неименованную функцию, потому что у нас будет несколько маршрутов.

Авторизация пользователя

Начнем с базового функционала — посмотрим, есть ли у нас пользователь с такими учетными данными, и вернем ответ.

Напишем первую функцию маршрута и разберёмся, что же здесь написано.

// Маршрут авторизацииregister_rest_route('api/', 'auth/', [    'methods' => 'POST',    'callback' => 'auth',    'args' => array(        'login' => array(            'default' => $login        ),        'password' => array(            'default' => $pass        ),    ),]);

Первые два аргумента функции — это переменные адреса, по которому мы будем посылать запрос, что соответсвует такому адресу:

https://awesomesite.com/wp-json/api/auth

Далее, в параметре ‘methods’ мы определяем метод, с помощью которого мы данные отправим (POST).

Параметр ‘callback’ вызывает функцию, которая должна будет сработать при обращении на этот адрес.

И наконец параметр ‘args’ массивом указывает, какие ключи в этом запросе имеются. В нём мы указываем, что передаем на обработку логин пользователя и пароль.

Строим запрос от приложения

Первый роут готов, мы пока его оставим в таком виде и ненадолго отвлечёмся от WordPress и вернемся к нашему приложению — давайте посмотрим, как мы будем такой запрос строить.

Мы уже договорились, что подробно расписывать устройство JS-приложения не будем. Условимся, что в нашем приложении при первоначальной загрузке мы просим указать пользователя email и пароль. После того, как он эти данные ввёл, мы передаем эти данные примерно вот таким образом:

// Формируем объект из логина и пароля пользователяlet data = { login, password };// Адрес к энд-поинту авторизацииlet pathToAPI = 'https://awesomesite.com/wp-json/api/auth';// Запросfetch(pathToAPI, {    method: 'POST',    body: JSON.stringify(data),    headers: {        'content-type': 'application/json'    }    }).then((response) => {        return response.json();    }).then((data) => {        handle(data);    })

Мы написали простейший fetch-запрос (настолько простейший, что даже catch не указали), с помощью которого забросим данные по нужному нам адресу.

Здесь я вынес адрес в отдельную переменную, чтобы лучше воспринимался визуально. Рекомендую сделать функцию, которая будет в зависимости от нужной операции возвращать соответствующий адрес к API.

Также обратите внимание на headers — там обязательно нужно указать строку ‘content-type’: ‘application/json’, иначе магии не получится.

Обрабатываем запрос

Теперь, когда практически всё готово, мы возвращаемся в WordPress и напишем обработчик запроса по маршруту авторизации.

Сначала обдумаем схему работы функции (это полезно и экономит время). Вот мы отправили логин (email) и пароль серверу. Он их должен проверить и если такой пользователь существует, то вернуть нам его ID. А если нет — то сообщить, что введённые данные неправильные.

Используя стандартные функции WordPress, напишем такую функцию, её работу прокомментирую прям по ходу:

// Функция авторизации пользователяfunction auth($request) {    // Вытаскиваем в отдельные переменные ключи из запроса    $login = $request['login'];    $password = $request['password'];    // Проверяем пользователя    $auth = wp_authenticate($login, $password);    // Если ошибки нет    if (!is_wp_error($auth)) {        // Получаем id пользователя по email        $user = get_user_by('email', $login);        $user_ID = $user->data->ID;        // Формируем объект ответа        $response = array(            "id" => $user_ID        );        // В случае ошибки    } else {        $response = array(            "state" => 'error',            "response" => 'Неправильный логин / пароль'        );    }        // Возвращаем объект ответа    return $response;}

Итак, первый маршрут готов. Можем попробовать послать запрос от приложения к API и получить ответ в виде объекта, который уже нужным нам образом можно обработать.

Запрос данных

Перейдем ко второму маршруту — запросим список последних постов для пользователя. Аналогичным образом добавляем новый роут для API:

// Маршрут получения постовregister_rest_route('api/', 'posts/', [    'methods'  => 'POST',    'callback' => 'getPosts',    'args' => array(        'id' => array(            'default' => $id        ),        'type' => array(            'default' => $type        ),        'counts' => array(            'default' => $counts        ),    ),]);

Здесь повысим ставки — теперь нам нужно 3 параметра передать: это id пользователя (зачем-то мы его получали же!), тип поста и количество постов.

Теперь напишем саму функцию по обработке:

// Функция авторизации пользователяfunction getPosts($request) {    // Вытаскиваем в отдельные переменные ключи из запроса    $id = $request['id'];    $type = $request['type'];    $counts = $request['counts'];    // Если id передано    if($id) {        // Массив постов        $posts = array();        // Формируем запрос с помощью WP_Query        $query = new WP_Query(array(            'post_type' =>  $type,            'posts_per_page' => $counts        ));        // Пройдемся по массиву        while ($query->have_posts()) : $query->the_post();            // Получаем заголовок и описание            $title = esc_html(get_the_title());            $desc = get_the_excerpt();                    // Получаем ссылку на изображение (если оно есть)            if(has_post_thumbnail()) {                $thumb_id = get_post_thumbnail_id();                $thumb_cover_url = wp_get_attachment_image_src($thumb_id, full, true);                $imgUrl = $thumb_cover_url[0];            } else {                $imgUrl = 'null'; // Или можно указать ссылку на картинку-заглушку            }                    // Формируем объект поста            $post = array(                "title" => $title,                "description" => $desc,                "img" => $imgUrl            );            // Добавляем его в массив постов            array_push($posts, $post);        endwhile; wp_reset_postdata();        // Ответ - это массив постов        $response = $posts;    // В случае, если id передано    } else {        $response = array(            "state" => 'error',            "response" => 'Мне нужен ID'        );    }        // Возвращаем объект ответа    return $response;}

В результате мы получим массив объектов, который можно спокойно использовать в своём приложении.

У нас даже получилось лучше, чем в стандартной реализации, потому что отдаётся меньший по составу объект и кроме того, у нас уже имеется ссылка на изображение-обложку поста, а не только ID медиафайла.

Итого

Вот так с помощью WordPress и его немудрёного функционала можно достаточно быстро собрать себе API для приложения. Осталось только взять любимый фреймворк и наладить взаимодействие.

Надеюсь, что материал будет полезен для вас и поможет разрешить некоторые трудности.