Есть мнение, что Swift — особенно благодаря развитию в опенсорсе — уже сейчас применим за рамками софта для платформ Apple. Наши коллеги из «Рамблера», включая разработчика Самвела Меджлумяна, даже пробуют этот язык в качестве серверного решения. На встрече сообщества CocoaHeads Самвел перечислил готовые продукты для построения сервера на Swift, сравнил их между собой и показал короткое демо.
— Меня зовут Самвел, я iOS-разработчик в «Рамблере». До прихода в мобильную разработку я долгое время занимался серверными продуктами, различными интеграционными системами, таргетинговыми системами, предоставляющими API для сторонних ресурсов, сайтов наших веб-мастеров и партнеров. На данный момент я занимаюсь проектом «Афиша Рестораны».
Под конец небольшой бонус, как организовать хороший API, парочка лучших практик и мое мнение относительно перспектив S3.
Надеюсь, многие из здесь присутствующих разделяют мою симпатию к Swift. Это потрясающий инструмент, который предоставляет нам огромные возможности, а сейчас еще и возможность реализовывать серверную часть. И мы можем реализовывать end to end на Swift, это потрясающе.
Вернемся на пару лет назад. 2 июня 2014 года я сидел в комнате общаги Саратовского меда. Это не столь важно для здесь присутствующих, если не учитывать того, что в этот день я, как и многие из вас, ждал важного события. Речь о WWDC, на которой Apple представила Swift. И уже через год с небольшим, 3 декабря 2015 года, Apple заопенсорсила Swift, выпустив его под лицензией Apache для Linux и OS X. Это было большое событие, это запустило огромную волну различных проектов и дополнительно смотивировало тех разработчиков, которые еще с первой беты хотели активно распространять Swift за пределами разработки для Apple-девайсов. Потрясающее время.
Давайте копнем первопричину. Это апрельская статистика доли интернет-трафика. Огромное число, которое предполагает, что большинство приложений, которые мы используем и, тем более, которые, я хочу верить, разрабатываем, имеют подключение к сети и различным сервисам.
Таким образом, бизнес-логика наших приложений так или иначе разделена на части. Это вызывает определенные зависимости. Часть логики, будь то авторизация приложений или бронирование столика, у нас находится на бэке. Это создает проблемы, зависимости. Мы все не любим зависимости. В конечном итоге это ограничивает нас.
Это если не учитывать того факта, что большинство бэкендщиков достаточно ревностно относятся к нашим пожеланиям, замечаниям, просьбам что-то изменить в API, добавить, поправить. Можно изучить самостоятельный инструмент, стать бэкендщиком самому, но это решает задачу только для нас. Что насчет команды? Предположим, что у нас iOS-команда и надо реализовать серверную утилиту для своих нужд. Например, в «Рамблере» есть дашрамба, написанная на Ruby, и поддержка сейчас достаточно проблематична.
Реализация end to end на Swift решает эту и ряд других проблем.
Понятие фреймворка на бэке отчасти отличается от привычного нам. По определению из вики, фреймворк — программная система, каркас, который позволяет организовать нашу систему. Это некая платформа. Это не библиотека, это не дополнительный язык, не новый для нас язык. В использовании фреймворка для любого нормального разработчика нет ничего сверхъестественного.
На данный момент есть четыре активно развивающихся инструмента. Общее количество звезд репозиториев этих инструментов достигает 31 тыс. Причем самый старый инструмент — Perfect, ему чуть больше полутора лет.
Для сравнения, у «рельсов» за семь лет всего 35 тыс. Развитие сообщества идет колоссальными шагами.
Предлагаю сравнение компонентов и перейдем к демо.
Комьюнити. При запуске проекта это очень важно. Здесь выделяется Perfect и Vapor, у них огромное сообщество, огромное количество контрибьютеров, подписчиков в Твиттере, активнейшие каналы в Slack, где вы можете оперативно получить ответ на любой ваш вопрос.
Что касается Kitura и Zewo — готовьтесь копать много кода, вы не получите быстрых ответов, но у них есть другие фишки. Впрочеам, у Zewo последний коммит был сделан 13 января 2017 года, хотя фреймворк, кажется, развивается.
Языки. За исключением Vapor у всех инструментов есть одна, две или более зависимостей на С. У Perfect это HTTP-сервер, у Kitura шаблонизаторы реализованы на С. Различные криптографические библиотеки. Отчасти это оправдывает себя в скорости.
Если посмотреть доступные онлайн-бенчмарки, то Vapor проигрывает всем фреймворкам и Node.JS. Это бенчмарк по использованию памяти и бенчмарк по обработке и выдаче JSON.
У меня есть информация, что в новой версии, которая на стадии беты, эта проблема решена и там все оптимизировано, поэтому ждем стабильной версии.
Что касается работы с БД, то она одинаково хорошо реализована практически во всех инструментах за исключением Zewo, там немного проблематично. Perfect и Vapor предоставляют огромное количество провайдеров для организации доступа к разным реляционным базам данных.
Какой у меня выбор? Несмотря на то, что Vapor уступает всем инструментам в скорости, я выбираю этот фреймворк. Он лаконичен, его синтаксис не может не нравиться Swift-разработчику, плюс подкупает идеологическая приверженность исключительно Swift style, плюс Vapor имеет огромное сообщество, достаточно активное, они фичерят, постоянно вносят новые изменения. Так что это мой выбор.
Что вам нужно сделать, чтобы установить и развернуть систему? Первое — поставить тулбокс. Тулбокс Vapor — всего лишь обертка для терминала, которая позволяет в удобной форме вызывать те или иные команды. Просто попросите brew, он все сделает за вас.
Создайте новый проект. Вы можете указать в качестве параметра template любой шаблон, который найдете на GitHub.
Третьим шагом перейдите в папку проекта и сбилдите его. Первый билд вызывает закачку зависимости сети. Чтобы избежать факапов с сетью, я сделал преинкрементальную сборку заранее.
Запустите ваш сервер, и все готово.
Помимо этого рекомендую вызвать команду xcode, которая создаст вам таргет, это привычная для вас среда разработки, ничего сверхъестественного.
Из каких частей состоит скомпилированный проект сервера?
Прежде всего это Package.swift. Ничего сверхъественного в этом файле нет, многие с ним знакомы, это пакет зависимостей, который подтягивает необходимые нам либы с сервера. И MySQL-провайдер.
Я бы хотел отдельно отметить файл main.swift, который инициализирует дроплет-объект. Это core layer, предоставляющий нам доступ ко всем остальным фишкам Vapor.
Здесь также закидывается роутинг для индекс-запроса, который показывает нам view welcome и запускается. Предлагаю запустить сервер и посмотреть, как все это прекрасно.
Сервер запущен, он находится по адресу localhost на порте 8080.
Кто хочет воочию посмотреть процесс установки Vapor, компиляции, подтягивания зависимостей — я в перерыве покажу, как вызвать команды в терминале и наслаждаться этим процессом.
Конфиги сервера находятся в папке configs. Вы можете настраивать необходимые параметры и изменять порт вашей системы. Порт по дефолту — 8080.
Вернемся в наш проект. Такой сервер бесполезен, если только вы не хотите делать какой-то сайт-визитку, чтобы показать своим друзьям. И само собой, если вы хотите сделать что-то большее, надо подключить БД.
Как работает Vapor с разными реляционными БД? У нас имеется драйвер, который обеспечивает взаимодействие с базой. К нему подключается провайдер. Под капотом драйвер взаимодействует с движком Fluent, разработанным ребятами из Vapor. Мы работаем непосредственно с MySQL-провайдером. Воспринимайте этот провайдер как persistent store в core data, тогда все станет понятно.
В качестве базы я выбрал MySQL. Для его установки надо вызвать две команды — brew install mysql и запускаем MySQL-сервер.
Давайте создадим БД. У меня есть заготовка, дамп базы находится в проекте, который будет доступен после презентации. Это единственная таблица, которая содержит четыре поля с событиями о мероприятиях CocoaHeads, которые мы хотим выдавать нашим API.
Для создания и управления БД после установки MySQL вы можете использовать различные утилиты, необязательно вызывать эти команды из терминала. Один из таких инструментов — Sequel Pro. Это утилита, интерфейс которой ничуть не отличается от интерфейса управления объектами core data в Xcode. Та же структура: создаете объекты, создаете к ним поля, указываете контент, данные.
Предлагаю показать, как подключить провайдер. Необходимо импортировать VaporMySQL и добавить провайдер в drop-объект. Выполняется это одной командой — addProvider(VaporMySQL.Provider.self). В принципе, уже все готово для работы с БД, этого достаточно.
После запуска проекта вы увидите, что сервер запущен. Нет подготовленных объектов.
При запуске и установке нового объекта у вас из коробки идут модельки. Они должны сопоставляться с таблицами, которые вы создаете в своих базах. В данном случае у меня моделька event, которая полностью соответствует таблице в базе MySQL. Чтобы ее подключить к своему провайдеру, я вызываю команду preparation module, моделька добавляется в мой провайдер.
В принципе, всё. Я могу отправлять этот объект по разному роутингу и получить их на сервере.
Добавляем группу запросов для пути версии API 1. Событие events будет обрабатывать event controller. Запускаем проект, видим, что DPS prepared, БД полностью подключена.
Давайте проверим запрос, который находится по адресу events. Группа запросов и сама сущность. Мы получаем наше событие, и API работает буквально в три строчки, не считая подключения базы.
Предлагаю показывать все объекты, не только те, на которых регистрация открыта. Сам процесс работы с какими-то компонентами Vapor ничуть не отличается от работы с Realm, core data, и вам достаточно 20-30 минут на изучение каких-то компонентов, чтобы запустить это. И из коробки у вас все будет готово. Проверим запрос. Получаем все события, которые имеются в БД.
Вернемся к докладу. Накину пару принципов про организацию хорошего API. Плохо структурированный API в дальнейшем может доставить вам много боли и неприятностей.
В первую очередь — версионность. Я показал, что моя версия API явно указана.
Я избегаю точечных нотаций и группирую запросы таким образом. Конечно, вы можете создавать разные запросы для разных версий, но это в конечном итоге запутает вас как бэкенд-разработчиков.
Выкидывайте ошибки. У меня есть плохой опыт работы с API, который выкидывает всегда 200-й код, но в теле запроса непонятное сообщение: error E, error C, error хз. О том, что это такое, знал единственный разработчик, который все это придумал.
Ладно, если есть какая-то документация, но там и ее не было. Хорошим тоном является явное указание статуса ответа и унифицированное тело, которое может парситься одинаково для всех запросов.
Зависимость — боль. Помните об этом. Ваш бэкенд и ваш клиент должны быть независимы друг от друга. Изменение бизнес-логики на одном компоненте не должно влечь за собой изменения на другом. Это хороший путь к диверсифицированному развитию проектов.
Что я думаю о перспективах Server Side Swift? Мне кажется, что Swift в указанном направлении ждет большое будущее. Во-первых, инвестирует Apple в это огромные деньги. Создав группу Swift API, Apple показал свою заинтересованность в этом. Плюс в этой группе участвуют не только сторонние разработчики указанных фреймворков, но и сотрудники Apple. В это инвестируют и другие компании. IBM разработала Kitura, тоже инвестирует огромные деньги и обещает перенести все свои сервера на Swift. Конечно, мы не знаем, когда это произойдет. Но будем надеяться на лучшее. Огромное сообщество, которое сформировалось за год-полтора, активно развивается. Люди активно взаимодействуют друг с другом, при этом являясь конкурентами.
Самое важное: Swift Server Side — не компромисс. Я к тому, что речь идет не о каком-то хипстерском решении. Swift не уступает по скорости ведущим компилируемым языкам. Это отдельная тема доклада, но можно найти бенчмарки, где скорость работы Swift примерно сопоставима. На указанных бенчмарках Swift обгоняет Node.JS.
На этом всё. Используйте Swift Server Side для домашних проектов и будьте счастливы. Спасибо.
— Меня зовут Самвел, я iOS-разработчик в «Рамблере». До прихода в мобильную разработку я долгое время занимался серверными продуктами, различными интеграционными системами, таргетинговыми системами, предоставляющими API для сторонних ресурсов, сайтов наших веб-мастеров и партнеров. На данный момент я занимаюсь проектом «Афиша Рестораны».
Под конец небольшой бонус, как организовать хороший API, парочка лучших практик и мое мнение относительно перспектив S3.
Надеюсь, многие из здесь присутствующих разделяют мою симпатию к Swift. Это потрясающий инструмент, который предоставляет нам огромные возможности, а сейчас еще и возможность реализовывать серверную часть. И мы можем реализовывать end to end на Swift, это потрясающе.
Вернемся на пару лет назад. 2 июня 2014 года я сидел в комнате общаги Саратовского меда. Это не столь важно для здесь присутствующих, если не учитывать того, что в этот день я, как и многие из вас, ждал важного события. Речь о WWDC, на которой Apple представила Swift. И уже через год с небольшим, 3 декабря 2015 года, Apple заопенсорсила Swift, выпустив его под лицензией Apache для Linux и OS X. Это было большое событие, это запустило огромную волну различных проектов и дополнительно смотивировало тех разработчиков, которые еще с первой беты хотели активно распространять Swift за пределами разработки для Apple-девайсов. Потрясающее время.
Давайте копнем первопричину. Это апрельская статистика доли интернет-трафика. Огромное число, которое предполагает, что большинство приложений, которые мы используем и, тем более, которые, я хочу верить, разрабатываем, имеют подключение к сети и различным сервисам.
Таким образом, бизнес-логика наших приложений так или иначе разделена на части. Это вызывает определенные зависимости. Часть логики, будь то авторизация приложений или бронирование столика, у нас находится на бэке. Это создает проблемы, зависимости. Мы все не любим зависимости. В конечном итоге это ограничивает нас.
Это если не учитывать того факта, что большинство бэкендщиков достаточно ревностно относятся к нашим пожеланиям, замечаниям, просьбам что-то изменить в API, добавить, поправить. Можно изучить самостоятельный инструмент, стать бэкендщиком самому, но это решает задачу только для нас. Что насчет команды? Предположим, что у нас iOS-команда и надо реализовать серверную утилиту для своих нужд. Например, в «Рамблере» есть дашрамба, написанная на Ruby, и поддержка сейчас достаточно проблематична.
Реализация end to end на Swift решает эту и ряд других проблем.
Понятие фреймворка на бэке отчасти отличается от привычного нам. По определению из вики, фреймворк — программная система, каркас, который позволяет организовать нашу систему. Это некая платформа. Это не библиотека, это не дополнительный язык, не новый для нас язык. В использовании фреймворка для любого нормального разработчика нет ничего сверхъестественного.
На данный момент есть четыре активно развивающихся инструмента. Общее количество звезд репозиториев этих инструментов достигает 31 тыс. Причем самый старый инструмент — Perfect, ему чуть больше полутора лет.
Для сравнения, у «рельсов» за семь лет всего 35 тыс. Развитие сообщества идет колоссальными шагами.
Предлагаю сравнение компонентов и перейдем к демо.
Комьюнити. При запуске проекта это очень важно. Здесь выделяется Perfect и Vapor, у них огромное сообщество, огромное количество контрибьютеров, подписчиков в Твиттере, активнейшие каналы в Slack, где вы можете оперативно получить ответ на любой ваш вопрос.
Что касается Kitura и Zewo — готовьтесь копать много кода, вы не получите быстрых ответов, но у них есть другие фишки. Впрочеам, у Zewo последний коммит был сделан 13 января 2017 года, хотя фреймворк, кажется, развивается.
Языки. За исключением Vapor у всех инструментов есть одна, две или более зависимостей на С. У Perfect это HTTP-сервер, у Kitura шаблонизаторы реализованы на С. Различные криптографические библиотеки. Отчасти это оправдывает себя в скорости.
Если посмотреть доступные онлайн-бенчмарки, то Vapor проигрывает всем фреймворкам и Node.JS. Это бенчмарк по использованию памяти и бенчмарк по обработке и выдаче JSON.
Ссылка на Medium
У меня есть информация, что в новой версии, которая на стадии беты, эта проблема решена и там все оптимизировано, поэтому ждем стабильной версии.
Что касается работы с БД, то она одинаково хорошо реализована практически во всех инструментах за исключением Zewo, там немного проблематично. Perfect и Vapor предоставляют огромное количество провайдеров для организации доступа к разным реляционным базам данных.
Какой у меня выбор? Несмотря на то, что Vapor уступает всем инструментам в скорости, я выбираю этот фреймворк. Он лаконичен, его синтаксис не может не нравиться Swift-разработчику, плюс подкупает идеологическая приверженность исключительно Swift style, плюс Vapor имеет огромное сообщество, достаточно активное, они фичерят, постоянно вносят новые изменения. Так что это мой выбор.
Что вам нужно сделать, чтобы установить и развернуть систему? Первое — поставить тулбокс. Тулбокс Vapor — всего лишь обертка для терминала, которая позволяет в удобной форме вызывать те или иные команды. Просто попросите brew, он все сделает за вас.
Создайте новый проект. Вы можете указать в качестве параметра template любой шаблон, который найдете на GitHub.
Третьим шагом перейдите в папку проекта и сбилдите его. Первый билд вызывает закачку зависимости сети. Чтобы избежать факапов с сетью, я сделал преинкрементальную сборку заранее.
Запустите ваш сервер, и все готово.
Помимо этого рекомендую вызвать команду xcode, которая создаст вам таргет, это привычная для вас среда разработки, ничего сверхъестественного.
Из каких частей состоит скомпилированный проект сервера?
Прежде всего это Package.swift. Ничего сверхъественного в этом файле нет, многие с ним знакомы, это пакет зависимостей, который подтягивает необходимые нам либы с сервера. И MySQL-провайдер.
Я бы хотел отдельно отметить файл main.swift, который инициализирует дроплет-объект. Это core layer, предоставляющий нам доступ ко всем остальным фишкам Vapor.
Здесь также закидывается роутинг для индекс-запроса, который показывает нам view welcome и запускается. Предлагаю запустить сервер и посмотреть, как все это прекрасно.
Сервер запущен, он находится по адресу localhost на порте 8080.
Кто хочет воочию посмотреть процесс установки Vapor, компиляции, подтягивания зависимостей — я в перерыве покажу, как вызвать команды в терминале и наслаждаться этим процессом.
Конфиги сервера находятся в папке configs. Вы можете настраивать необходимые параметры и изменять порт вашей системы. Порт по дефолту — 8080.
Вернемся в наш проект. Такой сервер бесполезен, если только вы не хотите делать какой-то сайт-визитку, чтобы показать своим друзьям. И само собой, если вы хотите сделать что-то большее, надо подключить БД.
Как работает Vapor с разными реляционными БД? У нас имеется драйвер, который обеспечивает взаимодействие с базой. К нему подключается провайдер. Под капотом драйвер взаимодействует с движком Fluent, разработанным ребятами из Vapor. Мы работаем непосредственно с MySQL-провайдером. Воспринимайте этот провайдер как persistent store в core data, тогда все станет понятно.
В качестве базы я выбрал MySQL. Для его установки надо вызвать две команды — brew install mysql и запускаем MySQL-сервер.
Давайте создадим БД. У меня есть заготовка, дамп базы находится в проекте, который будет доступен после презентации. Это единственная таблица, которая содержит четыре поля с событиями о мероприятиях CocoaHeads, которые мы хотим выдавать нашим API.
Для создания и управления БД после установки MySQL вы можете использовать различные утилиты, необязательно вызывать эти команды из терминала. Один из таких инструментов — Sequel Pro. Это утилита, интерфейс которой ничуть не отличается от интерфейса управления объектами core data в Xcode. Та же структура: создаете объекты, создаете к ним поля, указываете контент, данные.
Предлагаю показать, как подключить провайдер. Необходимо импортировать VaporMySQL и добавить провайдер в drop-объект. Выполняется это одной командой — addProvider(VaporMySQL.Provider.self). В принципе, уже все готово для работы с БД, этого достаточно.
После запуска проекта вы увидите, что сервер запущен. Нет подготовленных объектов.
При запуске и установке нового объекта у вас из коробки идут модельки. Они должны сопоставляться с таблицами, которые вы создаете в своих базах. В данном случае у меня моделька event, которая полностью соответствует таблице в базе MySQL. Чтобы ее подключить к своему провайдеру, я вызываю команду preparation module, моделька добавляется в мой провайдер.
В принципе, всё. Я могу отправлять этот объект по разному роутингу и получить их на сервере.
Добавляем группу запросов для пути версии API 1. Событие events будет обрабатывать event controller. Запускаем проект, видим, что DPS prepared, БД полностью подключена.
Давайте проверим запрос, который находится по адресу events. Группа запросов и сама сущность. Мы получаем наше событие, и API работает буквально в три строчки, не считая подключения базы.
Предлагаю показывать все объекты, не только те, на которых регистрация открыта. Сам процесс работы с какими-то компонентами Vapor ничуть не отличается от работы с Realm, core data, и вам достаточно 20-30 минут на изучение каких-то компонентов, чтобы запустить это. И из коробки у вас все будет готово. Проверим запрос. Получаем все события, которые имеются в БД.
Вернемся к докладу. Накину пару принципов про организацию хорошего API. Плохо структурированный API в дальнейшем может доставить вам много боли и неприятностей.
В первую очередь — версионность. Я показал, что моя версия API явно указана.
Я избегаю точечных нотаций и группирую запросы таким образом. Конечно, вы можете создавать разные запросы для разных версий, но это в конечном итоге запутает вас как бэкенд-разработчиков.
Выкидывайте ошибки. У меня есть плохой опыт работы с API, который выкидывает всегда 200-й код, но в теле запроса непонятное сообщение: error E, error C, error хз. О том, что это такое, знал единственный разработчик, который все это придумал.
Ладно, если есть какая-то документация, но там и ее не было. Хорошим тоном является явное указание статуса ответа и унифицированное тело, которое может парситься одинаково для всех запросов.
Зависимость — боль. Помните об этом. Ваш бэкенд и ваш клиент должны быть независимы друг от друга. Изменение бизнес-логики на одном компоненте не должно влечь за собой изменения на другом. Это хороший путь к диверсифицированному развитию проектов.
Что я думаю о перспективах Server Side Swift? Мне кажется, что Swift в указанном направлении ждет большое будущее. Во-первых, инвестирует Apple в это огромные деньги. Создав группу Swift API, Apple показал свою заинтересованность в этом. Плюс в этой группе участвуют не только сторонние разработчики указанных фреймворков, но и сотрудники Apple. В это инвестируют и другие компании. IBM разработала Kitura, тоже инвестирует огромные деньги и обещает перенести все свои сервера на Swift. Конечно, мы не знаем, когда это произойдет. Но будем надеяться на лучшее. Огромное сообщество, которое сформировалось за год-полтора, активно развивается. Люди активно взаимодействуют друг с другом, при этом являясь конкурентами.
Самое важное: Swift Server Side — не компромисс. Я к тому, что речь идет не о каком-то хипстерском решении. Swift не уступает по скорости ведущим компилируемым языкам. Это отдельная тема доклада, но можно найти бенчмарки, где скорость работы Swift примерно сопоставима. На указанных бенчмарках Swift обгоняет Node.JS.
На этом всё. Используйте Swift Server Side для домашних проектов и будьте счастливы. Спасибо.
Комментарии (4)
smanioso
09.10.2017 11:25Возможно стоило использовать более свежие данные от того же автора. В новых версиях Vapor, судя по тестам, выглядит гораздо лучше.
Cttr
09.10.2017 13:36Swift очень перспективный, активно разрабатываемый (гляньте гитхаб github.com/apple/swift/releases), ЯП. Но главная проблема для меня — это отсутствие/плохая поддержка драйверов к различным продуктам. Если свернуть со стандартного набора (PostgreSQL, MySQL, MongoDB, etc.) и есть потребность использовать например Cassandra (ScyllaDB) или ту же очередь NSQ, то обнаруживается, что клиентов или нет или они без активного развития.
arturgspb
Далее лично мое мнение про мировое мироустройство. Вы никогда не задумывались — почему у Гугла все хорошо, а Яндекс Тихо тихо теряет свои позиции? Про Рамблер вообще история отдельная — кажется уже умер, ну для меня точно, во всяком случае. Так вот, как вы думаете почему так происходит? Мое мнение — если заниматься всякой фигнёй типа этой, а не использовать и развивать нормальные технологии, где нормально можно найти программистов и библиотеки, то так все и будет продолжаться. Гугл двигает множество стандартов и в целом делает мир лучше. Яндекс, как правило, делает запилы под себя. Исключение комиссия по стандартизации С и конечно божественный кликхаус! В общем пока в велобаджо моют посуду...
arturgspb
Чего минусуем, стыдно стало? ;)