Рекомендации по проектированию и разработке прокси-сервера API

Вы просматриваете документацию по Apigee Edge.
Перейдите к документации по Apigee X.
Информация

Цель этого документа – предоставить набор стандартов и рекомендаций по разработке с помощью Apigee Edge. Здесь рассматриваются такие темы, как дизайн, программирование, использование правил, мониторинг и отладка. Информация была собрана на основе опыта разработчиков, которые работали с Apigee для реализации успешных программ API. Этот документ будет время от времени обновляться.

Помимо приведенных здесь рекомендаций, вам может быть полезен пост в сообществе Apigee Edge Antipatterns.

Стандарты разработки

Комментарии и документация

  • Добавьте встроенные комментарии в конфигурации ProxyEndpoint и TargetEndpoint. Комментарии повышают читабельность потока, особенно если названия файлов правил недостаточно описательны, чтобы понять, как работает поток.
  • Оставляйте полезные комментарии. Не оставляйте очевидные комментарии.
  • Используйте одинаковые отступы, пробелы, вертикальное выравнивание и т. д.

Кодирование в стиле фреймворка

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

  • Чтобы включить принцип DRY (не повторяйся), где это возможно, в конфигурациях правил и скриптах должны использоваться специализированные функции, которые можно использовать повторно. Например, специальное правило для извлечения параметров запроса из сообщений запроса может называться ExtractVariables.ExtractRequestParameters. Отдельное правило для добавления заголовков CORS можно назвать AssignMessage.SetCORSHeaders. Эти правила можно хранить в системе управления версиями и добавлять в каждый прокси-сервер API, которому нужно извлекать параметры или задавать заголовки технологии CORS. Это позволит избежать создания избыточных (и, следовательно, менее удобных в управлении) конфигураций.
  • Удалите из прокси API неиспользуемые правила и ресурсы (JavaScript, Java, XSLT и т. д.), особенно большие ресурсы, которые могут замедлить импорт и развертывание.

Правила именования

  • Атрибут Policy name и название XML-файла правил должны быть идентичными.
  • Атрибут Script и ServiceCallout правила name и название файла ресурса должны быть идентичными.
  • DisplayName должно точно описывать функцию правила для человека, который никогда раньше не работал с этим прокси-сервером API.
  • Называйте правила в соответствии с их функцией. Apigee рекомендует использовать единые правила именования для всех правил. Например, используйте короткие префиксы, за которыми следуют описательные слова, разделенные дефисами. Например, AM-xxx для правил AssignMessage. Также ознакомьтесь с информацией об инструменте apigeelint.
  • Используйте правильные расширения для файлов ресурсов: .js для JavaScript, .py для Python и .jar для JAR-файлов Java.
  • Названия переменных должны быть единообразными. Если вы выбрали стиль, например camelCase или under_score, используйте его во всем прокси-сервере API.
  • По возможности используйте префиксы переменных, чтобы упорядочивать их по назначению, например Consumer.username и Consumer.password.

Разработка прокси-сервера API

Первоначальные соображения по дизайну

  • Чтобы узнать больше о проектировании RESTful API, скачайте электронную книгу Web API Design: The Missing Link.
  • При создании прокси API по возможности используйте правила и функции Apigee Edge. Не кодируйте всю логику прокси-сервера в ресурсах JavaScript, Java или Python.
  • Создавайте процессы в логическом порядке. Несколько потоков, каждый с одним условием, предпочтительнее, чем несколько условных прикреплений к одному и тому же PreFlow и Postflow.
  • В качестве резервного варианта создайте прокси-сервер API по умолчанию с базовым путем ProxyEndpoint /. Его можно использовать, чтобы перенаправлять базовые запросы API на сайт разработчика, возвращать собственный ответ или выполнять другие действия, более полезные, чем возврат значения messaging.adaptors.http.flow.ApplicationNotFound по умолчанию.
  • Используйте ресурсы TargetServer, чтобы отделить конфигурации TargetEndpoint от конкретных URL и поддерживать продвижение в разных средах.
    Подробнее о балансировке нагрузки между внутренними серверами…
  • Если у вас несколько правил маршрутизации, создайте одно правило по умолчанию, то есть правило маршрутизации без условия. Убедитесь, что правило RouteRule по умолчанию определено последним в списке условных маршрутов. Правила маршрутизации оцениваются сверху вниз в ProxyEndpoint.
    Ознакомьтесь с документацией по конфигурации прокси-сервера API.
  • Размер пакета прокси-сервера API не должен превышать 15 МБ. В Apigee Edge для частного облака можно изменить ограничение размера, изменив свойство thrift_framed_transport_size_in_mb в следующих файлах: cassandra.yaml (в Cassandra) и conf/apigee/management-server/repository.properties.
  • Версии API. Рекомендации Apigee по управлению версиями API приведены в разделе "Версии" электронной книги Web API Design: The Missing Link.

