Практическое руководство по написанию приложений REST

Практическое руководство по написанию приложений REST

20 декабря 2022 г.

Авторское право на изображение (c) 2022 Sergio Mijatovic n

Методология REST (передача репрезентативного состояния) в основном представляет собой способ создания веб-сервисов. Многое можно найти в Интернете об этом; например, см. эту статью. Я расскажу о том, как создать REST-приложение и API для него. n n Приложение будет посвящено покупкам: добавляйте клиентов и товары для продажи, затем создавайте, обновляйте и удаляйте заказы. Так что это простой API, но в нем есть большинство движущихся частей, которые вам могут понадобиться, и должно быть достаточно ясно, как его расширить.

Здесь я объясню основы; в конце статьи есть ссылка на полное приложение. Таким образом, вы получите самое необходимое с очень небольшим кодированием, что является отличным способом обучения. n n Вместо общей архитектурной схемы я начну так, как это сделал бы обычный человек: с создания прототипа с нуля.

Установка программного обеспечения инфраструктуры

n Вам понадобится-Apache или Nginx в качестве веб-сервера, PostgreSQL для базы данных и Vely для инфраструктуры приложений. п

Создать приложение

n Сначала я создам приложение. С этой целью я создам каталог, в котором будет мой исходный код: n

mkdir shopping
cd shopping

n, а затем-Vely-приложение, которое я удачно назвал "покупки": n

sudo vf -i -u $(whoami) shopping

n Опция "-i" говорит о создании приложения, а "-u" говорит о том, что оно будет принадлежать вам (то есть результат "whoami", который является вашим текущим пользователем ОС). п

Настройка базы данных

n Итак, приложение создано. Самый первый ресурс, который нужен моему REST-приложению, — это клиент. Без возможности представлять клиентов нет покупок. n n Создайте пользователя Postgres и базу данных: n

echo "create user $(whoami);
create database db_shopping with owner=$(whoami);
grant all on database db_shopping to $(whoami);
q
" | sudo -u postgres psql

n Это создаст пользователя PostgreSQL с тем же именем, что и у пользователя моей ОС Linux, и это нормально. Это упрощает вход в систему, и мне не понадобится пароль, потому что Postgres будет аутентифицировать меня через сеанс пользователя моей ОС. Первое, что мне нужно, это создать таблицу для клиентов. Вход в только что созданную базу данных: n

psql -d db_shopping

n и создайте таблицу клиентов: n

create table if not exists customers (firstName varchar(30), lastName varchar(30), customerID bigserial primary key);

n Это очень простая таблица с именем и фамилией клиента. «customerID» — это автоматически сгенерированный уникальный идентификатор, присвоенный клиенту. База данных сделает это за меня. Сделав это, нажмите Ctrl-D, чтобы выйти из оболочки базы данных. n n Чтобы иметь возможность использовать эту базу данных, мне нужно создать файл a-database_config_file. Каждая база данных должна иметь один. Файл конфигурации базы данных — это просто информация о соединении, предписанная поставщиком данной базы данных, в данном случае PostgreSQL. Как правило, он содержит информацию для входа в систему и идентификацию базы данных. В этом случае создайте файл конфигурации с именем «db_shopping» (вы можете назвать его как угодно, но обязательно используйте это имя в дальнейшем): n

echo "user=$(whoami) dbname=db_shopping"  > db_shopping

n Postgres потребуется имя пользователя моей операционной системы и имя базы данных. Это те же самые имена, которые я использовал при создании пользователя и базы данных Postgres выше. п

Создать веб-сервис

n Я могу сразу же найти хорошее применение тому, что у меня есть. Откройте редактор и создайте файл "add_customer.vely", скопируйте и вставьте его туда: n

#include "vely.h"

void add_customer()
{
    out-header use content-type "application/json"

    input-param first_name
    input-param last_name
    // Add a customer SQL
    run-query @db_shopping ="insert into customers (firstName, lastName) 
            values ('%s', '%s') returning customerID" output define customerID : 
            first_name, last_name
        @"<<p-out customerID>>"
    end-query
}

n Это очень просто, но делает многое. Это типичный веб-сервис, который вы будете писать часто. Предоставляются некоторые входные параметры, и некоторые SQL выполняются с этими данными. n n В этом случае есть два входных параметра: "first_name" и "last_name". Запись базы данных вставляется в таблицу «клиенты». «CustomerID», созданный для клиента, отображается в виде очень простого документа JSON. Вот и все функциональные возможности веб-службы на серверной части. п

n Как я могу использовать все это до сих пор?

