5 книг по проектированию Web API


Оглавление (нажмите, чтобы открыть):

Изучаем REST: Руководство по созданию RESTful сервиса

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

В настоящее время существует не так много руководств по REST API, которые могли бы помочь программистам-одиночкам. RestApiTutorial.ru предназначен для отслеживания лучших практик REST API и их агрегирования, для обеспечения быстрого поиска и самообразования. Мы рассмотрим теоретические и практические аспекты создания RESTful веб-сервисов.

Перейдите к уроку Что такое REST? для рассмотрения концепций и ограничений RESTful архитектуры.

Проектирование и разработка web-приложений, Тузовский А.Ф., 2020

Проектирование и разработка web-приложений, Тузовский А.Ф., 2020.

В пособии рассматриваются современные интернет-технологии и их использование для создания web-приложений. Поясняются основные понятия и стандарты сети Интернет и реализованной на ее основе web-сети (World Wide Web), состав программного обеспечения данной сети, логика работы web-приложений, основные подходы и технологии их разработки. В качестве примера подходов к разработке web-приложений рассматриваются технологии ASP.Net Web Forms и MVC. В заключительной главе пособия поясняются современные методы проектирования
web-приложений и рекомендации по реализации их различных уровней. Соответствует актуальным требованиям Федерального государственного образовательного стандарта среднего профессионального образования и профессиональным требованиям. Предназначено для студентов образовательных учреждений среднего профессионального образования, обучающихся по специальности «Прикладная информатика».

ВВЕДЕНИЕ.

Сегодня практически вес компьютеры (настольные и мобильные) подключены к сети Интерне! и в основном используют одни из её сервисов World Wide Web (Всемирную Паутину, web-СЕТЬ). Первоначально данный сервис (web-сеть) использовался только для связывания и предоставления статической информации. Однако в настоящее время он стал платформой для удаленного использования специальных прикладных программ web-приложений. Если ранее, прежде чем использовать приложение на локальном компьютере, требовалось её устанавливать, то сейчас приложение можно запускать с помощью web-браузера (Интернет-обозревателя), просто указав его адрес. При этом само приложение выполняется на удаленном компьютере (сервере), а пользователь может работать с ним на своем компьютере с помощью web-браузера. В связи с активным развитием сети Интернет, web-сети и изменением подхода к использованию приложений специалисты в области информационных технологий должны уметь разрабатывать такие web-приложения.

ОГЛАВЛЕНИЕ.

ВВЕДЕНИЕ.
1. ИНТЕРНЕТ И WEB-СЕТЬ.
2. ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ WEB-СЕТИ.
3. ПОДХОДЫ К РАЗРАБОТКЕ WEB-ПРИЛОЖЕНИЙ.
4. РАЗРАБОТКИ СЕРВЕРНЫХ WEB-ПРИЛОЖЕНИЙ С ПОМОЩЬЮ ТЕХНОЛОГИЙ ASP.NET.
5. ПРОЕКТИРОВАНИЕ WEB-ПРИЛОЖЕНИЙ.
СПИСОК ЛИТЕРАТУРЫ.

Бесплатно скачать электронную книгу в удобном формате, смотреть и читать:
Скачать книгу Проектирование и разработка web-приложений, Тузовский А.Ф., 2020 — fileskachat.com, быстрое и бесплатное скачивание.

Скачать pdf
Ниже можно купить эту книгу по лучшей цене со скидкой с доставкой по всей России. Купить эту книгу

Web API

Введение в Web API

Одним из преимуществ стека технологий на платформе .NET является возможность создания сервисов. Так, в ASP.NET мы могли создавать ASMX-веб-службы. Кроме того, мы можем использовать более функциональную в этом плане технологию WCF для создания веб-служб.

Но с последним релизом MVC 4 и вообще всей платформы .NET 4.5 в нашем распоряжении оказался еще один инструмент для создания веб-служб — Web API. Концепция Web API (которую кстати можно использовать не только в MVC, но и в веб-формах) новый подход к реализации веб-приложений.

Создадим простое приложение ASP.NET MVC 4, указав в качестве шаблона проекта Web API :

Среда создаст обычный mvc-проект со стандартной структурой. По умолчанию нам будет создано два контроллера. Один из них стандартный контроллер HomeController. Второй контроллер — ValuesController, который и реализует функционал Web API:

Как видно, определение контроллера Web API отличается от обычного контроллера. Во-первых, он образован от класса ApiController , который не связан с базовым классом обычных контроллеров — Controller

Во-вторых, контроллеры Web API применяют стиль REST. Вообще поддержка архитектуры REST (Representation State Transfer или «передача состояния представления») является одним из основных узловых пунктов технологии Web API.

Для взаимодействия с сервером в REST-архитектуре используются методы HTTP:

У нас тут нет обычных методов действий, как в традиционных контроллерах, которые возвращают ActionResult. А определенные в контроллере ValuesContoller методы сопоставляются с одноименными методами HTTP.

Маршрутизация в Web API

Поскольку в Web API методы контроллера не являются прямыми ресурсами и сопоставляются с методами HTTP, то и весь механизм маршрутизации действует не как при определении обычных маршрутов. Все определения маршрутов для Web API находятся в файле WebApiConfig.cs (в папке App_Start):

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

В итоге обращение api/values будет соответствовать обращению к контроллеру ValuesCotroller, причем почти ко всем действиям сразу (кроме Get(int id) — так как в данном случае необходим еще идентификатор, например api/values/2)

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

Так, например, запрос GET api/values будет сопоставлен с методом IEnumerable Get() и вернет в ответ браузеру коллекцию элементов string .

Если же сервер получит запрос PUT с адресом api/values, то такой запрос будет сопоставлен с методом Put.

А запросу GET api/values/7 будет соответствовать метод string Get(int id) , так как этот метод принимает параметр.

Условности при наименовании методов

При создании методов контроллера Web API действует некоторые условности. Так, имена методов по умолчанию должны начинаться с имени предназначенного для них метода HTTP. В случае с контроллером по умолчанию все просто: все методы действий носят названия методов HTTP.

Однако мы можем использовать и любые другие имена без префиксов, но в этом случае нам надо будет явно указать метод HTTP в виде атрибута, например:

Таким образом, если первые два действия соответствуют соглашениям о наименовании (в начале содержат название метода HTTP), то к остальным мы применяем атрибуты, чтобы система знала, с каким методом надо сопоставлять запрос.

Web-разработка: книги, которые не стоит упускать

Дата публикации: 2020-10-18

От автора: в эпоху интернета почти не осталось тех, кто гуглит не видеоматериалы, а книги. Но есть и одна сфера, где литература до сих пор имеет хорошие позиции. Запросы вроде «web разработка книги» остаются популярными среди начинающих веб-разработчиков. Несмотря на целые массивы материалов, найти тот, который будет одновременно хорошо написан и актуален, довольно трудно. Но чтобы вы не потерялись в источниках для обучения, рассмотрим самые топовые книги, которые дают реальные знания.

Книга, как main src

Многие из тех, кто только начал постигать веб-разработку, начнут возражать: «Книги написаны сложно! Они не дают реальных примеров!». Истина где-то рядом, но не совсем там. Учебники по web-разработке до сих пор актуальны. Они является основными источниками знаний. И если вы считаете, что учитель в IT-школе сможет дать вам больше, чем бесплатный абонемент в библиотеку, то сегодня докажем обратное. Даже в 2020 году обучение должно строиться на учебниках и статьях, а не на субъективном опыте пусть даже самого продвинутого учителя.

Итак, представим, что вы все же попали на оффлайн-курсы. Вам преподают основы разметки страницы, JavaScript и много всего прочего. Конечно, базовые знания вы получите и даже сможете их применять. Но без использования книг вы будете словно дирижабль, полностью нагруженный песком — не взлететь.

Дело в том, что учителя, которые преподают в подобных школах, редко являются хорошими специалистами. Это порок профессионального образования, как явления, и веб-разработка не является исключением: «Кто не умеет, тот учит». Мы ни в коем случае не хотим оскорбить тех, кто находит в обучении младшего поколения свое призвание и считает, что передать знание — священная миссия. Но, как правило, IT-школа — это бизнес-проект. Уж если говорить о преподавателях базового уровня обучения, то их познания не удовлетворят пытливый ум.

Как создать сайт самому?

Какие технологии и знания необходимы сегодня, чтобы создавать сайты самостоятельно? Узнайте на интенсиве!

Это вовсе не значит, что курсы плохи. Но если вы хотите постичь web-разработку, то ваш первый помощник — учебник. Он позволит вам знать, применять и понимать больше, чем учитель. Курсы круты, когда их дают признанные профессионалы. Как правило, они делают это посредством вебинаров и для продвинутого уровня.

В пользу живых учителей также говорит тот факт, что для книг характерно моральное устаревание, и с этим трудно не согласиться. Печатные источники хороши только тогда, когда только вышли из-под станка. В веб-разработке все настолько динамично, что книга может устареть за день и быстрее. Но и здесь есть светлая сторона: толковый автор знает, что писать стоит только об основательных трендах. Он не наполняет книгу, основываясь на статьях в Интернете. Как правило, автор хорошей книги — профессионал, который знает, как все объяснить для начинающих. К тому же, хорошие книги не устаревают. К примеру, «Базы Данных» авторства Каролин Бегг до сих пор актуальна, несмотря на то, что сами СУБД уже не раз обновлялись.