Как включить CORS

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

CORS (совместное использование ресурсов между разными источниками) – это стандартный механизм, который позволяет вызовам JavaScript XMLHttpRequest (XHR), выполняемым на веб-странице, взаимодействовать с ресурсами из доменов, отличных от источника. CORS – это распространенное решение для правила ограничения источника, которое применяется во всех браузерах. Например, если вы выполните вызов XHR к Twitter API из кода JavaScript, выполняемого в браузере, вызов завершится неудачно. Это связано с тем, что домен, с которого страница загружается в браузер, отличается от домена, с которого загружается Twitter API. CORS позволяет серверам разрешать совместное использование ресурсов между разными источниками.

Информацию о том, как включить CORS в прокси-сервер API до публикации API, можно найти в статье Как добавить поддержку CORS в прокси-сервер API.

Размер полезной нагрузки сообщения

Чтобы избежать проблем с памятью в Edge, размер полезной нагрузки сообщения ограничен 10 МБ. При превышении этих размеров возникает ошибка protocol.http.TooBigBody.

Эта проблема также обсуждается в этой записи в сообществе Apigee.

Ниже приведены рекомендуемые стратегии обработки больших сообщений в Edge:

  • Запросы и ответы потока. Обратите внимание, что во время трансляции правила больше не имеют доступа к содержимому сообщений. Подробнее о запросах и ответах для потоковой передачи…
  • В Edge для частного облака версии 4.15.07 и более ранних версий измените файл обработчика сообщений http.properties, чтобы увеличить лимит в параметре HTTPResponse.body.buffer.limit. Обязательно протестируйте изменения, прежде чем внедрять их в рабочую среду.
  • В Edge для частного облака версии 4.16.01 и более поздних версий запросы с полезной нагрузкой должны включать заголовок Content-Length или, в случае потоковой передачи, заголовок Transfer-Encoding: chunked. При отправке запроса POST к прокси API с пустым содержимым необходимо передать заголовок Content-Length со значением 0.
  • В Edge для частного облака версии 4.16.01 и более поздних версий, чтобы изменить лимиты, задайте следующие свойства в файле /opt/apigee/router.properties или message-processor.properties. Подробнее о том, как задать ограничение на размер сообщения на маршрутизаторе или Message Processor…

    Для обоих свойств задано значение по умолчанию "10m", соответствующее 10 МБ:
    • conf_http_HTTPRequest.body.buffer.limit
    • conf_http_HTTPResponse.body.buffer.limit

Обработка ошибок

  • Используйте FaultRules для обработки всех ошибок. (Правила RaiseFault используются для остановки потока сообщений и перенаправления обработки в поток FaultRules.)
  • В потоке FaultRules используйте правила AssignMessage для создания ответа об ошибке, а не правила RaiseFault. Условное выполнение правил AssignMessage на основе типа возникшей ошибки.
  • Всегда включает обработчик ошибок по умолчанию, чтобы системные ошибки можно было сопоставить с форматами ответов на ошибки, заданными клиентом.
  • Если возможно, всегда приводите ответы об ошибках к стандартным форматам, доступным в вашей компании или проекте.
  • Используйте понятные сообщения об ошибках, которые предлагают решение проблемы.

Подробнее о том, как обрабатывать ошибки…

Ознакомьтесь с рекомендациями по проектированию ответов об ошибках в RESTful API.

Сохранение

