Pull to refresh

Написание web-API к своей системе

Reading time 3 min
Views 24K
Добрый день, %username%!
За последний год столкнулся с несколькими задачами по написанию SOAP/REST API к различным сервисам и вывел для себя боле-менее удобную модель. Я не претендую на фундаментальное исследование, просто хочу поделиться опытом наступания на грабли.

Для начала общие требования к default API:
  • возможность расширения
  • удобный стандартизированный формат запросов
  • удобный стандартизированный формат ответов
  • достаточный уровень безопасности
  • возврат ошибок выполнения запроса


Клиентом нашего API может быть как сервер (PHP/Perl/Python etс), так и UI (JS). Механизмы авторизации при этом будут несколько отличаться, но все остальное лучше стандартизировать.
После долгих тестов в реальной жизни я предпочел JSON. Я не имею ничего против XML, но очень часто приходится пользоваться функционалом API из JavaScript — почему бы и не использовать нативный формат?

Структура запроса к серверу выглядит примерно так:
cmd="имя команды"&data="JSON объект"&sig="сигнатура запроса, используемая для аутентификации и проверки целостности запроса"
По порядку:
cmd — ограниченный набор команд, обеспечивающий функционал. Например, auth, profile, edit, view и так далее — в зависимости от ваших потребностей. Этот параметр не передается в JSONе, чтобы не парсить JSON в случае отсутствия такой команды.
data — передаваемая информация в JSONе.
sig — сигнатура, обеспечивающая проверку правильности запроса и авторизацию. Например, при запросе сервер-сервер я использую следующий алгоритм: md5(cmd+secret+data), где secret — информация, известная обоим серверам (и нашему, и серверу клиента), но неизвестная более никому.
При запросе сервер-клиент (AJAX-JavaScript) приходится использовать менее секурный вариант — secret хранится в cookie и меняется каждый сеанс.

Ответ:
{
status: "ok или error - удачность выполнения запроса"
response: "возвращаемые данные"
error: "код ошибки или 0 в случае удачи"
}

Я думаю, тут пояснений не нужно.
Приближаемся к реализации. Рассмотрим алгоритм работы серверной части:
  1. проверить, существует ли команда, соответствующая параметру cmd
  2. если да — то поверить сигнатуру(sig) — на этом этапе мы отметаем большую часть неумелых атак, еще не загружая сервер
  3. загрузить соответствующий модуль, реализующий функционал и передать ему данные
  4. модуль делает свою работу — мы ему тут не нужны
  5. сформировать ответ с результатами работы модуля или кодом ошибки и вернуть его клиенту

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

Посмотрим на классы, которые сформировались за несколько подобных систем и теперь мигрируют из одной в другую:
  1. Manager — проверяет существование команды и правильность сигнатуры, проверяет правильность данных на входе и отправляет ошибки о не корректных данных
  2. Module — каждый объект этого класса описывает определенный модуль. Описание состоит из названия, списка необходимых для работы файлов, которые будут включены при запуске модуля, список параметров, которые он будет брать у объекта Registry, список параметров, без которых его не запускать, а сразу выдавать ошибку
  3. Registry — синглтон, в честь одноименного шаблона — заворачивает в себя входящие данные под чутким руководством объекта Manager. Позже именно к нему будут обращаться модули за данными
  4. Response — синглтон, строит ответ из данных, полученных от модуля. Именно в нем мы кодируем ответ в нужный нам формат (JSON в данном случае)
  5. Класс-обертка к БД по вкусу

Таким образом, модули можно писать хоть процедурные — все данные они берут из объекта Registry и возвращают в объект Response.

Стандартные модули, которые встречаются почти в каждой системе:
  • auth — открытие соединения с API
  • log_out — собственно закрытие соединения
  • user — вывод информации о пользователе
  • view — просмотр одной записи
  • list — просмотр списка записей
  • add — добавление записи
  • edit — редактирование записи
  • del — удаление записи

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

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

UPD: это не описание создания REST или не дай бог SOAP API. Это то, что вылилось из эксплуатации нескольких систем и является более производительным и простым решением. Если вам надо книжный REST — читайте Фраулера, там без меня все описано.
Tags:
Hubs:
+58
Comments 180
Comments Comments 180

Articles