Книга или онлайн-курс

Итак, определились, что изучать веб-разработку лучше одному и с учебником. Но соблазн посмотреть реальное применение кода в видеокурсе все же велик. Тем более, что лучшие из них действительно разбирают все детально и могут ускорить студента в сотни раз, по сравнению с теми, кто учит книги. Какие же преимущества у видеороликов:

зачастую их пишут профессионалы. Да, в этом ролики во многом похожи на книги. Когда человек хорошо знаком с тематикой, он готов размещать видео-уроки, отвечать на вопросы, советовать литературу. Тем более, что, за редким исключением, вы всегда можете посмотреть реальное портфолио автора курса;

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

позволяют не читать. Развитие медиа-пространства сформировало общество, которое не любит читать. Правда, существуют люди, неспособные воспринимать информацию таким образом. Для них книги — это долгий путь, который только предстоит пройти.

Одним большим недостатком видеороликов по сравнению с учебником является то, что первые не всегда рассматривают проблему в полном объеме. Допустим, один вебмастер решает использовать конкретный способ для запуска серверного Python-скрипта через веб-интерфейс. Он применяет его всю жизнь и считает лучшим. Он не станет тратить эфирное время на рассмотрение остальных способов. В учебнике по web-разработке автор может расписать все более детально.

Как создать сайт самому?

Какие технологии и знания необходимы сегодня, чтобы создавать сайты самостоятельно? Узнайте на интенсиве!

Также короткие статьи и видеоуроки заставляют ученика проходить все в режиме нон-стоп, поглощая информацию и пропуская важные моменты. Студенты, которые учат веб-разработку исключительно методом онлайн-уроков, склонны просто копировать действия учителя, не особенно вникая в сам механизм программирования. В итоге, не могут применить полученные знания на практике. К тому же, перенасыщение информацией способствует забыванию. Только детально рассмотрев проблему, поняв ее суть, можно реализовать знания много лет спустя.

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

Два направления развития

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

Пособия по веб-рисованию

Говорят, что хорошим дизайнером просто нужно родиться: обучение здесь ни к чему. Но практика показывает обратное: люди с хорошим вкусом, но без художественного таланта могут создавать хороший UX. А если их еще и вооружить знаниями о том, как сделать красивое полезным, такой дизайнер будет нарасхват. Кстати, бесплатный совет: лучшие книги по веб-дизайну оформлены приятнее остальной литературы.

Mobile UI Design Patterns

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

About Face: Основы дизайна взаимодействия

Как офицер знает Устав, так и дизайнер должен знать эту книгу. Она вроде главной по созданию UI/UX. Первое издание увидело свет еще до начала двадцать первого века, но книга остается актуальной и сегодня (помните, что выше говорилось о хороших учебниках). Даже в 2020 году она дает представление о том, как сделать дизайн функциональной единицей.

100 главных принципов дизайна. Как удержать внимание

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

Настольные книги программиста

Ни в коем случае не хотим унизить важность дизайна, но он не появится в сети без веб-разработчиков, которые превращают рисунок в работающий код. Техническая составляющая веб-разработки требует глубинных и актуальных знаний — без книг здесь никак. Сразу опустим те, которые учат азам HTML/CSS. Просто выбирайте актуальный источник, который вам понравится!

JavaScript: подробное руководство

Неудивительно, если где-то живет семья, в которой этот учебник по web-разработке передают по наследству. Настоящая легенда мира веб-программирования. Аналогичной литературы просто не существует — всегда полная и современная информация от издания к изданию.

PHP Web Services

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

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

Как создать сайт самому?

Какие технологии и знания необходимы сегодня, чтобы создавать сайты самостоятельно? Узнайте на интенсиве!

Веб-дизайн. Быстрый старт

Изучите курс и узнайте, как создать дизайн и протопип сайта в Figma!

DRF, часть 1 — Проектирование структуры API

Введение

Раз уж у меня не получается написать полноценную огромную статью про Django REST Framework, следует публиковать хотя бы небольшие заметки. Начать следует с прописных истин.

  1. 1. Дуб — дерево.
  2. 2. Олень — животное.
  3. 3. Смерь — неизбежна.
  4. 4. api — отдельное приложение в нашем проекте
  5. 5. Следует придерживаться общепринятых правил именования частей API
  6. 6. API должен быть версионным
  7. 7. API должен быть простым

С первыми тремя пунктами всё ясно, поэтому перейду сразу к четвёртому и нижеследующим.

Структура каталогов и версионность

Сначала я пытался запихнуть API в разные части основного проекта, создавал в каталоге с приложениями файлы api.py , serializers.py и permissions.py .

О том, насколько это плохая идея, я узнал почти сразу же, когда начал путаться с тем, что и где лежит. Стоило только переименовать один из каталогов, как сразу же всё начинало сыпаться. В итоге я пришёл к тому, что API — не просто отдельное приложение, содержащее только файлы __init__.py и urls.py (со ссылками на нужные файлы в приложениях Django), а полноценный модуль со множеством вложенных модулей. В общем, почувствуйте разницу:

Надеюсь, структура понятна. Во-первых, всё, что связано с API, переехало в одноимённое приложение. Во-вторых, API теперь поддерживает версионность. Для этого нужно всего ничего — создать соответствующие каталоги и правильно описать файл urls.py в самом начале. Я сделал так:

Естественно, где-то в главном файле urls.py есть строка, в которой конфигурация URL для API присоединяется к общей конфигурации URL через всё тот же include() .

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


Именование API

Сначала хочу сказать, как делать НЕ НАДО:

Это что угодно, но не API. К сожалению, по ночам мне всё ещё снятся кошмары, в которых я вижу, как на одном из сайтов общение с сервисами сделано именно так.

Это API? Конечно же, нет! Суть REST-сервисов в том, что требуемое действие определяется HTTP-заголовком!

Разница, как говорится, налицо.

В Django REST Framework обновление записи может быть произведено двумя способами — полностью или частично. В первом случае вызывается запрос с заголовком PUT , во втором — PATCH .

При полном обновлении сериализатор проверяет заполнение всех полей модели, у которых не указаны свойства null=True . Не будем забывать, что для модели пользователя обязательными для заполнения являются поля «Пароль» и «Имя пользователя». Но мы же всего лишь хотели указать новую дату рождения! Почему DRF проверяет все поля? Потому что надо было вызывать метод PATCH .

Теперь пора поговорить, как делать лучше (моё мнение по данному вопросу актуально только на момент написания статьи и в будущем может быть пересмотрено).

Сериализаторы и всё остальное.

Я считаю, что при написании новой версии API могут измениться поля, с которыми работают сериализаторы, поэтому для каждой версии их лучше создавать заново. Кроме того, сами методы для работы с данными могут стать другими. Отсюда следует простой вывод (до которого мне пришлось доходить своим умом пару месяцев):

Мастер Йода рекомендует:  Алексей Могилевский, архитектор Internet Explorer, перешёл в «Яндекс»

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

Подходы к проектированию RESTful API

В этой статье я поделюсь опытом проектирования RESTful API — на конкретных примерах покажу, как делать хотя бы простые сервисы красиво. Также мы поговорим, что такое API и зачем он нужен, поговорим об основах REST — обсудим, на чем его можно реализовывать; коснемся основных веб-практик, которые зависят и не зависят от этой технологии. Также узнаем, как составлять хорошую документацию, затрачивая на это минимум усилий, и посмотрим, какие существуют способы нумерации версий для RESTful API.

Часть 1. Теория

Итак, как мы все знаем, API — application programming interface (интерфейс программирования приложений), набор правил и механизмов, с помощью которых одно приложение или компонент взаимодействует с другими

Почему хороший API — это важно?

  • Простота использования и поддержки. Хороший API просто использовать и поддерживать.
  • Хорошая конверсия в среде разработчиков. Если всем нравится ваш API, к вам приходят новые клиенты и пользователи.
  • Выше популярность вашего сервиса. Чем больше пользователей API, тем выше популярность вашего сервиса.
  • Лучше изоляция компонентов. Чем лучше структура API, тем лучше изоляция компонентов.
  • Хорошее впечатление о продукте. API — это как бы UI разработчиков; это то, на что разработчики обращают внимание в первую очередь при встрече с продуктом. Если API кривой, вы как технический эксперт не будете рекомендовать компаниям использовать такой продукт, приобретая что-то стороннее.

Теперь посмотрим, какие бывают виды API.

Виды API по способу реализации:

  • Web service APIs
    • XML-RPC and JSON-RPC
    • SOAP
    • REST
  • WebSockets APIs
  • Library-based APIs
    • Java Script
  • Class-based APIs
    • C# API
    • Java

Виды API по категориям применения:

  • OS function and routines
    • Access to file system
    • Access to user interface
  • Object remoting APIs
    • CORBA
    • .Net remoting
  • Hardware APIs
    • Video acceleration (OpenCL…)
    • Hard disk drives
    • PCI bus

Как мы видим, к Web API относятся XML-RPC и JSON-RPC, SOAP и REST.