Карты пар "ключ-значение"

  • Используйте карты "ключ-значение" только для небольших наборов данных. Они не предназначены для долгосрочного хранения данных.
  • При использовании карт "ключ-значение" учитывайте производительность, поскольку эта информация хранится в базе данных Cassandra.

Ознакомьтесь с правилами в отношении операций с картами пар "ключ-значение".

Кеширование ответов

  • Не заполняйте кеш ответов, если ответ не был получен или если запрос не является запросом GET. Операции создания, обновления и удаления не должны кешироваться. <SkipCachePopulation>response.status.code != 200 or request.verb != "GET"</SkipCachePopulation>
  • Заполните кеш контентом одного типа, например XML или JSON. После получения записи responseCache преобразуйте ее в нужный тип контента с помощью JSONtoXML или XMLToJSON. Это позволит избежать хранения двойных, тройных и других копий данных.
  • Убедитесь, что ключ кеша соответствует требованиям к кешированию. Во многих случаях в качестве уникального идентификатора можно использовать request.querystring.
  • Не включайте ключ API (client_id) в ключ кеша, если это не требуется. Чаще всего API, защищенные только ключом, возвращают одинаковые данные всем клиентам для определенного запроса. Хранить одно и то же значение для нескольких записей на основе ключа API неэффективно.
  • Чтобы избежать неактуальных данных, задайте подходящие интервалы истечения срока действия кеша.
  • По возможности настройте правило кеширования ответов, которое заполняет кеш, так, чтобы оно выполнялось в PostFlow ответа ProxyEndpoint как можно позже. Другими словами, он должен выполняться после перевода и медиации, в том числе медиации на основе JavaScript и преобразования между форматами JSON и XML. Кеширование данных медиации позволяет избежать снижения производительности, связанного с выполнением шага медиации каждый раз при получении кешированных данных.

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

  • Правила кеширования ответов для поиска записи в кеше должны применяться в PreFlow запроса ProxyEndpoint. Не реализуйте слишком много логики, кроме создания ключа кеша, до возврата записи кеша. В противном случае преимущества кеширования будут минимальными.
  • В целом, поиск в кеше ответов всегда должен быть как можно ближе к запросу клиента. В то же время кеш ответов должен быть как можно ближе к ответу клиента.
  • Если в прокси используется несколько разных правил кеширования ответов, следуйте приведенным ниже рекомендациям, чтобы обеспечить дискретное поведение для каждого из них:
    • Выполнять каждое правило на основе взаимоисключающих условий. Это позволит гарантировать, что будет выполнено только одно из нескольких правил кеширования ответов.
    • Для каждого правила кеширования ответов определите разные ресурсы кеша. Ресурс кеша указывается в элементе <CacheResource> политики.

Ознакомьтесь с правилами кеширования ответов.

Правила и собственный код

Правила или пользовательский код?

  • В первую очередь используйте встроенные правила (если это возможно). Правила Apigee надежны, оптимизированы и поддерживаются. Например, используйте стандартные правила AssignMessage и ExtractVariables вместо JavaScript (если это возможно), чтобы создавать полезные нагрузки, извлекать информацию из полезных нагрузок (XPath, JSONPath) и т. д.
  • Предпочтительнее использовать JavaScript, а не Python или Java. Однако если производительность является основным требованием, то лучше использовать Java, а не JavaScript.

JavaScript

  • Используйте JavaScript, если он более интуитивно понятен, чем правила Apigee (например, при настройке target.url для множества разных комбинаций URI).
  • Сложный синтаксический анализ полезной нагрузки, например итерация по объекту JSON и кодирование/декодирование Base64.
  • Правила JavaScript предусматривают ограничение по времени, поэтому бесконечные циклы блокируются.
  • Всегда используйте шаги JavaScript и помещайте файлы в папку ресурсов jsc. Тип правил JavaScript предварительно компилирует код во время развертывания.

Подробнее о том, как программировать прокси API с помощью JavaScript…

Java

  • Используйте Java, если производительность является приоритетом или если логику нельзя реализовать на JavaScript.
  • Включите отслеживание исходных файлов Java в исходном коде.