Сначала сделайте заявку:

vv -q --db=postgres:db_shopping --path="/api/v1/shopping"

n "vv -q" является здесь основной частью, в нем говорится о создании кода C из исходных файлов Vely и создании Makefile, а затем создании собственного исполняемого файла для приложения. «--db=postgres:db_shopping» говорит, что вы используете базу данных Postgres, и это описано в конфигурационном файле «db_shopping». Наконец, "--path="/api/v1/shopping"" позволяет указать префикс пути URL. Подробнее об этом чуть позже. n n Теперь я могу использовать приложение, такое простое и маленькое, каким оно является на данный момент. Я добавлю к этому, но это самая важная часть, а все остальное будет как бы повторять то, что я уже сделал. Итак, то, что вы узнали до сих пор, — это то, что вам действительно нужно знать. п

Запустите приложение

n Есть несколько способов запустить это. n n Начнем с того, что программа Vely состоит из обработчиков запросов. Функция add_customer(), которую я написал, является обработчиком запросов. Обработчик запроса всегда находится в файле с тем же именем, поэтому он должен быть "add_customer.vely". Я могу написать в нем другие функции, но я должен иметь в нем «add_customer()», потому что фреймворк Vely будет вызывать его, когда его попросят выполнить запрос «add_customer». Обратите внимание, что запрос также может быть «добавить клиента», потому что Vely преобразует дефисы в символы подчеркивания, чтобы они были допустимыми идентификаторами C. n n Следует также помнить, что Vely обрабатывает HTTP-запросы. Поэтому независимо от того, как вы вызываете программу Vely, это должен быть HTTP-запрос. Это хорошо, потому что делает интерфейс единым и стандартным для всех. n n Хорошо, зная это, я готов запустить программу. п

Запуск как программы командной строки

n Первый способ запустить мое REST-приложение — просто вызвать его как программу командной строки. Это полезно, если программа предназначена для такой работы, а также в целях отладки: n

export REQUEST_METHOD=POST
export SCRIPT_NAME="/api/v1/shopping"
export PATH_INFO="/add-customer/first-name/Joe/last-name/Darling"
export QUERY_STRING=""
/var/lib/vv/bld/shopping/shopping

n Это полноценный HTTP-запрос POST. Метод запроса — «POST», потому что создается ресурс, и в данном случае это клиент. Для SCRIPT_NAME установлено значение, которое я указал в опции «--path» при создании приложения. Это может быть что угодно, но оно должно заканчиваться именем приложения (вспомните его указание в вызове "vf" при его создании). Это префикс приложения. По умолчанию это просто имя приложения, поэтому, если вы опустите «--path», это будет просто «/shopping». n n Далее следует PATH_INFO. Первый сегмент пути всегда является именем запроса. На данный момент я создал один обработчик запросов, поэтому он должен быть «add-customer» (или «add_customer» тоже подойдет). Затем идут любые входные параметры, за которыми сразу же следуют их значения. В этом случае есть два входных параметра (вспомните операторы «input-param» в вашем коде), поэтому «first_name» будет иметь значение «Joe», а «last_name» будет «Darling». Помните, что Vely переводит дефисы в подчеркивания в именах. n n QUERY_STRING будет иметь дополнительные фильтры для запроса, и они будут в форме: n

<param>=<value>&...

n Эти параметры получаются в вашем коде с помощью точно такой же инструкции input-param. На самом деле вы могли бы переписать приведенное выше как: n

...
export PATH_INFO="/add-customer"
export QUERY_STRING="first-name=Joe&last-name=Darling"
...

n Обратите внимание, что теперь параметры "first_name" и "last_name" теперь являются частью строки запроса. Или вы можете написать:

...
export PATH_INFO="/add-customer/first-name/Joe"
export QUERY_STRING="last-name=Darling"
...

n Теперь входные параметры разделены между путем и строкой запроса. n n Какую форму использовать, зависит от логики вашего запроса. Используйте QUERY_STRING для получения дополнительной информации и PATH_INFO для передачи логической иерархии ресурсов, необходимых для вашего запроса. Это может звучать немного нечетко, и это так. Это действительно зависит от вас, как лучше интерпретировать ваши собственные требования к приложению. n n В любом случае результатом вызова вышеприведенного исполняемого файла «shopping» будет идентификатор клиента, заключенный в кавычки, так что это действительный документ JSON. Например, это может быть так при первом запуске: n

"1"

н

Запуск в качестве веб-службы