RPC (remote procedure call — «удаленный вызов процедур») — понятие очень старое, объединяющие древние, средние и современные протоколы, которые позволяют вызвать метод в другом приложении. XML-RPC — протокол, появившийся в 1998 г. вскоре после появления XML. Изначально он поддерживался Microsoft, но вскоре Microsoft полностью переключилась на SOAP, поэтому в .Net Framework мы не найдем классов для поддержки этого протокола. Несмотря на это, XML-RPC продолжает жить до сих пор в различных языках (особенно в PHP) — видимо, заслужил любовь разработчиков простотой.

SOAP также появился в 1998 г. стараниями Microsoft. Он был анонсирован как революция в мире ПО. Нельзя сказать, что все пошло по плану Microsoft: было огромное количество критики из-за сложности и тяжеловесности протокола. В то же время, были и те, кто считал SOAP настоящим прорывом. Протокол продолжал развиваться и плодиться десятками новых и новых спецификаций, пока в 2003 г. W3C не утвердила в качестве рекомендации SOAP 1.2, который и сейчас — последний. Семейство у SOAP получилось внушительное: WS-Addressing, WS-Enumeration, WS-Eventing, WS-Transfer, WS-Trust, WS-Federation, Web Single Sign-On.

Затем, что закономерно, все же появился действительно простой подход — REST. Аббревиатура REST расшифровывается как representational state transfer — «передача состояния представления» или, лучше сказать, представление данных в удобном для клиента формате. Термин «REST» был введен Роем Филдингом в 2000 г. Основная идея REST в том, что каждое обращение к сервису переводит клиентское приложение в новое состояние. По сути, REST — не протокол и не стандарт, а подход, архитектурный стиль проектирования API.

Каковы принципы REST?

  • Клиент-серверная архитектура — без этого REST немыслим.
  • Любые данные — ресурс.
  • Любой ресурс имеет ID, по которому можно получить данные.
  • Ресурсы могут быть связаны между собой — для этого в составе ответа передается либо ID, либо, как чаще рекомендуется, ссылка. Но я пока не дошел до того, чтобы все было настолько хорошо, чтобы можно было легко использовать ссылки.
  • Используются стандартные методы HTTP (GET, POST, PUT, DELETE) — т. к. они уже заложены в составе протокола, мы их можем использовать для того, чтобы построить каркас взаимодействия с нашим сервером.
  • Сервер не хранит состояние — это значит, сервер не отделяет один вызов от другого, не сохраняет все сессии в памяти. Если у вас есть какое-либо масштабируемое облако, какая-то ферма из серверов, которая реализует ваш сервис, нет необходимости обеспечивать согласованность состояния этих сервисов между всеми узлами, которые у вас есть. Это сильно упрощает масштабирование — при добавлении еще одного узла все прекрасно работает.
  • Он очень прост!
  • Мы переиспользуем существующие стандарты, которые в ходу уже очень давно и применяются на многих устройствах.
  • REST основывается на HTTP => доступны все плюшки:
    • Кэширование.
    • Масштабирование.
    • Минимум накладных расходов.
    • Стандартные коды ошибок.
  • Очень хорошая распространенность (даже IoT-устройства уже умеют работать на HTTP).

Лучшие решения (независимые от технологий)

Какие в современном мире есть лучшие решения, не связанные с конкретной реализацией? Эти решения советую использовать обязательно:

  • SSL повсюду — самое важное в вашем сервисе, т. к. без SSL авторизация и аутентификация бессмысленны.
  • Документация и версионность сервиса — с первого дня работы.
  • Методы POST и PUT должны возвращать обратно объект, который они изменили или создали, — это позволит сократить время обращения к сервису вдвое.
  • Поддержка фильтрации, сортировки и постраничного вывода — очень желательно, чтобы это было стандартно и работало «из коробки».
  • Поддержка MediaType. MediaType — способ сказать серверу, в каком формате вы хотите получить содержимое. Если вы возьмете какую-либо стандартную реализацию web API и зайдете туда из браузера, API отдаст вам XML, а если зайдете через какой-нибудь Postman, он вернет JSON.
  • Prettyprint & gzip. Не минимизируйте запросы и не делайте компакт для JSON (того ответа, который придет от сервера). Накладные расходы на prettyprint —единицы процентов, что видно, если посмотреть, сколько занимают табы по отношению к общему размеру сообщения. Если вы уберете табы и будете присылать все в одну строку, запаритесь с отладкой. Что касается gzip, он дает выигрыш в разы. Т. ч. очень советую использовать и prettyprint, и gzip.
  • Используйте только стандартный механизм кэширования (ETag) и Last-Modified (дата последнего изменения) — этих двух параметров серверу достаточно, чтобы клиент понял, что содержимое не требует обновления. Придумывать что-то свое тут не имеет смысла.
  • Всегда используйте стандартные коды ошибок HTTP. Иначе вам однажды придется кому-нибудь объяснять, почему вы решили, что ошибку 419 в вашем проекте клиенту нужно трактовать именно так, как вы почему-то придумали. Это неудобно и некрасиво — за это клиент вам спасибо не скажет!

Свойства HTTP-методов

Сегодня мы будем говорить только про GET, POST, PUT, DELETE.

Если говорить вкратце об остальных, представленных в таблице, OPTIONS — получение настроек безопасности, HEAD — получение заголовков без тела сообщения, PATCH — частичное изменение содержимого.

Как вы видите, все методы, кроме POST, представленные в таблице, идемпотентны. Идемпотентность — возможность выполнить одно и то же обращение к сервису несколько раз, при этом ответ каждый раз будет одинаковым. Другими словами, не важно, по какой причине и сколько раз вы выполнили это действие. Допустим, вы выполняли действие по изменению объекта (PUT), и вам пришла ошибка. Вы не знаете, что ее вызвало и в какой момент, вы не знаете, изменился объект или нет. Но, благодаря идемпотентности, вы гарантированно можете выполнить этой действие еще раз, т. ч. клиенты могут быть спокойны за целостность своих данных.

«Safe» же значит, что обращение к серверу не изменяет содержимое. Так, GET может быть вызван много раз, но он не изменит никакого содержимого. Если бы он изменял содержимое, в силу того, что GET может быть закэширован, вам пришлось бы бороться с кэшированием, изобретать какие-нибудь хитрые параметры.

Часть 2. Практика

Выбираем технологию

Теперь, когда мы поняли, как работает REST, можем приступить к написанию RESTful API ¬ сервиса, отвечающего принципам REST. Начнем с выбора технологии.

Первый вариант — WCF Services. Все, кто работал с этой технологией, обычно возвращаться к ней больше не хотят — у нее есть серьезные недостатки и мало плюсов:
– webHttpBinding only (а зачем тогда остальные. ).
– Поддерживаются только HTTP Get & POST (и все).
+ Разные форматы XML, JSON, ATOM.

Второй вариант — Web API. В этом случае плюсы очевидны:
+ Очень простой.
+ Открытый исходный код.
+ Все возможности HTTP.
+ Все возможности MVC.
+ Легкий.
+ Тоже поддерживает кучу форматов.

Естественно, мы выбираем Web API. Теперь выберем подходящий хостинг для Web API.

Выбираем хостинг для Web API

Тут есть достаточно вариантов:

  • ASP.NET MVC (старый добрый).
  • Azure (облачная структура).
  • OWIN — Open Web Interface for .NET (свежая разработка от Microsoft).
  • IIS
  • Self-hosted

OWIN — не платформа и не библиотека, а спецификация, которая устраняет сильную связанность веб-приложения с реализацией сервера. Она позволяет запускать приложения на любой платформе, поддерживающей OWIN, без изменений. На самом деле, спецификация очень проста — это просто «словарь» из параметров и их значений. Базовые параметры определены в спецификации.

OWIN сводится к очень простой конструкции:

По схеме мы видим, что есть хост, на котором есть сервер, который поддерживает очень простой «словарь», состоящий из перечня «параметр — значение». Все модули, которые подключаются к этому серверу, конфигурируются именно так. Сервер, поддерживающий этот контракт, привязанный к определенной платформе, умеет распознавать все эти параметры и инициализировать инфраструктуру соответствующим образом. Получается, что, если вы пишете сервис, который работает с OWIN, можете свободно, без изменений кода, переносить его между платформами и использовать то же самое на других ОС.

Katana — реализация OWIN от Microsoft. Она позволяет размещать OWIN-сборки в IIS. Вот так она выглядит, очень просто:

Вы указываете, какой класс является у вас Startup. Это простой dll, который поднимается IIS. Вызывается конфигуратор. Этого кода достаточно, чтобы все заработало.

Проектируем интерфейс