Подробнее о том, как использовать Java в прокси API, рассказывается в статьях Как преобразовать ответ в верхний регистр с помощью вызова Java и Правила вызова Java.

Python

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

Выноски скриптов (Java, JavaScript, Python)

  • Используйте глобальный блок try/catch или его эквивалент.
  • Создавайте значимые исключения и правильно обрабатывайте их для использования в ответах об ошибках.
  • Вызывайте и перехватывайте исключения на ранних этапах. Не используйте глобальный блок try/catch для обработки всех исключений.
  • При необходимости выполняйте проверки на значения null и undefined. Например, это может понадобиться при получении необязательных переменных процесса.
  • Не создавайте HTTP/S-запросы внутри вызова скрипта. Вместо этого используйте правило Apigee ServiceCallout, поскольку оно корректно обрабатывает подключения.

JavaScript

  • JavaScript на платформе API поддерживает XML с помощью E4X.

Подробнее об объектной модели JavaScript…

Java

  • При доступе к полезной нагрузке сообщений старайтесь использовать context.getMessage() вместо context.getResponseMessage или context.getRequestMessage. Это гарантирует, что код сможет получить полезную нагрузку как в запросе, так и в ответе.
  • Импортируйте библиотеки в организацию или среду Apigee Edge и не включайте их в JAR-файл. Это уменьшит размер пакета и позволит другим JAR-файлам получить доступ к тому же репозиторию библиотеки.
  • Импортируйте JAR-файлы с помощью API ресурсов Apigee, а не добавляйте их в папку ресурсов прокси API. Это сократит время развертывания и позволит нескольким прокси API ссылаться на одни и те же JAR-файлы. Ещё одно преимущество – изоляция загрузчика классов.
  • Не используйте Java для обработки ресурсов (например, для создания пулов потоков и управления ими).

Подробнее о том, как преобразовать ответ в верхний регистр с помощью вызова Java…

Python

  • Создавайте значимые исключения и правильно обрабатывайте их для использования в ответах об ошибках Apigee.

Подробнее о правиле "Скрипт Python"…

ServiceCallouts

  • Существует множество допустимых вариантов использования цепочки прокси-серверов, когда вы используете вызов сервиса в одном прокси-сервере API для вызова другого прокси-сервера API. Если вы используете цепочку прокси, избегайте бесконечных рекурсивных вызовов одного и того же прокси-сервера API.

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

  • Создайте запрос ServiceCallout с помощью правила AssignMessage и заполните объект запроса в переменной сообщения. (включая настройку полезной нагрузки запроса, пути и метода).
  • URL, настроенный в правиле, должен содержать спецификацию протокола. Это означает, что часть URL, относящаяся к протоколу, например https://, не может быть указана с помощью переменной. Кроме того, необходимо использовать отдельные переменные для доменной части URL и для остальной части URL. Пример: https://{domain}/{path}
  • Сохраните объект ответа для ServiceCallout в отдельной переменной сообщения. Затем вы можете проанализировать переменную сообщения и сохранить исходную полезную нагрузку сообщения для использования в других правилах.

Ознакомьтесь с правилами в отношении описаний услуг.

Как получить доступ к объектам

Правила AccessEntity

  • Чтобы повысить производительность, ищите приложения по uuid, а не по названию.

Ознакомьтесь с правилами доступа к объектам.

Журналы

  • Используйте общую политику syslog для разных пакетов и в рамках одного пакета. Это позволит поддерживать единый формат журнала.

Ознакомьтесь с правилами MessageLogging.

Мониторинг

Клиентам облачной версии не нужно проверять отдельные компоненты Apigee Edge (маршрутизаторы, процессоры сообщений и т. д.). Глобальная команда по операциям Apigee тщательно отслеживает все компоненты, а также проверяет работоспособность API, учитывая запросы клиентов.

Apigee Analytics

Аналитика может отслеживать некритические ошибки API, поскольку измеряет процент ошибок.

Подробнее о сводках Аналитики…

Трассировка

Инструмент трассировки в интерфейсе управления API Edge полезен для отладки проблем с API во время выполнения, разработки или эксплуатации API.

Подробнее об использовании инструмента "Трассировка"…

Безопасность