По вашему запросу ничего не найдено :(
Убедитесь, что запрос написан правильно, или посмотрите другие наши статьи:
img
Почитайте первую часть статьи. Первая проблема. Два роутера работают с одной областью OSPF, и каждый роутер имеет loopback интерфейс, объявленный в OSPF. Вот вывод таблиц маршрутизации: Как мы можем наблюдать, что роутер R1 узнал о сети 10.2.2.0/24 от роутера R2, но в таблице маршрутизации роутера R2 пусто. Что не так? Видно, что OSPF не включен на интерфейсе loopback0 роутера R1, так что же мы тогда объявляем в сетях? Похоже, мы объявляем сеть 10.10.1.0/24, но эта сеть не настроена ни на одном интерфейсе... Сеть 10.1.1.0/24 настроена на интерфейсе loopback0 роутера R1. Здесь вы видите неправильно введенную команду network. Удалим ее. R1(config)#router ospf 1 R1(config-router)#no network 10.10.1.1 0.0.0.0 area 0 R1(config-router)#network 10.1.1.0 0.0.0.255 area 0 Давайте удостоверимся, что команда network настроена правильно. Проблема устранена! Эта проблема может показаться не серьезной, но использование неправильных сетевых операторов - это то, что происходит постоянно. Особенно если мы используем меньшие подсети (например, /27 или /28 или аналогичные), люди склонны делать ошибки с обратными маскам. Итог урока: убедитесь, что вы настроили правильный сетевой адрес, обратную маску и область. Видео: протокол OSPF (Open Shortest Path First) за 8 минут Урок №2 Очередная возможная ситуация. Опять два роутера, но другая проблема. Вот таблицы маршрутизации: В очередной раз роутер R2 не увидел сеть 10.1.1.0/24. Что интересно, что роутер R1 не имеет сети 10.1.1.0/24 в своей таблице маршрутизации как непосредственно подключенной. Мы можем проверить, что роутер R1 использует правильную настройку команды network. Поскольку R1 даже не имеет сети в своей таблице маршрутизации, предположим, что проблема с интерфейсом. Кажется, кто-то забыл применить команду "no shutdown" на интерфейсе. R1(config)#interface loopback 0 R1(config-if)#no shutdown Давайте включим интерфейс. И теперь он появляется в таблице маршрутизации роутера R2. Итог урока: нельзя объявлять то, чего у тебя нет! Урок №3 Новый урок! Одна область, опять два роутера... мы хотели бы иметь "full connectivity", но не работает OSPF ... вот вывод таблиц маршрутизации: Роутер R1 не показывает никаких маршрутов OSPF, R2 показывает ... Необходимо выяснить, что не так: Быстро взглянем на роутер R2, чтобы убедиться, что он действительно объявляет правильную сеть(и). Да это так и есть. Вывод роутера R1 более интересен ... видно, что у него настроен distribute-list. В этом заключается наша проблема. Давайте удалим distribute-list. R1(config)#router ospf 1 R1(config-router)#no distribute-list 1 in Эта команда отключит его. Задача решена! Итог урока: знать о distribute-list, запрещающий объявление и / или установку префиксов в таблице маршрутизации. Урок №4 Взглянем на более сложные проблемы OSPF. На изображении выше мы имеем роутер R1 и роутер R2, но на этот раз мы имеем конфигурацию OSPF с несколькими областями. Вот конфигурация OSPF этих роутеров: Видно, что все сети были объявлены. Область 2 не связана напрямую с областью 0, поэтому была создана виртуальная связь. Роутер R1, однако, не увидел сеть 2.2.2.0/24 от роутера R2, но роутер R2 увидел сеть 1.1.1.0/24. Лучше всего начать с виртуальной линии здесь: Хм, это выглядит не очень хорошо. Виртуальная связь отключена. Обратите внимание на IP-адреса, которые мы видим здесь, это IP-адреса, настроенные на интерфейсах FastEthernet обоих маршрутизаторов. Всякий раз, когда мы настраиваем виртуальное соединение, нам нужно настроить идентификатор маршрутизатора OSPF другой стороны, а не IP-адрес другой стороны! Вот ошибка, так что давайте исправим ее. R1(config)#router ospf 1 R1(config-router)#no area 12 virtual-link 192.168.12.2 R1(config-router)#area 12 virtual-link 2.2.2.2 R2(config)#router ospf 1 R2(config-router)#no area 12 virtual-link 192.168.12.1 R2(config-router)#area 12 virtual-link 1.1.1.1 Вот так должна выглядеть virtual-link, настроенная между идентификаторами маршрутизаторов OSPF. Сразу после ввода правильных команд появятся данные сообщения в консоли. Запись OSPF для сети 2.2.2.0/24 появилась. Урок №5 Другая проблема. Те же роутеры, но появился "домен внешней маршрутизации". Это может быть другой протокол маршрутизации, такой как RIP или EIGRP, который мы будем распространять в OSPF. R2 перераспределяет сеть 2.2.2.0 / 24 в OSPF, но по какой-то причине она не отображается на R1. Чтобы было интересно, мы не будем просматривать конфигурацию OSPF на роутерах. Нет сети 2.2.2.0/24 на роутере R1, поэтому давайте изучим роутер R2. Как мы можем видеть, сеть находится в таблице маршрутизации роутера R2 как directly connected. Как мы можем видеть роутер R2 был настроен для перераспределения напрямую подключенных сетей. Это должно включать сеть 2.2.2.0/24 на интерфейса loopback0. Однако в базе данных OSPF пусто? Что может быть причиной этого? Возможно, вы помните правила различных типов областей OSPF. Давайте выясним, что это за область! Вот и объяснение, это stub area! Stub area не допускают LSA type 5 (внешние маршруты). Мы можем либо превратить эту область в normal area или NSSA. Давайте переведем в NSSA. R1(config)#router ospf 1 R1(config-router)#no area 12 stub R1(config-router)#area 12 nssa R2(config)#router ospf 1 R2(config-router)#no area 12 stub R2(config-router)#area 12 nssa Изменим тип области на обоих маршрутизаторах. Область NSSA допускает внешние маршруты с помощью LSA type 7. Наша сеть 2.2.2.0 / 24 теперь в базе данных OSPF маршрутизатора R2. Итог урока: Stub area не допускают внешних префиксов (LSA Type 5). Либо измените область на NSSA, либо прекратите перераспределение. Урок №6 Очередная проблема. Проблема default route OSPF. На рисунке имеются роутер R1 и роутер R2, и сеть 192.168.12.0 /24 объявленная в OSPF. Loopback интерфейсы роутера R2 не объявляется в OSPF, но мы используем default route, чтобы роутер R1 мог добраться до них. Здесь представлены конфигурации OSPF: Видно, что в выводе роутера R2 присутствует команда default-information originate для объявления default route. Увы, но мы не видим default route на роутере R1. Будем искать неполадки в настройке. Давайте проверим роутер R2: В таблице маршрутизации роутера R2 не виден default route. Чтобы OSPF объявлял default route, можно использовать два варианта: Убедитесь, что у вас есть default route в routing table (невозможно объявлять то, чего нет); Примените команду default-information originate always. Она объявит default route, даже если он не прописан. R2(config)#ip route 0.0.0.0 0.0.0.0 null 0 Выше первый метод решения проблемы. Мы создадим default route на роутере R2. Обычно указывается default route на ISP роутере, но сейчас другого роутера нет. Мы укажем default route для интерфейса null0, и он будет внесен в routing table. Правило работает! R2(config)#no ip route 0.0.0.0 0.0.0.0 null 0 R2(config)#router ospf 1 R2(config-router)#default-information originate always Итог урока: что бы объявить default route с помощью OSPF, вам нужно иметь default route в таблице маршрутизации или использовать ключевое слово "always". Урок №7 Немного сложнее проблема... те же два роутера , все в зоне 0. Вот настройки OSPF: Ничего особенного, все сети объявлены, и мы используем одну область. Увы ... таблицы маршрутизации пусты! По крайней мере, никакой отсутствует информация о OSPF ... Настройки network выглядят хорошо, так что это хороший момент вникнуть поглубже в OSPF LSDB. Давайте сначала проверим идентификаторы маршрутизатора OSPF: Здесь мы видим OSPF router ID. Если вы внимательно посмотрите на информацию выше, вы заметите что-то необычное. State full, но роутер R1 не выбрал DR / BDR, а роутер R2 выбрал роутер R1 в качестве BDR. Мы можем использовать команду show ip ospf database router для поиска информации от определенного соседа OSPF. Роутер R1 говорит нам, adv router is not-reachable. Это плохо. Роутер R2 также сообщает нам, что роутер R1 недоступен, и если вы посмотрите внимательно, то увидите, что он видит связь как point-to-point. Мы не видим этого в выводе на роутере R1. Это, вероятно, означает, что роутер R1 и роутер R2 используют другой тип сети OSPF, что приводит к разнице в LSDB. Это не позволит нашим роутерам устанавливать маршруты в таблицу маршрутизации! Теперь мы кое-что выяснили. Тип сети отличается ... широковещательная передача на роутере R2 и точка-точка на роутере R1. Нам действительно удалось установить соседство OSPF с этим, но возникает разница в LSDB. Произведем исправления. R1(config)#interface fa0/0 R1(config-if)#ip ospf network broadcast Изменение типа сети на роутере R1 сделает свое дело. Наконец "О" появляется в наших таблицах маршрутизации...проблема решена! Итог урока: убедитесь, что вы используете правильный тип сети OSPF на обоих роутерах. Урок №8 Очередная внештатная ситуация. OSPF настроено между роутерами R1 и R2, но не все сети объявлены. Loopback интерфейсы роутера R2 перераспределяются в OSPF. Вот настройки обоих роутеров: Мы наблюдаем команду redistribute connected на роутере R2, которая должна перераспределить сети на интерфейсах обратной связи в OSPF. Однако здесь ничего нет ... Обычно было бы неплохо проверить, есть ли distribute list или нет. Ключ к решению этой проблемы - эта команда. Если вы наберете redistribute connected OSPF будет распространять только classful networks. R2(config)#router ospf 1 R2(config-router)#redistribute connected subnets Нам нужно добавить параметр "subnets", позволяющий заставить его выполнять redistribute subnet основных сетей. Ну вот, наша маршрутная таблица заполнена. Итог урока: добавьте параметр " subnets " при использовании перераспределения или перераспределяются только classful networks.
img
Привет, друг! В марте 2017 года на сайте разработчика FreePBX Distro появился новый дистрибутив, который включает в себя FreePBX 14 версии, Linux 7.3 и само ядро обработки телефонных вызовов – Asterisk (11, 13 и 14 версии). Отметим, что на момент написания статьи релиз проходит полномасштабное тестирование и доступен в формате «релиз - кандидата», или просто RC (Release Candidate). В статье рассмотрим процесс установки дистрибутива RC 1 SNG7-FPBX-64bit-1703-1 и проведем беглый обзор новых «фишек». Установка Установку мы будем производить на виртуальной машине в среде виртуализации Hyper-V. После загрузки .iso дистрибутива с сайта разработчика, сравниваем его MD5 - сумму и подключаем его к виртуальному приводу и включаем виртуальную машину: Выбираем рекомендуемую опцию инсталляции и нажимаем Enter: Выбираем опцию вывод детализации информации об установке через VGA и нажимаем Enter: Оставляем селектор на стандартной установке и нажимаем Enter: Начинается процесс установки, который занимает примерно 10-20 минут. По окончанию установки мы увидим соответствующее сообщение. Нажимаем Reboot: Готово. Переходим к изучению нового интерфейса. Новый интерфейс FreePBX 14 Из нововведений сразу в глаза бросается виджет Live Network Usage, который показывает загрузку виду Tx/Rx (передача/прием) на сетевом интерфейсе: Пробежимся по вкладке Admin. Мы нашли дополнительный раздел Updates, в котором теперь можно планировать автоматическое обновление системы и модулей: Во вкладке Applications появился модуль Calendar, который позволяет производить интеграцию с календарями (Outlook, iCal, CalDAV и обычный локальный календарь): Важнейшей особенностью нового интерфейса является UCP (User Control Panel) 14 версии, в котором полностью переделана графическая компонента, визуализация информации, добавлена гибкая система настройки «дашбордов» и настройки виджетов: Мы продолжим следить за новым релизом и держать вас в курсе :)
img
REST API – один из самых распространенных типов доступных веб-сервисов, но проектировать их сложно. Они позволяют разным клиентам, включая браузер, настольные приложения, мобильные приложения и практически любое устройство с подключением к Интернету, взаимодействовать с сервером. Именно поэтому очень важно правильно проектировать REST API, чтобы в будущем не было проблем. Создание API с нуля может оказать непосильной задачей из-за большого количества вещей, которые необходимо учесть – от базовой безопасности до использования правильных методов HTTP, реализации аутентификации, определения того, какие запросы и ответы среди многих других принимаются и возвращаются. В этой статье я очень постарался сжать материал в 15 пунктов с важными рекомендациями, которые позволят создать хороший API. Все рекомендации никак не зависят от языка, поэтому потенциально применимы к любой платформе или технологии. 1. Обязательно используйте имена существительные в названиях путях к конечным точкам Вам всегда следует использовать имена существительные, которые обозначают объект, который вы извлекаете или которым вы манипулируете. В качестве имени пути всегда предпочтительнее использовать множественное число. Избегайте использования глаголов в названиях путях к конечным точкам, потому что наш метод HTTP-запроса уже является глаголом и по сути не добавляет никакой новой информации. Действие должно быть произведено с помощью методов HTTP-запроса. Наиболее распространенными являются методы GET, POST, PATCH, PUT и DELETE. GET извлекает ресурсы POST отправляет новые данные на сервер PUT/PATCH модифицируют уже существующие данные DELETE удаляет данные Глаголы сопоставляются с функциями CRUD (Create, read, update и delete). Помня об этих принципах, мы должны создавать маршруты типа GET /books для получения списка книг, а не GET /get-books или GET /book. Аналогично, POST /books - для добавления новой книги, PUT /books/:id - для модификации полных данных книги с заданным идентификатором (id), а PATCH /books/:id обновляет частичные изменения в книге. И наконец, DELETE /books/:id предназначен для удаления существующей книги в заданным идентификатором. 2. JSON как основной формат отправки и получения данных Несколько лет назад прием и ответы на запросы API выполнялись в основном в XML. Но сейчас «стандартным» форматом для отправки и получения данных API в большинстве приложений стал JSON. Поэтому наш второй пункт рекомендует убедиться, что конечные точки возвращают формат данных JSON в качестве ответа, а также при приеме информации через полезную нагрузку HTTP-сообщений. Несмотря на то, что FormData хорошо подходит для отправки данных от клиента, особенно если нам нужно отправлять файлы, они не очень подходят для текста и чисел. Нам не нужны FormData для их передачи, так как в большинстве фреймворков можно передавать JSON непосредственно на стороне клиента. При получении данных от клиента нам необходимо убедиться, что клиент правильно интерпретирует данные JSON, и для этого при выполнении запроса в заголовке ответа Content-Type должен быть установлен на application/json. Стоит еще раз упомянуть исключение, когда мы пытаемся отправлять и получать файлы между клиентом и сервером. В этом конкретном случае нам необходимо обрабатывать файл ответа и отправлять FormData с клиента на сервер. 3. Используйте коды состояний HTTP Коды состояний HTTP всегда полезно использовать для того, чтобы указать на выполнение или невыполнение запроса. Не используйте слишком много кодов состояний и всегда используйте одни и те же коды для одних и тех же результатов в API. Вот некоторые примеры: 200 – общее выполнение 201 – успешное создание 400 – неверные запросы от клиента, такие как неверные параметры 401 – несанкционированные запросы 403 – отсутствие прав доступа к ресурсам 404 – отсутствуют ресурсы 429 – слишком много запросов 5хх – внутренние ошибки (их следует избегать насколько это возможно) В зависимости от ситуаций их может быть и больше, но ограничение количества кодов состояний помогает клиенту использовать более предсказуемый API. 4. Возвращайте стандартизированные сообщения Помимо использования кодов состояния HTTP, которые указывают на результат запроса, всегда используйте стандартизированные ответы для аналогичных конечных точек. Пользователи могут всегда рассчитывать на одинаковую структуру и действовать соответственно. Это также относится к статусу, указывающему на выполнение запроса, и сообщениях об ошибках. В случае выборки коллекций придерживайтесь определенного формата, независимо от того, включает ли тело ответа массив данных, подобный этому: [ { bookId: 1, name: "The Republic" }, { bookId: 2, name: "Animal Farm" } ] или вот такой комбинированный ответ: { "data": [ { "bookId": 1, "name": "The Republic" }, { "bookId": 2, "name": "Animal Farm" } ], "totalDocs": 200, "nextPageId": 3 } Здесь рекомендация заключается в том, чтобы быть последовательным независимо от того, какой подход вы выберете для этого. Аналогичное поведение должно быть реализовано при извлечении объекта, а также при создании и модификации ресурсов, которым обычно рекомендуется возвращать последний экземпляр объекта. // Ответ после успешного вызова POST /books { "bookId": 3, "name": "Brave New World" } Хоть это и никак не навредит, но все же излишнем будет включать универсальное сообщение, например, «Книга успешно создана», так как это уже следует из кода состояния HTTP. И последнее, но не менее важное: при наличии стандартного формата ответа коды ошибок также важны (и даже более важные). Это сообщение должно включать информацию, которую клиент может использовать для представления ошибок конечному пользователю, а соответственно, это должно быть не общее предупреждение, такое как «то-то пошло не так», которого следует избегать, насколько это возможно. Вот пример: { "code": "book/not_found", "message": "A book with the ID 6 could not be found" } Опять же, нет необходимости включать код состояния в содержимое ответа, но полезно определить набор кодов ошибок, таких как book/not_found, чтобы пользователь мог сопоставить их с разными строками и создать свое собственное сообщение об ошибке для конечного пользователя. В частности, для сред разработки или промежуточных сред может показаться правильным также включить стек ошибок в ответ с целью помочь в отладке ошибок. Но не включайте те, что находятся в промышленной эксплуатации, так как это создаст угрозу безопасности, раскрывая незапланированную информацию. 5. Используйте разбиение на страницы, фильтрацию и сортировку при выборе коллекций записей Как только будет создана конечная точка, которая возвращает список элементов, необходимо будет установить разбиение на страницы. Обычно коллекции со временем растут, поэтому важно всегда следить за тем, чтобы возвращалось ограниченное и контролируемое количество элементов. Справедливо будет позволить пользователям API выбирать, сколько объектов получить, но всегда полезно заранее определить число и установить для него максимум. Основная причина, почему нужно это сделать, заключается в том, что для возврата огромного массива данных потребуется очень много времени и большая пропускная способность. Для реализации нумерации страниц есть два хорошо известных способа: skip/limit или keyset. Первый вариант обеспечивает более удобный для пользователя способ извлечения данных, но обычно он менее эффективен, так как базы данных сканируют множество документов для извлечения нужных записей. Мне больше нравится второй вариант. Разделения на страницы с помощью keyset получает идентификатор (id) в качестве ссылки для «вырезания» коллекции или таблицы с условием без сканирования записей. Также API должны предоставлять фильтры и возможности сортировки, которые упрощают способы получения данных. Частью решения повышения производительности являются индексные базы данных, которые позволяют максимизировать производительность при помощи шаблонов доступа, которые применяются с фильтрами и параметрами сортировки. При проектировании API эти свойства разбиения на страницы, фильтрации и сортировки определяются как параметры запроса в URL-адресе. Например, если вы хотим получить информацию о первых 10 книгах, принадлежащих к категории «роман», то наша конечная точка будет выглядеть вот так: GET /books?limit=10&category=romance 6. PATCH вместо PUT Маловероятно, что необходимо будет сразу полностью обновить всю запись, обычно есть конфиденциальные или полные записи, которые следует уберечь от манипуляций пользователя. Именно поэтому для выполнения частичных обновлений ресурса следует использовать PATCH, а вот PUT полностью меняет существующий ресурс. Они оба должны использовать тело запроса для передачи информации, подлежащей модификации. Разница лишь в том, что для PATCH это поля, а для запроса PUT – полный объект. Тем не менее, стоит отметить, что ничто не мешает нам использовать PUT для частичной модификации, нет никаких «ограничений на передачу по сети», которые бы это подтверждали. Это просто факт, которого стоит придерживаться. 7. Предоставьте более подробные ответы Шаблоны доступа являются ключевыми при создании доступных ресурсов API и возвращаемых данных. Когда система растет, то и свойства записи также растут, но не всегда все эти свойства нужны клиентам для работы. Именно в таких ситуациях становится полезным предоставление возможности возвращать сокращенные или полные ответы для одной и той же конечной точки. Если пользователю нужны только некоторые поля, то упрощенный ответ помогает снизить расход трафика и потенциально сложность получения других вычисляемых полей. Простой способ реализовать – предоставить дополнительный параметр запроса, чтобы включить или отключить предоставление более подробного ответа. GET /books/:id { "bookId": 1, "name": "The Republic" }GET /books/:id?extended=true { "bookId": 1, "name": "The Republic" "tags": ["philosophy", "history", "Greece"], "author": { "id": 1, "name": "Plato" } } 8. Обязанность конечной точки Принцип единственной обязанности фокусируется на концепции удержания функции, метода или класса на одной обязанности, которую они выполняют хорошо. Мы можем сказать, что это наш API - хороший API, если он выполняет одну конкретную вещь и никогда не меняется. Это помогает пользователям лучше понять наш API и сделать его более предсказуемым, что облегчит общую интеграцию. Лучше всего расширить список доступных конечных точек, а не создавать очень сложные конечные точки, которые пытаются решить множество задач одновременно. 9. Предоставьте полную документацию по API Пользователи вашего API должны понимать, как использовать доступные конечные точки и чего ожидать. Это возможно только при наличии хорошей и подробной документации. Обратите внимание на следующие аспекты, чтобы ваша документация была полной. Доступные конечные точки с описанием их назначения Права доступа, необходимые для выполнения конечной точки Примеры вызовов и ответов Сообщения о предполагаемых ошибках Немаловажным является постоянное обновление документации после внесения изменений и дополнений в систему. Лучший способ для этого – сделать документацию по API неотъемлемой частью разработки. Двумя хорошо известными инструментами в данном вопросе являются Swagger и Postman – они доступны для большинства сред разработки API. 10. Используйте SSL для обеспечения безопасности и настройте CORS Безопасность – еще одно очень важной свойство, которым должен обладать наш API. Настройка SSL путем установки действительного сертификата на сервер обеспечит безопасную связь с пользователями и предотвратит некоторые виды потенциальных атак. CORS (Cross-origin resource sharing – Обмен ресурсами с запросом происхождения) – это функция безопасности браузера, которая ограничивает HTTP-запросы из различных источников, которые инициируются сценариями, запущенными в браузере. Если ресурсы вашего REST API получают непростые HTTP-запросы из разных источников, то вам нужно включить поддержку CORS для того, чтобы пользователи работали соответствующим образом. Протокол CORS требует, чтобы браузер отправил предварительный запрос на сервер и дождался утверждения (или запрос учетных данных) с сервера перед отправкой фактического запроса. Запрос предварительной проверки отображается в API как HTTP-запрос, использующий метод OPTIONS (среди других заголовков). Значит, для поддержки CORS в ресурсе REST API необходимо реализовать метод OPTIONS, который будет отвечать на предварительный запрос, по крайней мере, со следующими заголовками ответа, предусмотренными стандартом Fetch: Access-Control-Allow-Methods Access-Control-Allow-Headers Access-Control-Allow-Origin Какие значения назначать этим ключам, зависит от того, настолько открытым и гибким должен быть наш API. Мы можем назначить определённые методы и известные источники или использовать специальные символы, чтобы иметь открытые ограничения CORS. 11. Управление версиями API В процессе разработки конечные точки начинают меняться и перестраиваться. Но мы должны, насколько это возможно, избегать внезапного изменения конечных точек для пользователя. Рекомендуется рассматривать API как ресурс с обратной совместимость, в котором новые и обновленные конечные точки должны быть доступны, но не должны влиять на предыдущие стандарты. Вот где управление версиями API приходит на помощь – когда клиенты должны иметь возможность выбирать, к какой версии подключаться. Есть несколько способов описать управление версиями API: Добавление нового заголовка x-version=v2 Наличие параметра запроса ?apiVersion=2 Версия как часть URL: /v2/books/:id 12. Кэшируйте данные для повышения производительности Чтобы повысить производительность нашего API, полезно следить за данными, которые редко меняются и к которым часто обращаются. Для таких данных мы можем рассмотреть возможность использования базы данных в памяти или кэш-памяти, которая избавит от доступа к основной базе данных. Главная проблема здесь заключается в том, что данные могут устареть, поэтому следует решить вопрос с внедрением последней версии. Использование кэшированных данных будет полезным для пользователей для загрузки конфигураций и каталогов информации, которые не предназначены для постоянного изменения в течение долгого времени. При использовании кэширования не забудьте включить Cache-Control в заголовки. Это поможет пользователям эффективно использовать систему кэширования. 13. Используйте даты в формате UTC Сложно представить системы, которые в какой-то момент перестает работать из-за дат. На уровне данных важно быть логичным в том, как даты отображаются на клиентских приложениях. ISO 8601 – это международный стандартный формат данных для даты и времени. Данные должны быть в формате Z или UTC, для которых пользователи могут могли бы выбрать часовой пояс в случае, если такая дата должны отображаться при любых условиях. Вот пример того, как должны выглядеть даты: { "createdAt": "2022-03-08T19:15:08Z" } 14. Конечная точка проверки работоспособности Может произойти ситуация, когда наш API перестанет работать, и для его запуска потребуется время. При таких обстоятельствах клиенты хотят знать, что службы недоступны, и быть в курсе ситуации. Для этого предоставьте конечную точку (например, GET /health), которая бы определяла работоспособность API. Эта конечная точка может вызываться и другими приложениями, такими как балансировщики нагрузки. Можно продвинуться еще дальне и сообщать о периодах технического обслуживания или работоспособности частей API. 15. Разрешите аутентификацию по ключу API Аутентификация с помощью ключей API даст возможность сторонним приложениям легко создавать интеграцию с нашим API. Эти ключи API следует передавать с помощью пользовательского заголовка HTTP (например, Api-Key или X-Api-Key). Ключи должны иметь дату окончания срока действия, и должна быть возможность их отозвать с целью признания недействительными по соображениям безопасности.
ВЕСЕННИЕ СКИДКИ
40%
50%
60%
До конца акции: 30 дней 24 : 59 : 59