Как пример возьмем простую модель с расписанием движения поездов на станциях. Вот примеры простейших запросов REST:

  • Корневые (независимые) сущности API:
    • GET /stations — получить все вокзалы.
    • GET /stations/123 — получить информацию по вокзалу с >Далее я еще расскажу про DDD, почему мы делаем именно так.

    Контроллер

    Итак, у нас есть станции, и теперь нам нужно написать простейший контроллер:

    Это роутинг, построенный на атрибутах. Здесь мы указываем имя контроллера и просим отдать список (в данном случае — случайные тестовые данные).

    OData (www.odata.org)

    Теперь представьте, что у вас больше данных, чем нужно на клиенте (больше ста тащить вряд ли имеет смысл). При этом писать самому какое-либо разбиение на страницы, конечно, совсем не хочется. Вместо этого есть простой способ — использовать легкую версию OData, которая поддерживается Web API.

    IQueryable позволяет вам использовать несколько простых, но эффективных механизмов фильтрации и управления данными на клиентской стороне. Единственное, что нужно сделать, — подключить OData-сборку из NuGet, указать EnableQuery и возвращать интерфейс iQueryable.

    Основное отличие такой облегченной верси от полноценной в том, что здесь нет контроллера, который возвращает метаданные. Полноценная OData немного изменяет ответ (заворачивает в спец. Обертку модель, которую вы собираетесь возвращать) и умеет возвращать связанное дерево объектов, которые вы хотите ей отдать. Также облегченная версия OData не умеет делать штуки вроде join, count и т. д.

    Параметры запросов

    А вот что можно делать:

    • $filter — фильтр, по имени, например. Все функции можно посмотреть на сайте OData — они очень помогают и позволяют существенно ограничить выборку.
    • $select — очень важная штука. Если у вас большая коллекция и все объекты толстые, но при этом вам нужно сформировать какой-то dropdown, в котором нет ничего, кроме ID и имени, которое вы хотите отобразить, — поможет эта функция, которая упростит и ускорит взаимодействие с сервером.
    • $orderby — сортировка.
    • $top и $skip — ограничение по выборкам.

    Этого достаточно, чтобы самому не изобретать велосипеда. Все это умеет стандартная JS-библиотека вроде Breeze.

    EnableQuery Attribute


    На самом деле OData — такая штука, которой очень легко можно выстрелить себе в ногу. Если у вас в таблице миллионы записей, и вам нужно тянуть их с сервера на клиент, это будет тяжело, а если таких запросов будет много — совсем смертельно.

    Именно для таких случаев у атрибута EnableQuery (см. код выше) есть такой набор параметров, с помощью которых очень многое можно ограничить: не давать больше строк, чем надо, не давать делать join, арифметические операции и т. д. При этом писать самому ничего не надо.

    • AllowedArithmeticOperators
    • AllowedFunctions
    • AllowedLogicalOperators
    • AllowedOrderByProperties
    • AllowedQueryOptions
    • EnableConstantParameterization
    • EnsureStableOrdering
    • HandleNullPropagation
    • MaxAnyAllExpressionDepth
    • MaxExpansionDepth
    • MaxNodeCount
    • MaxOrderByNodeCount
    • MaxSkip
    • MaxTop
    • PageSize

    Итак, вот примеры простейших запросов REST:

    • GET /stations – получить все вокзалы
    • GET /trains – расписание всех поездов
    • GET /stations/555/arrivals
    • GET /stations/555/departures

    Допустим, у нас есть вокзал 555, и мы хотим получить все его отправления и прибытия. Очевидно, что здесь должна использоваться сущность, которая зависит от сущности вокзала. Но как это сделать в контроллерах? Если мы все это будет делать роутинг-атрибутами и складывать в один класс, понятно, что в таком примере, как у нас, проблем нет. Но если у вас будет десяток вложенных сущностей и глубина будет расти еще дальше, все это вырастет в неподдерживаемый формат.

    И тут есть простое решение — в роутинг-атрибутах в контроллерах можно делать переменные:

    Соответственно, все зависимые сущности выносите в отдельный контроллер. Сколько их — совершенно неважно, так как они живут отдельно. С точки зрения Web API, они будут восприниматься разными контроллерами — сама система как бы не знает, что они зависимы, несмотря на то, что в URL они выглядят таковыми.

    Единственное, возникает проблема — здесь у нас «stations», и до этого был «stations». Если вы в одном месте что-то поменяете, а в другом — ничего не поменяете, ничего работать не будет. Однако тут есть простое решение — использование констант для роутинга:

    Тогда зависимый контроллер будет выглядеть так:

    Вы можете делать для зависимых контроллеров простейшие операции — вы просто берете и вычисляете роут сами, и тогда вы не ошибетесь. Кроме того, эти штуки полезно использовать в тестировании. Если вы хотите написать тест и потом хотите этим управлять, а не бегать каждый раз по всем миллионам ваших тестов и исправлять все строки, где указаны эти относительные URL’ы, то вы также можете использовать эти константы. Когда вы их меняете, данные у вас меняются везде. Это очень удобно.

    Итак, мы с вами обсудили, как могут выглядеть простейшие GET-операции. Все понимают, как сделать единичный GET. Но, кроме него, нам нужно обсудить еще три операции.

    • POST – создать новую сущность
      • POST /Stations – JSON-описание сущности целиком. Действие добавляет новую сущность в коллекцию.
      • Возвращает созданную сущность (во-первых, чтобы не было двойных походов к серверу, во-вторых, чтобы, если это нужно, вернуть со стороны сервера параметры, которые посчитались в этом объекте и нужны вам на клиенте).
    • PUT — изменить сущность
      • PUT /Stations/12 — Изменить сущность с >Еще примеры CRUD:

        • POST /Stations — добавляем вокзал.
        • POST /Stations/1/Departures — добавляем информацию об отправлении с вокзала 1.
        • DELETE /Stations/1/Departures/14 — удаляем запись об отправлении с вокзала 1.
        • GET /Stations/33/Departures/10/Tickets — список проданных билетов для отправления 10 с вокзала 33.

        Важно понимать, что узлы — обязательно какие-то сущности, то, что можно «потрогать» (билет, поезд, факт отправления поезда и т. д.).

        Антишаблоны

        А вот примеры, как делать не надо:

        • GET /Stations/?op=departure&train=11
          Здесь query string используется не только для передачи данных, но и для действий.
        • GET /Stations/DeleteAll
          Это реальный пример из жизни. Тут мы делаем GET на этот адрес, и он, по идее, должен удалить все сущности из коллекции — в итоге он ведет себя очень непредсказуемо из-за кэширования.
        • POST /GetUserActivity
          На самом деле здесь GET, который записан как POST. POST нужен был из-за параметров запроса в body, но в body у GET нельзя ничего передать — GET можно передать только в query string. GET даже по стандарту не поддерживает body.
        • POST /Stations/Create
          Здесь действие указано в составе URL — это избыточно.

        Проектируем API

        Допустим, у вас есть API, который вы хотите предложить людям, и есть доменная модель. Как связаны сущности API с доменной моделью? Да никак они не связаны, на самом деле. В этом нет никакой необходимости: то, что вы делаете в API, никак не связано с вашей внутренней доменной моделью.

        Может возникнуть вопрос, как проектировать API, если это не CRUD? Для этого мы записываем любые действия как команды на изменения. Мы делаем сохранение, чтение, удаление команды, GET, проверку статуса этой команды. GET из коллекции команд — вы получаете список всех команд, которые вы отправляли для какой-либо конкретной сущности.

        Доменная модель

        Мы поговорим о связи доменной модели с объектами. В примере у нас есть отель (Hotel), есть бронирования (Reservation), комнаты (Room) и устройства (Device), к ним привязанные. В нашем проекте это позволяло управлять комнатами посредством этих устройств.

        Но вот незадача: устройство — сущность, которая живет своей жизнью, и непонятно, как ее отделять от отеля. Но разделить отель и устройства, на самом деле, очень просто — поможет DDD. В первую очередь, нужно разобраться, где границы доменных областей и где границы сущностей, ответственных за согласованность системы.

        Bounded context (BC)

        Bounded context (изолированный поддомен) — фактически, наборы объектов, не зависимые друг от друга и имеющие совершенно независимые модели (разные). В примере мы можем взять и растащить отели и устройства на два разных BC — они не связаны между собой, но присутствует дублирование. Возникает дополнительная сущность (AttachedDevice):

        Тут у нас разные представления одного и того же устройства, и в этом нет ничего страшного.

        В DDD aggregate route — сущность, которая владеет всеми потомками. Это вершина нашего дерева (Hotel); то, за что можно вытянуть все остальное. А AttachedDevice так взять нельзя — его не существует, и он не имеет никакого смысла. Так же и классы Room и Reservation не имеют никакого смысла, будучи оторванными от Hotel. Поэтому доступ ко всем этим классам — исключительно через рутовую сущность, через Hotel, в данном случае. Device же — другой route с самого начала, другое дерево с другим набором полей.

        Итак, если вы понимаете, что одна сущность у вас играет в двух разных доменах, просто распилите ее — и это будет всего лишь проекция мастер-сущности. В AttachedDevice будут, например, поля с номером комнаты, а в Device такие поля не нужны.

        А вот примеры запросов, как они могут выглядеть в такой доменной модели:

        • PUT /hotels/555/rooms/105/attachedDevices — заменить всю коллекцию привязанных устройств на новую.
        • POST /hotels/555/rooms/105/attachedDevices — привязать еще одно устройство.
        • DELETE /hotels/12 — удалить описание отеля с >Я не буду сейчас рассказывать про это архитектуру, но хочу коротко обрисовать, в чем ее принцип действия. Архитектура CQRS основана на разделении потоков данных.

        У нас есть один поток, через который пользователь отправляет на сервер команду об изменении домена. Однако не факт, что изменение действительно произойдет, — пользователь не оперирует данными непосредственно. Итак, после того как пользователь посылает команду на изменение сущности, сервер ее обрабатывает и перекладывает в какую-то модель, которая оптимизирована на чтение — UI считывает это.

        Такой подход позволит вам следовать принципам REST очень легко. Если есть команда, значит, есть сущность «список команд».

        REST without PUT

        В простом CRUD-мире PUT — это штука, которая меняет объекты. Но если мы строго следуем принципу CQRS и делаем все через команды, PUT у нас пропадает, т. к. мы не можем менять объекты. Вместо этого можем лишь послать объекту команду на изменение. При этом можно отслеживать статус выполнения, отменять команды (DELETE), легко хранить историю изменений, а пользователь ничего не изменяет, а просто сообщает о намерениях.

        Парадигма REST without PUT — пока еще спорная и не до конца проверенная, но для каких-то случаев действительно хорошо применима.

        Fine-grained VS coarse-grained

        Представьте, что вы делаете большой сервис, большой объект. Тут у вас есть два подхода: fine-grained API и coarse-grained API («мелкозернистый» и «крупнозернистый» API).

        Fine-grained API:

        • Много маленьких объектов.
        • Бизнес-логика уходит на сторону клиента.
        • Нужно знать, как связаны объекты.
        • Создаете больше сущностей.
        • Сложно делать локальные изменения, например
          • POST /blogs//likes.
        • Нужно отслеживать состояние на клиенте.
        • Большие объекты нельзя сохранить частично.

        Для начала советую проектировать fine-grained API: каждый раз, когда вы создаете объект, отправляете его на сервер. На каждое действие на стороне клиента происходит обращение к серверу. Однако с маленькими сущностями работать проще, чем с большими: если вы напишете большую сущность, вам трудно будет потом ее распилить, трудно будет делать небольшие изменения и выдергивать из нее независимые куски. Т. ч. лучше начинать с маленьких сущностей и постепенно их укрупнять.

        Нумерация версий

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

        Какие известны на текущий момент варианты нумерации версий Web API?

        Самое простое — указать версию в URL.

        Вот готовые варианты, когда самому ничего делать не надо:

        Вот один интересный готовый вариант.

        Это всего лишь роутинг атрибутов с constraint — если вы делали какие-либо серьезные объекты, наверняка делали constraint. По номеру версии в этом атрибуте ребята просто реализовали constraint. Соответственно, на один и тот же атрибут с разными версиями, но одинаковым именем контроллера вешаете на два разных класса и указываете разные версии. Все работает «из коробки….

        Документация

        Как видите, Swagger вытащил все, что у нас есть, вытащил XML-комментарии.

        Ниже — полное описание модели GET. Если нажать на кнопку, он ее в самом деле выполнит и вернет результат.

        А вот так выглядит документация к POST, первая часть:

        Вот вторая часть:

        Все, что было написано в XML-комментариях, — здесь.

        Рассказ о том, как не надо проектировать API

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

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

        Обзор ситуации

        Организация, о которой идёт речь, использовала для управления жилыми помещениями систему Beds24. Сведения о том, что именно свободно, а что занято, синхронизировались с различными системами бронирования жилья (с такими, как Booking, AirBnB и другими). Организация занималась разработкой сайта и хотела, чтобы при поиске выводились лишь сведения о комнатах, свободных в указанный период времени и подходящих по вместимости. Подобная задача выглядела весьма простой, так как Beds24 предоставляет API для интеграции с другими системами. На самом же деле оказалось, что разработчики этого API допустили при его проектировании множество ошибок. Предлагаю разобрать эти ошибки, выявить конкретные проблемы и поговорить о том, как подходить к разработке API в рассматриваемых ситуациях.

        Проблема №1: формат тела запроса

        Так как клиенту интересны только сведения о том, свободен ли, скажем, гостиничный номер, или занят, нас интересует лишь обращение к конечной точке API /getAvailabilities . И, хотя обращение к подобному API должно приводить к получению данных о доступности комнат, это обращение, на самом деле, выглядит как POST-запрос, так как автор API решил оснастить его возможностью принимать, в виде JSON-тела запроса, фильтры. Вот список возможных параметров запроса и примеры принимаемых ими значений:

        Пройдёмся по этому JSON-объекту и поговорим о том, что здесь не так.

        1. Даты ( checkIn , lastNight и checkOut ) представлены в формате YYYYMMDD . Тут нет абсолютно никакой причины для того, чтобы не использовать стандартный формат ISO 8601 ( YYYY-MM-DD ) при преобразовании дат в строки, так как это — широко применяемый стандарт представления дат. Он знаком многим разработчикам, именно его ожидают получить на вход многие JSON-парсеры. Кроме того, возникает ощущение, что поле lastNight является избыточным, так как тут имеется поле checkOut , которое всегда представлено датой, на один день опережающей дату, заданную в lastNight . В связи с отмеченными выше недостатками предлагаю, при проектировании подобных API, стремиться к тому, чтобы всегда использовать стандартные способы представления дат и стараться не обременять пользователей API необходимостью работы с избыточными данными.
        2. Все поля-идентификаторы, а также поля numAdult и numChild , являются числовыми, но представлены в виде строк. В данном случае для представления их в виде строк нет никакой видимой причины.
        3. Здесь можно заметить следующие пары полей: roomId и roomIds , а так же propId и propIds . Наличие полей roomId и propId является избыточным, так как и то и другое можно использовать для передачи идентификаторов. Кроме того, тут можно заметить проблему с типами. Обратите внимание на то, что поле roomId является строковым, а в массиве roomIds нужно использовать числовые значения идентификаторов. Это может привести к путанице, к проблемами с парсингом, и, кроме того, говорит о том, что на сервере некоторые операции выполняются со строками, а некоторые с числами, несмотря на то, что эти строки и числа используются для представления одних и тех же данных.

        Мне хотелось бы предложить разработчикам API стараться не усложнять жизнь тем, кто этими API будет пользоваться, допуская при проектировании API ошибки, подобные вышеописанным. А именно, стоит стремиться к стандартному форматированию данных, к тому, чтобы они не были бы избыточными, к тому, чтобы для представления однородных сущностей не использовались бы разные типы данных. И не стоит всё, без разбора, представлять в виде строк.

        Проблема №2: формат тела ответа

        Как уже было сказано, нам интересна лишь конечная точка API /getAvailabilities . Давайте посмотрим на то, как выглядит ответ этой конечной точки, и поговорим о том, какие недочёты допущены при его формировании. Помните о том, что нас, при обращении к API, интересует список идентификаторов объектов, свободных в заданный период времени и способных вместить заданное количество людей. Ниже приведён пример тела запроса к API и пример того, что оно выдаёт в ответ на этот запрос.

        Поговорим о проблемах ответа.

        1. В теле ответа свойства ownerId и numAdult внезапно стали числами. А в запросе нужно было указывать их в виде строк.
        2. Список объектов недвижимости представлен в виде свойств объекта, ключами которых являются идентификаторы комнат ( roomId ). Логично было бы ожидать того, что подобные данные выводились бы в виде массива. Для нас это означает, что для того чтобы получить список доступных комнат, нужно перебрать весь объект, проверяя при этом наличие у вложенных в него объектов определённых свойств, вроде roomsavail , и не обращая внимания на что-то вроде checkIn и lastNight . Затем нужно было бы проверить значение свойства roomsavail , и, если оно больше 0, можно было бы сделать вывод о том, что соответствующий объект доступен для бронирования. А теперь давайте присмотримся к свойству roomsavail . Вот какие варианты его представления встречаются в теле ответа: «roomsavail»: «0» и «roomsavail»: 1 . Видите закономерность? Если комнаты заняты — значение свойства представлено строкой. Если свободны — оно превращается в число. Это способно привести к множеству проблем в языках, строго относящихся к типам данных, так как в них одно и то же свойство не должно принимать значения разных типов. В связи с вышесказанным мне хотелось бы предложить разработчикам использовать массивы JSON-объектов для представления неких наборов данных, а не применять для этой цели неудобные конструкции в виде пар ключ-значение, подобные той, что мы тут рассматриваем. Кроме того, нужно следить за тем, чтобы поля однородных объектов не содержали бы данные разных типов. Правильно отформатированный ответ сервера мог бы выглядеть так, как показано ниже. Обратите внимание и на то, что при представлении данных в таком виде сведения о комнатах не содержат дублирующихся данных.

        Проблема №3: обработка ошибок

        Вот как организована обработка ошибок в рассматриваемом здесь API: на все запросы система отправляет ответы с кодом 200 — даже в том случае, если произошла ошибка. Это означает, что единственный способ отличить нормальный ответ от ответа с сообщением об ошибке заключается в разборе тела ответа и в проверке наличия в нём полей error или errorCode . В API предусмотрены лишь следующие 6 кодов ошибок.

        Предлагаю всем, кто это читает, постараться не возвращать ответ с кодом 200 (успешная обработка запроса) в том случае, если при обработке запроса что-то пошло не так. Пойти на такой шаг можно лишь в том случае, если это предусмотрено фреймворком, на базе которого вы разрабатываете API. Возврат адекватных кодов ответов позволяет клиентам API заранее знать о том, нужно ли им парсить тело ответа или нет, и о том, как именно это делать (то есть — разбирать ли обычный ответ сервера или объект ошибки).

        В нашем случае улучшить API в этом направлении можно двумя способами: можно либо предусмотреть особый HTTP-код в диапазоне 400–499 для каждой из 6 возможных ошибок (лучше всего поступить именно так), либо возвращать, при возникновении ошибки, код 500, что позволит клиенту, по меньшей мере, знать перед разбором тела ответа о том, что оно содержит сведения об ошибке.

        Проблема №4: «инструкции»

        Ниже приведены «инструкции» по использованию API из документации проекта:

        Пожалуйста изучите следующие инструкции при использовании API.

        1. Обращения к API следует проектировать так, чтобы в ходе их выполнения приходилось бы отправлять и принимать минимальный объём данных.
        2. Обращения к API выполняются по одному за раз. Необходимо дождаться выполнения очередного обращения к API прежде чем выполнять следующее обращение.
        3. Если нужно выполнить несколько обращений к API, между ними следует предусмотреть наличие паузы длительностью несколько секунд.
        4. Вызовы API нужно выполнять не слишком часто, поддерживая уровень обращений на минимальном уровне, необходимом для решения задач клиента.
        5. Чрезмерное использование API в пределах 5-минутного периода приведёт к блокировке вашей учётной записи без дополнительных уведомлений.
        6. Мы оставляем за собой право блокировать доступ к системе клиентам, которые, по нашему мнению, чрезмерно используют API. Делается это по нашему усмотрению и без дополнительных уведомлений.


        В то время как пункты 1 и 4 выглядят вполне обоснованными, с другими пунктами этой инструкции я согласиться не могу. Рассмотрим их.

        1. Пункт №2. Если вы разрабатываете REST API, то предполагается, что это будет API, не зависящее от состояния. Независимость обращений к API от предыдущих обращений к нему — это одна из причин того, что технология REST нашла широкое применение в облачных приложениях. Если некий модуль системы не поддерживает состояние, его, в случае ошибки, можно легко развернуть повторно. Системы, основанные на подобных модулях, легко масштабируются при изменении нагрузки на них. При проектировании RESTful API стоит следить за тем, чтобы это было API, не зависящее от состояния, и чтобы тем, кто его использует, не приходилось бы беспокоиться о чём-то вроде выполнения только одного запроса за раз.
        2. Пункт №3. Этот пункт выглядит довольно странно и неоднозначно. Я не могу понять причину, по которой был написан этот пункт инструкции, но у меня возникает ощущение, что он говорит нам о том, что в процессе обработки запроса система выполняет некие действия, и, если её при этом «отвлечь» ещё одним запросом, отправленным не вовремя, это может нарушить её работу. Кроме того, то, что автор руководства говорит о «нескольких секундах», не позволяет узнать точной длительности паузы, которую нужно выдержать между последовательными запросами.
        3. Пункты №5 и №6. Тут говорится о «чрезмерном использовании API», но никаких критериев «чрезмерного использования» не приводится. Может, это 10 запросов в секунду? А может — 1? Кроме того, некоторые веб-проекты могут иметь огромные объёмы трафика. Если без каких-то адекватных причин и без уведомлений закрывать им доступ к нужным им API, их администраторы, наверняка, от использования таких API откажутся. Если вам доведётся писать подобные инструкции — используйте в них чёткие формулировки и ставьте себя на место пользователей, которым придётся работать с вашей системой, руководствуясь вашими инструкциями.

        Проблема №5: документация

        Вот как выглядит документация к API.

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

        Для создания подобных материалов рекомендуется пользоваться специальными инструментами. Если речь идёт о простых документах, похожих на вышеописанный, то для их оформления вполне достаточно чего-то вроде обычного markdown-файла. Если документация устроена сложнее, то для её оформления лучше всего воспользоваться инструментами наподобие Swagger или Apiary.

        Кстати, если сами хотите взглянуть на документацию к API Beds24 — загляните сюда.

        Проблема №6: безопасность

        В документации ко всем конечным точкам API сказано следующее:

        Для использования этих функций должен быть разрешён доступ к API. Это делается в меню SETTINGS → ACCOUNT → ACCOUNT ACCESS.

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

        Большинство JSON-методов требуют ключ API для доступа к учётной записи. Ключ доступа к API можно установить, воспользовавшись меню SETTINGS → ACCOUNT → ACCOUNT ACCESS.

        В дополнение к непонятному разъяснению вопросов аутентификации оказывается, что ключ для доступа к API пользователь должен создавать самостоятельно (делается это, кстати, путём ручного заполнения соответствующего поля, какие-то средства для автоматического создания ключей не предусмотрены). Длина ключа должна быть в пределах от 16 до 64 символов. Если позволить пользователям самостоятельно создавать ключи для доступа к API, это может привести к появлению весьма небезопасных ключей, которые можно легко подобрать. В подобной ситуации возможны и проблемы, связанные с содержимым ключей, так как в поле для ключа можно ввести всё что угодно. В худшем случае это может привести к атаке на сервис методом SQL-инъекции или к чему-то подобному. При проектировании API не позволяйте пользователям создавать ключи для доступа к API самостоятельно. Вместо этого генерируйте для них ключи автоматически. Пользователь не должен иметь возможности изменить содержимое такого ключа, но, при необходимости, он должен иметь возможность сгенерировать новый ключ, признав старый недействительным.

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

        Если токен аутентификации передаётся в теле запроса — это означает, что серверу, прежде чем он доберётся до ключа, нужно будет разобрать тело запроса. После этого он извлекает ключ, выполняет аутентификацию, а затем уже решает — что ему делать с запросом — выполнять его или нет. Если аутентификация удалась — то сервер не будет подвержен дополнительной нагрузке, так как в таком случае тело запроса всё равно пришлось бы разбирать. А вот если аутентифицировать запрос не получилось, то ценное процессорное время будет потрачено на разбор тела запроса впустую. Лучше будет отправлять токен аутентификации в заголовке запроса, используя что-то наподобие схемы аутентификации Bearer. При таком подходе серверу понадобится разбирать тело запроса лишь в том случае, если аутентификация окажется успешной. Ещё одной причиной, по которой для аутентификации рекомендуется использовать стандартную схему наподобие Bearer, является тот факт, что с подобными схемами знакомо большинство разработчиков.

        Проблема №7: производительность

        Эта проблема в моём списке последняя, но это не умаляет её важности. Дело в том, что на выполнение запроса к рассматриваемому API уходит немного больше секунды. В современных приложениях такие задержки могут оказаться недопустимыми. Собственно говоря, тут можно посоветовать всем, кто занимается разработкой API, не забывать о производительности.

        Итоги

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

        Поэтому я хотел бы попросить всех, кто проектирует API, думать о том, как с ним будут работать пользователи их сервисов. Следите за тем, чтобы документация к API полно описывала бы их возможности, чтобы она была бы понятной и хорошо оформленной. Контролируйте именование сущностей, обращайте внимание на то, чтобы данные, которые выдаёт или принимает ваше API, были бы чётко структурированными, чтобы с ними было бы легко и удобно работать. Кроме того, не забывайте о безопасности и о правильной обработке ошибок. Если при проектировании API принять во внимание всё то, о чём мы говорили, тогда для работы с ним не понадобится писать нечто вроде тех странных «инструкций», которые мы обсуждали выше.

        Как уже было сказано, этот материал направлен не на то, чтобы отбить у читателей охоту пользоваться Beds24 или любой другой системой с плохо спроектированным API. Моя цель заключалась в том, чтобы, продемонстрировав примеры ошибок и подходы к их решению, дать рекомендации, следуя которыми все желающие могли бы повысить качество своих разработок. Надеюсь, этот материал привлечёт внимание прочитавших его программистов к качеству разрабатываемых ими решений. А это значит, что в мире будет больше хороших API.

        Книги о проектировании и разработке программного обеспечения

        Шаблоны проектирования

        Э. Гамма Приемы объектно-ориентированного проектирования. Паттерны проектирования / Э. Гамма, Р. Хелм, Р. Джонсон, Д. Влиссидес. – СПб.: Питер, 2009. – 366 с.

        Классическая и наиболее известная книга о шаблонах проектирования. Описание каждого шаблона достаточно подробное, обычно содержит несколько вариантов реализации с их слабыми и сильными сторонами. Примеры в книге приведены на C++ и Smalltalk, однако словесное описание и UML диаграммы помогут разобраться программистам на других языках. Рекомендую посмотреть книгу всем без исключения будущим программистам.

        Джейсон Мак-Колм Смит Элементарные шаблоны проектирования : Пер. с англ. — М. : ООО “И.Д. Вильямс”, 2013. — 304 с.

        Книга Мак-Колма более похожа на научный труд, чем на учебник, однако, является достаточно интересной и полезной. В первую очередь рассматриваются элементарные шаблоны — такие, как делегирование, наследование, рекурсия. Затем, показывает как из элементарных шаблонов построить более сложные — при этом шаблоны рассматриваются крайне подробно. Достаточно полезной показалась система обозначений PIN (Pattern Instance Notation), разработанная автором в качестве расширения UML. PIN используется на протяжении всей книги, т.к. позволяет элегантно отображать зависимости между паттернами, не вникая в детали их реализации. В конце приводится описание \(\rho\)-исчисления, являющегося формальной теорией, лежащей в основе шаблонов проектирования. Я рекомендую посмотреть книгу всем программистам, которые этого еще не сделали — будет интересно.

        Влиссидес Джон. Применение шаблонов проектирования. Дополнительные штрихи. : Пер. англ. М.: Издательский дом «Вильямс

        Хорошее дополнение к книге Гаммы и Хелма с несколько другим способом изложения и местами более интересными примерами. Начинается книга с заблуждений о шаблонах — далеко не все, особенно студенты, понимают как ими пользоваться. По ходу книги автор ставит перед читателем ряд проблем и всякий раз выполняет поиск подходящих шаблонов проектирования, при этом приводится даже некоторый алгоритм выполнения такого поиска. Первым примером книги является проектирование файловой системы (с сущностями «Файл», «Каталог», «Ярлык»), на нем рассматриваются паттерны Composite, Proxy (для реализации «Ярлыка» файла — этот пример сильно отличается от того, что приведено в GoF), Visitor (тоже очень удачное применение) и Template Method (в контексте рефакторинга и инверсного управления). Затем, в пример добавляется владелец файла, но пользователей нужно создавать, а еще они объединяются в группы. На примере системы управления пользователями рассматриваются шаблоны Singleton и Mediator (для связи пользователей с группой «многие ко многим»). В конце второй главы приводится хорошая диаграмма «pattern: role annotation». В третьей главе рассматриваются тонкости и проблемы реализации шаблонов — начинаются с Singleton-а (проблема с зависимостями между несколькими Одиночками, параллельным программированием и освобождением памяти из под них). Затем также рассматривается Observer и Visitor (на мой взгляд, выбран слишком примитивный пример с построением графического интерфейса из двух полей ввода и кнопкой). В конце главы описывается «нестандартный» шаблон Generaton Gap — лично я про него читал впервые, применить вы его сможете лишь в тех случаях если ваша система генерирует исходный код программ, рассматривается он на примере генератора пользовательского интерфейса (типа Qt Designer), но отмечается что нечто подобное используется в YACC. Цель паттерна Generaton Gap — убрать зависимость между сгенерированным системой кодом и тем, что дописывает потом вручную пользователь, для этого предлагается, казалось бы очевидное решение — генерируемый код помещается в базовый класс, который пользователь может наследовать для увеличения функциональности (хотя я бы рассмотрел также вариант с композицией). Последним примером книги является система обработки событий (Event), при этом ставится проблема — типов событий много, но, получив событие, мы не хотим выполнять кучу dynamic_cast для установления его типа. На этом примере описаны шаблоны Mulicast и Typed Message — лично мне это показалось бесполезным. В конце книги приводится рекомендации по разработке шаблонов проектирования (семь правил, которые помогут вам придумать новый шаблон) — я бы назвал это правилами по изучению шаблонов (советую прочитать). В целом, хорошая книга, но с плохим переводом (очень много явных ляпов) и местами устаревшая (т.к. примеры написаны на С++, который развивался и сильно изменился, а книга старая) — например не совсем правильно подмечены недостатки Singleton-а Маерса и описан неактуальный подход с Double-Clecked Locking (хотя для истории и кругозора может пригодится).

        Тепляков С. В. Паттерны проектирования на платформе .NET – СПб.: Питер, 2015. – 320 с.

        Замечательная книга от разработчика компании Microsoft и известного в узких кругах блогера (до выпуска книги Сергей много писал на тему паттернов проектирования на своем сайте). Не смотря на то, что в названии фигурирует .NET, книга будет полезна всем без исключения разработчикам (в книге Гаммы тоже приводятся примеры на Smalltalk, но это не мешает ей быть классикой). Главы книги можно читать в любом порядке, т.к. они не связаны друг с другом — как и в книге Гаммы разделение по главам осуществляется на основе типов паттернов (паттерны поведения, порождающие паттерны, структурные паттерны), кроме того, есть глава посвященная принципам SOLID. Рассматриваются вопросы unit-тестирования в контексте применения шаблонов проектирования.

        UML и объектно-ориентированный анализ

        Буч Градди Объектно-ориентированный анализ и проектирование с примерами приложений, 3-е изд. / Буч Градди, Максимчук Роберт А., Энгл Майкл У., Янг Бобби Дж., Коналлен Джим, Хьюстон Келли А.: Пер с англ. — М.: ООО «И.Д. Вильямс», 2010. — 720 с.

        Классическая книга по программированию от очень авторитетного автора. В книге есть множество интересных и важных для программиста вещей, но они обильно разбавлены рассуждениями на отвлеченные темы и, на мой взгляд, очень неудачными примерами про теплицы. Во второй вам расскажут про общие принципы ООП; в третьей главе — дополнят некоторыми обозначениями UML и интересным разделом про качество классов и объектов; в четвертой — рассматриваются различные подходы к классификации и уточнению абстракций. Пятая глава книги содержит описание 13 видов UML диаграмм, но на мой взгляд Буч выбрал не самые лучшие примеры и недостаточно времени уделил описанию назначения этих диаграмм. Шестая глава содержит описание процесса разработки программного обеспечения, при этом выделяются макропроцесс (жизненный цикл проекта) и микропроцесс (проектирование) — для них описываются стадии с видами деятельности на каждой из них. Седьмая глава завершает изложение очень коротким описанием организационных вопросов. Вторую половину книги составляют примеры приложений (можно посмотреть в каком порядке Буч предлагает их проектировать и какие виды диаграмм использовать).
        Все главы кроме пятой очень обзорные — в них нет смысла вчитываться, по этим темам написаны отдельные толстые книги. Например, про качество ПО в нескольких книгах рассуждает Роберт Мартин, а про проектирование ПО (микропроцесс) написал отдельную книгу Розенберг — при этом он использует другой подход (ICONIX). Очень часто долгие рассуждения Буча касаются очевидных вещей и как бы вы не вчитывались — не получится узнать что-то новое, поэтому я считаю, что книгу достаточно бегло просмотреть. Наиболее полезные, на мой взгляд, части книги:

        • описание элементов объектной модели во второй главе;
        • большая часть третьей главы, посвященная основам ООП;
        • описание UML в пятой главе;
        • по диагонали можно прочитать шестую главу и просмотреть несколько примеров из приложения.
        Розенберг Д., Скотт К. Применение объектного моделирования с использованием UML и анализ прецедентов.: Пер. с англ. М.: ДМК Пресс, 2002

        Книга посвящена разработке программного обеспечения в соответствии с процессом ICONIX, поэтому несмотря на то, что в названии фигурирует UML — рассматриваются всего 4 вида диаграмм (прецедентов, пригодности, последовательности и классов). Диаграмма пригодности не описана во многих других книгах по UML, т.к. в стандарте UML она описана в дополнении. В книге не только описываются сами диаграммы, но и процесс разработки ICONIX, который является итеративным, что оказывает влияние на процесс построения диаграмм. Каждому виду диаграммы посвящена отдельная глава, в конце которой приводится топ 10 ошибок — это тоже очень полезная и интересная часть. Книга в 7 раз тоньше произведения Буча, а полезной информации, на мой взгляд, в ней больше.

        Буч Г., Рамбо Д., Джекобсон А. Язык UML Руководство пользователя — С-П.: Издательство «Питер», 2010 — 432 с.

        Долгое время единственной действительно хорошей книгой, посвященной объектно-ориентированному анализу и проектированию, была книга Буча, в которой рассматривалась его нотация. Основываясь на ней, конечно же, можно было понять UML, но почему-то лишь немногие были на это способны. В тоже самое время, иногда появлялись какие-то журнальные статьи, в которых упоминался UML. Обычно эти статьи не отличались подробностью и просто пересказывали то, что когда-то услышал автор по этой теме. Вообще, это происходит потому, что практикующие пользователи UML редко когда пишут статьи.

        Практически каждый программист слышал словосочетание Rational Rose, но обычно плохо себе представляет что это такое. Мало того, традиционна следующая ситуация: программист что-то услышал о программном продукте, с радостью его установил себе на компьютер (давайте не будем уточнять, как он достал себе копию), запустил программу… а она оказалась совсем не похожей на WinWord. Т.е., как нарисовать стрелку ясно, а что за ней стоит и как это потом использовать — непонятно.

        Надо сказать, что использование CASE продуктов подразумевает наличие хотя бы базовых знаний об используемой технологии. Я сомневаюсь, что человек, основываясь на одном лишь здравом смысле, сможет понять зачем нужна Rational Rose. По крайней мере потому, что там используется специфическая терминология для выбранной нотации.

        Так вот, эта книга, является одной из трех книг, написанных создателями UML. Это полное изложение UML, позволяющее читателю изучить его и приступить к практическому использованию. В книге не рассматриваются принципы объектно-ориентированного анализа, поэтому от читателя потребуется знакомство с ним (например, по соседней книге Буча).

        Поэтому, если вы уже применяете UML достаточно долгое время, то «Руководство пользователя» вряд ли будет для вас обладать какой-то особенной ценностью, но если вы хотите овладеть им — нверное, это то что нужно.

        Итог:
        Книга, несомненно, достойна того, что бы ее прочитали хотя бы для ознакомления с нотацией. Она не является основополагающей, как «Объектно-ориентированный анализ и проектирование» Гради Буча, но все равно достаточно интересна.

        Чистый код и рефакторинг

        Мартин Р. Чистый код. Создание, анализ и рефакторинг. Библиотека программиста. — СПб.: Питер, 2014. — 464 с.

        Книга посвящена вопросам написания программного кода, который легко поддерживать — обсуждаются не только стили кодирования, форматирования, но и, например, структура хорошего кода, юнит-тестирование, использование исключений. В контексте чистого кода описываются некоторые шаблоны проектирования. Альтернативой можно считать книгу Фаулера (она также посвящена чистому коду), но Роберт Мартин пишет гораздо интереснее. Рекомендую прочитать книгу всем студентам, прошедшим курс объектно-ориентированного программирования.

        Фаулер М. Рефакторинг. Улучшение существующего кода/ М. Фаулер. Символ-Плюс, 2008. 432 с.
        Аллен Э. Типичные ошибки проектирования / Э.Аллен: Пер. с англ. – СПб.: Питер, 2003. – 224 с.

        Книги Мартина Фаулера и Эрика Аллена посвящены чистому коду и рефакторингу, но в отличии от книги Боба Мартина, в них делается попытка каталогизации видов рефакторинга (у Фаулера) или ошибок (у Аллена). Если вы разрабатывали что-то чуть-чуть сложнее тетриса — то книги читаются быстро т.к., значительная часть материала вам и так знакома. Книги стоит пролистать, бегло найти интересные моменты и посмотреть их более детально. Покупать их не стоит (я взял на работе почитать), вряд-ли вы будете это перечитывать. С другой стороны, знакомый тимлид требует от работников при рефакторинге указывать конкретный вид (название берется из каталога вот этой книги) в комментарии к коммиту в репозитории. Из книги Аллена мне больше всего понравились главы 2, 3 и 22 — в них можно кое-что узнать об экстремальном программировании, спецификации и тестировании, а также прочитать краткое (но достаточное) описание «паттернов проектирования для отладки». Советую читать именно эти главы.

        Другое

        Чакон Скотт, Страуб Бен Git для профессионального программиста. — СПб.: Питер, 2020. — 496 с.: ил.

        В книге автор рассказывает про систему контроля версий «git», при этом делает это не поверхностно (как многочисленные статьи в интернете), а очень подробно. Главы выстроены таким образом, чтобы читатель сразу мог начать пробовать некоторые команды git, а затем узнавать про различные варианты их использования. Очень помогает читать обилие иллюстраций к примерам. Книга настолько полно описывает git, что после нее по этой теме можно читать только stack overflow (какие-то конкретные вопросы все равно будут возникать), но вы будете уметь работать в команде, использующей git, выбирать оптимальный вариант использования git для своей команды, настраивать git на сервере и т.д.

        С. Бобровский Технологии Пентагона на службе российских программистов. Программная инженерия. — СПб.: Питер, 2003. — 222 с.: ил.

        Основная проблема, обсуждаемая в книге — ошибки в программах. В контексте проблемы рассматриваются модели разработки ПО и управления проектами и языки программирования. Книга состоит из четырех глав:

        1. Очень коротко описываются подходы, позволяющие повысить качество продукта (в т.ч. сократить число ошибок): гибкие практики (Agile), развитие качеств программиста — профессиональные и личностные качества, особое внимание уделяется обучению и мотивации.
        2. Описание истории развития языков программирования. Акцент делается на влияние на этот процесс спец. служб в 20 веке. Кроме того, много написано о том, что большая база кода на устаревших языках мешает забыть о них и, следовательно, препятствует развитию более совершенных языков.
        3. Очень коротко описываются подходы к управлению процессом разработки ПО — такие как C/SCSC и CMM. В частности это процессы управления рисками (превышения бюджета проекта или сроков). Из главы можно узнать о сути предлагаемого подхода их достоинствах и недостатках. Чтобы использовать методики информации недостаточно, к сожалению в книге нет ссылок на литературу, где эту информацию можно получить.
        4. Описаны 2 японских проекта связанных с разработкой систем параллельной обработки данных. Более подробного описания проекта ЭВМ 5 поколения на русском языке я не встречал.

        Итог: интересная книга для общего развития. Первая глава слишком поверхностная и посвящена скорее вопросам психологии и мотивации личностного роста программиста. Вторая и четвертая главы имеют полностью обзорный и исторических характер — с их помощью можно расширить кругозор, но не более. Наиболее полезной является третья глава, но ее стоит читать только в том случае если вы решили заняться управлением проектами и никаких других книг по этой теме не читали.

        Брукс, Ф. Мифический человеко-месяц или как создаются программные системы / Ф. Брукс. — М.: СПб: Символ-Плюс, 2020. — 304 c.

        Эта книга не о программировании на конкретном языке. В ней очень ясным, живым языком рассказывается о тех выводах, к которым пришел автор в процессе руководства работы над операционной системой OS/360. Некоторые моменты, конечно же, устарели; например, проблема машинного времени уже не стоит в таком остром ракурсе перед программистами (во всяком случае, в большинстве проектов). Тем не менее, общие рекомендации по обеспечению работы большой группы программистов очень сложно переоценить. Например, вы можете сразу же ответить, что лучше: тысяча посредственных программистов, сто хорошиих или десять гениев? Имеется в виду, для реализации очень крупного проекта в разумное время. Я не говорю о том, что в книге есть ответ на этот вопрос — в книге есть очень полезные мысли на эту тему, которые пригодятся вам при начале работы и наборе сотрудников.

        «Мифический человеко-месяц» — это, судя по тому что это выражение вынесено в название, для Брукса самый важный момент в книге. Брукс пишет о том, что нельзя мерять время выполнения проекта просто линейно считая, что если один человек сделает его за сто лет, то сто человек сделают его за один год.

        От первого издания отличается тем, что в него добавлена статья «Серебряной пули нет», в которой Брукс двадцать лет назад предупреждал о том, что в течение этих лет в программировании ничего революционного не произойдет и статьей, которая была написана специально для второго издания. Эта статья посвящена актуальным аспектам проектирования и ответу на вопрос о том, почему же «Мифический человеко-месяц» до сих пор остался современным.

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

        Проектирование API

        Создании API не похоже на разработку типичного веб-приложения. В API нет пользовательского интерфейса, но есть интерфейс для взаимодействия программ. Часто из-за этого создание API занимает гораздо больше времени, чем планируется в начале. Хочу поделиться соображениями, которые позволяют тратить меньше времени на разработку API.

        Используйте HTTP

        В качестве базового протокола для API удобно использовать HTTP по ряду причин:

        • в большинстве языков программирования есть библиотеки для работы с HTTP, что сокращает время разработки клиента и сервера;
        • HTTP – текстовый протокол, это упрощает его отладку;
        • при использовании HTTP будет минимум проблем с прокси-серверами;
        • при необходимости HTTP можно расширять.

        Используйте REST

        Архитектура REST делает API простым для изучения и разработки. Неочевидный её плюс – упрощение процедуры инвалидации кэша.

        Используйте JSON

        Хороший формат вывода данных в API уменьшает время разработки не только сервера, но и клиентских приложений. Я рекомендую использовать JSON: он занимает мало места, является текстовым (я значит прост в отладке), и для него можно написать клиент прямо в JavaScript-консоли браузера.

        Предусмотрите механизм версионирования

        С изменениями в API есть одна проблема – их нельзя делать без риска поломать клиенты, которые используют это API. Если ваши клиенты – мобильные приложения, то часть из них обязательно не будет обновляться.

        Чтобы изменения не поломали обратную совместимость, можно выпустить новую версию API. Версионирование API на HTTP можно делать с помощью с помощью URL http://example.com/api/v1/friends.json , или заголовка, в котором клиент указывает нужную версию API.

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

        Документируйте API

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

        Простого описания в гугл-документе может быть достаточно. Для каждого запроса укажите: назначение, способ вызова, пример ответа и список возвращаемых ошибок. Хорошая документация к API описывает его возможности, даёт примеры запросов для «быстрого старта», и описывает общие процедуры – паджинацию, авторизацию, формат вывода данных.

        Смотрите также

        Мысли о веб-разработке на Ruby on Rails: работа с кодом, приёмы, инструменты, организация процесса разработки.

        Лучшие практики проектирования и реализации API на C#

        C# – мощный и красивый объектно-ориентированный язык. Но мощь сама по себе не гарантирует, что всё написанное вами на C# будет эталоном. «Кривой» код встречается даже у опытных программистов, особенно если они пришли с других языков и платформ . И ладно бы некрасивости были связаны с реальными сложностями. Нет же! Кривизна возникает и в таких простых вещах, как именование элементов в соответствии со спецификацией языка C#. Многие не умеют выбрать между структурой и классом, не отличают команду от запроса и так далее. Если хотите, чтобы коллеги любили ваш код – этот вебинар для вас! Мы разберем:

        • Принципы именования классов, переменных и т.д.
        • Как выбрать между классом и структурой.
        • Как выбрать между абстрактным классом и интерфейсом.
        • Как выбрать между методом и свойством.
        • Чего не стоит делать в конструкторе.
        • Когда фабрика лучше конструктора.
        • Как реализовать паттерн Dispose.
        • Признак «одержимости примитивами».
        • Скрытые зависимости.
        • Нарушения закона Деметры.
        • Временные связанности.
        • Когда хорош Switch-Case.

        В первую очередь вебинар будет полезен:
        – начинающим со знанием основ C# (без минимального знакомства с языком не все будет понятно),
        – тем, кто переходит на C# с другого языка.

        В некоторых разделах даже middle-девелоперы могут найти для себя что-то новое.

        Мастер Йода рекомендует:  Выбор CMS, которую полюбит ваша организация
Добавить комментарий