Пример за REST API с PHP от нулата, без употреба на фреймуърк

api_diagram2

Преди да започна с примера, ще се опитам с мой (прости) думи да обясня какво се има предвид под REST API и за какво в крайна сметка се използва.

Какво е REST API

REST съкратено от Representational State Transfer – стил софтуерна архитектура за реализация на уеб услуги. Най-общо, това е концепция за заделяне на системен ресурс, който се променя въз основа на взаимодействието между клиент и сървър. В общи линии клиентът прави заявка, сървърът я обработва и връща отговор, съответстващ на заявката. Архитектурният стил на REST прилага 6 условия и когато дадено приложение покрива тези условия, то може да се нарече RESTful.

API (съкратено от Application Programming Interface) е набор от правила, които позволяват на една част от софтуерна програма да комуникира с друга част. Повече подробности са достъпни в wikipedia.

RESTful API е уеб приложение, което базирано на принципите на REST и HTTP. Често се използва с медийния тип JSON, но работи и с останалите типове. Базовите операции, които поддържа, са GET, PUT, POST и DELETE.

За какво най-общо се използва REST API

Пример 1: REST API

Имаме онлайн бизнес и искаме да проверим посещенията за даден месец. Един от вариантите е да ползваме API функциите на Google Developers, чрез които ще получим достъп до данните в Google Analytics. По този начин няма да бъде необходимо всеки път да зареждаме цялото приложение на Google Analytics, а ще можем да следим това, което ни интересува от собственото табло (dashboard) на нашето приложение.

Пример 2: RESTful API

Например, работим с уеб базиран библиотечен софтуер за управляване и проследяване на библиотечни единици и читатели на библиотека. Приложението има база данни с пълно библиографско описание на книги, с които разполага библиотеката. Софтуерът е качен на lib.example.com. Чрез RESTful API архитектурата приложението може да предостави достъп до данните на уеб сайта на библиотеката и същевременно до уеб сайтовете на училищата.

По този начин се получава, че две или повече приложения ползват една обща база от данни. В примера уеб сайтът на библиотеката спазва правилата за ползване на библиотечния софтуер, за да работи с данните на библиотечното приложение.

Условие и реализиране на задачата

Да си представи че имаме следната задача – клиент прави заявка за извеждане на статистика с посетителите на собствения си уеб сайт. Тези данни се изтеглят от различна база данни/приложение. Резултатът, който би трябва да получи клиентът, е посетителите за даден месец.

Примерен отговор:

{„error“: false, „message“: „“, data: [„Google Analytics“ : 150, „Positive Guys“: 5000]}

Задължителни изисквания

  • Да поддържа няколко източника. Лесно да се добавят нови източници.
  • Трябва да може да се справя с голямо разнообрази от методи.
  • Да прехваща грешно въведени данни.
  • Да връща JSON формат.
  • Да не се използва фреймуърк.

Този проект ще бъде разгледан чисто структурно, а не като цяло завършено приложение.

Решение

Първото, което ще направим, е да създадем базата данни или приложението, от което ще получаваме данните. В нашия случай то ще бъде PHP уеб страница, която ще изпраща масив от данни на нашия клиент.

За улеснение ще разделим проекта на две части, като в първата част ще разработим API приложението, а във втората – клиента.

Изграждане на база данни/приложение за получаване на статистиката

Създаваме API приложението в папка api_project и в нея създаваме index.php файл, в който ще се съдържа цялото приложение.

<?php
header("Content-Type:application/json");
if (!empty($_GET['month']))
{
    $numberOfMonth = $_GET['month'];
    $monthData = get_month($numberOfMonth);
    if (empty($monthData))
    {
        response(TRUE, "Out of Range", NULL);
    } else
    {
        response(FALSE, "", $monthData);
    }
} else
{
    response(400, "Invalid Request", NULL);
}
function response($status, $status_message, $data)
{
    header("HTTP/1.1 " . $status);
    $response['error'] = $status;
    $response['message'] = $status_message;
    $response['data'] = $data;
    $json_response = json_encode($response);
    echo $json_response;
}
function get_month($numberOfMonth)
{
    $monthlyStats = [
        "january" => ['Google Analytics' => 50, 'Positive Guys' => 500],
        "february" => ['Google Analytics' => 150, 'Positive Guys' => 5000],
    ];
    foreach ($monthlyStats as $mKey => $curentMonth)
    {
        if ($mKey == $numberOfMonth)
        {
            return $curentMonth;
            break;
        }
    }
}

След това е необходимо да създадем .htaccess файл в същата папка и да опишем правилата, по които да се ръководи.

Най-общо разрешаваме пренаписването и достъпването на index.php с променлива month.

RewriteEngine On    

RewriteRule ^([a-zA-Z_-]*)\.(html|json|xml)?$ index.php?month=$1 [NC,L]

Така завършва първа част от проекта, като в резултат на това вече е налична „базата данни/приложението“, от където клиентът ще достъпва информация за посетителите на уеб сайта.

Изграждане на клиентска част, в която ще се получават статистическите данни

Клиентската част ще създадем в папка api_client с файл index.php. Съдържанието на файла ще представлява html страница, която ще е с много семпъл интерфейс, чрез който клиентът ще прави рикуест месец и ще респонсва месечната статистика.


<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">

        <title></title>
    </head>
    <body>

        <h2>Monthly website statistics</h2>
        <form  action="" method="POST">
    
                <select name="month">
                    <option>Select Month</option>
                    <option value="january">January</option>
                    <option value="february">February</option>
                </select>
            </div>
            <button type="submit" name="submit">Submit</button>
        </form>
        <p>&nbsp;</p>
        <h3>
            <?php
            if (isset($_POST['submit']))
            {
                $name = $_POST['month'];
                $url = "http://localhost/api_project/?month=" . $name;
                $client = curl_init($url);
                curl_setopt($client, CURLOPT_RETURNTRANSFER, true);
                $response = curl_exec($client);
                $result = json_decode($response);
                if (!empty($result))
                {
                    echo $result->error;
                    echo $result->message;
                    foreach ($result->data as $key => $value)
                    {
                        echo $key . ': ' . $value . '<br>';
                    }
                }
            }
            ?>
        </h3>

    </body>
</html>

След като всичко е готово, можем да тестваме приложението директно през браузъра на http://localhost/api_client/ и от там през формата. Другият вариант  е през Postman, като направим рикуест на localhost/api_project?month=february.

screenshot postman
в случай когато подадем грешни данни

 

 

Ще отбележа, че в този пример не са приложени най-добри практики, защото целта е да се придобие обща представа за архитектурата REST API с PHP.