n Приложения REST обычно запускаются в Интернете, так что это, вероятно, самый полезный способ. Для этого запустите ваше приложение как сервер приложений FastCGI. Вам не нужно ничего делать для создания такого сервера, Vely автоматически создает его, когда вы его создаете. Для этого используйте диспетчер процессов Vely FastCGI: n

vf --min-worker=3 --max-worker=10 shopping

n Это запустит серверный процесс (демон), который продолжит работу в фоновом режиме. Он создаст рабочие процессы для моего приложения для обработки запросов. В этом случае будет минимум 3 и максимум 10 процессов, в зависимости от нагрузки. Чем меньше запросов поступает, тем меньше процессов будет выполняться, и наоборот. Это адаптивный режим; см. vf для получения дополнительной информации. n n В любом случае, теперь мое приложение запущено и готово к использованию. Чтобы пользователи (или приложения) могли отправлять ему запросы, мне нужен обратный прокси-сервер, который может быть веб-сервером, таким как Apache или Nginx, но это может быть любой веб-сервер, поддерживающий FastCGI, как это делает большинство из них. n n Отправить запрос из веб-клиента

Чтобы протестировать веб-сервер, вот как это сделать. Если вы используете сервер Apache, убедитесь, что у вас включены модули «proxy» и «proxy_fcgi». Если вы используете Nginx, это уже сделано за вас по умолчанию, так что не беспокойтесь.

Для Apache я добавлю это в файл конфигурации (который будет "/etc/apache2/apache2.conf" или "/etc/httpd/conf/httpd.conf"): n

ProxyPass "/api/v1/shopping" unix:///var/lib/vv/shopping/sock/sock|fcgi://localhost/shopping

n Здесь я говорю Apache пересылать любой URL-адрес, начинающийся с "/api/v1/shopping" (помните, что это указано в параметре "--path" при создании приложения) в сокет, созданный Vely для применение. Тогда я просто перезапущу Apache. n n Для Nginx я бы отредактировал файл конфигурации (либо "/etc/nginx/sites-enabled/default", либо "/etc/nginx/nginx.conf") и добавил в раздел "server {}": n

location /api/v1/shopping { include /etc/nginx/fastcgi_params; fastcgi_pass  unix:///var/lib/vv/shopping/sock/sock; }

n Это делает то же самое, что и для Apache. Перезапустите Nginx, чтобы изменения вступили в силу. n n После этого я могу использовать эту HTML-форму для вызова моего REST API: n n

<form action="/api/v1/shopping/add-customer" method="POST">
   <label for="first_name">First name:</label><br>
   <input type="text" name="first_name" value=""><br>

   <label for="last_name">Last name:</label><br>
   <input type="text" name="last_name" value=""><br><br>

   <input type="submit" value="Submit">
</form>

n Я также могу использовать программу curl для вызова из командной строки. Обратите внимание, что в этом случае curl будет делать то же самое, что и браузер, то есть связываться с веб-сервером, который, в свою очередь, будет обращаться к моему серверу FastCGI, чтобы обслужить запрос: n

curl -X POST  "http://127.0.0.1/api/v1/shopping/add-customer/first-name/Joe/last-name/Darling"

n n Отправить запрос локально без веб-сервера

Это полезно, когда вы не хотите настраивать веб-сервер, но хотите протестировать его так же, как веб-сервер. Он работает, отправляя запрос вашему приложению из командной строки с помощью FastCGI_client. Это похоже на вызов программы из командной строки, но в отличие от выполнения программы, она фактически связывается с сервером приложений (работающим в фоновом режиме) с помощью сокета и получает от него ответ: n

export REQUEST_METHOD=POST
export SCRIPT_NAME="/api/v1/shopping"
export PATH_INFO="/add-customer/first-name/Joe/last-name/Darling"
export QUERY_STRING=""
cgi-fcgi -connect /var/lib/vv/shopping/sock/sock  /

n Ответ, конечно же, такой же, как и при вызове из командной строки — помните, что независимо от того, как вы запускаете приложение Vely, оно работает одинаково! Точно так же вы можете разделить параметры между PATH_INFO и QUERY_STRING. п

Заключение

n Я создал базовое приложение REST и вызывал свой REST API несколькими способами. n n Теперь, когда вы изучили основы, вы можете перейти к полному примеру REST, который будет продолжать добавляться к нему, имеет более полная функциональность (включая управление товарами и заказами), а также демонстрирует использование методов PUT, GET и DELETE. Не волнуйтесь, того, что вы узнали здесь, должно быть достаточно, чтобы сделать полный пример на одном дыхании.


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE