Поддержание документации к микросервисам в актуальном состоянии по прежнему требует предельной дисциплины при разработке, ну и больших трудозарат. Очень разумный подход к созданию документации предлагает, например, GraphQL, где документация неразрывно связана с программным кодом и этим гарантируется 100% соответствие документации и документируемых сервисов. Однако, непривычность подхода GraphQL для разработчиков, привыкших к REST-API, все еще затрудняет продвижение этой технологии в практическую разработку приложений. Тут же можно вспомнить и SOAP, который уже давно решил проблему соответствия документации и сервисов, но из-за переусложненности не прижился в широких массах разработчиков.
Хотелось бы найти такой стек технологий для разработки микросервисов, который обеспечил такую же самодокументируемость программного кода при разработке «традиционных» REST-API микросервисов. И он, как оказалось, уже существует.
Определим действующих лиц и исполнителей, которые будут задействованы в нашем небольшом примере.
ArangoDB — гибридная, документо+граф-ориентированная база данных.
UPD. Более детальное знакомство с этой базой данных стало поводом для еще одного разочарования. Как оказалось, после превышения базой данных некоиторого лимита, который ограничен свободной оперативной памятью — база начинает не то что тормозить — она просто останавливается вместе с сервером. При этом высказываись робкие предположения о том что переход на новые движки хранения все будет работать лучше, которые пока не подтвердились.
UPD1. Хорошо иногда возвращаться и перепроверять обновленные версии продукта. Вскоре после написания этой статьи вышла версия 3.4, которая по заверению разработчиков пофиксила проблему с производительностью (фактически полную остановку) после превышения коллекцией размера оперативной памяти. Но я еще лично это не перепроверял. После соответствующих экспериментов сделаю очередной апдейт этой статьи. Рад, что arangodb возможно преодолела эту проблему и в этом случае она снова очень привлекательна для разработки приложений на ее основе.
Foxx — микросервисный фреймверк, встроенный в базу данных ArangoDB. Работает на движке JavaScript, который (в отличие от nodejs) может одновременно выполняться в неограниченном количестве параллельных потоков (не блокирующих друг друга), вследствие чего нет необходимости в конструкциях promise/than/canch и async/await. В отличие от mongodb, в которой не рекомендуется злоупотреблять серверными процедурами, и реляционных баз данных, в которых хранимые процедуры используются также осторожно и уж точно не взаимодействуют по REST-API с клиентами (браузерами, мобильными приложениями и т.п.) — микросервисный фреймверк Foxx был разработан как раз для разработки микросервисов которые напрямую общаются по http-протоколу с клиентами.
Swagger — это программная среда с открытым исходным кодом, поддерживаемая большой экосистемой инструментов, которая помогает разработчикам разрабатывать, создавать, документировать и потреблять веб-службы RESTful. Хотя большинство пользователей идентифицируют Swagger с Swagger UI, набор инструментов Swagger включает поддержку автоматической документации, генерации кода и генерации тестовых примеров.
То, что Swagger включает поддержку генерации кода это ситуация противоположная той, которую хотелось бы получить — когда код поддерживает генерацию документации. То что предлагает нам ArangoDB+Foxx как раз включает обратный вариант. Когда по коду микросервисов генерируется схема для Swagger-а. Впрочем, теперь в этом можно убедиться самостоятельно проделав минимум работы.
У Вас должна быть установлена ArangoDB, чтобы выполнить дальнейшие действия.
При инсталяции микросервиса, для каждой коллекции из поля «Document Collections» (см. п.2) будут созданы роуты, реализующие CRUD операции методами POST, GET, PUT и DELETE. Впрочем, это только заготовки методов, которые можно менять, удалять, добавлять новые. Мы выбрали одну коллекцию при содании микросервиса (cats), хотя могли этого и не деать, а все добавить потом вручную.
Тепрь у нашей коллекции cats есть роуты для CRUD операций, и мы можем начать вызывать эти роуты из админки базы данных выбрав вкладку API (Services->[Имя микросервиса]->API). В этом вкладке расположен привычный интерфейс Swagger-а. Также есть возможность опубликовать интерфейс Swagger-а на внешнем роуте доступном не только через админку, но как обычный URL.
Если попробовать добавить документ в коллекцию cats методом POST {«name»: «Tom»}, то получим статус с ошибкой. Т.к. поле name мы нигде еще не определили. Поэтому продолжим дальше работу с админкой ArangoDB.
4. Для более удобной разработки в ArangoDB предусмотрен режим Development, который включается на вкладке Settings (Services->[Имя микросервиса]->Settings-Set development)
Теперь можно менять код миросервиса и сразу наблюдать результат (без дополнительного деплоя). Каталог, в котором расположен программный код микросервиса можно узнать в админке на вкладке Info (Services->[Имя микросервиса]->Info).
Посмотрим как выглядит определение роута POST
Как валидация так и документирование, основаны на использовании схемы объекта. Внесем в нее небольшие изменения, добавив поле name:
Перейдя в закладку API, можно убедиться, что схема поменялась и теперь объект с полем name можно добавить в коллекцию cats.
apapacy@gmail.com
12 ноября 2018 года.
Хотелось бы найти такой стек технологий для разработки микросервисов, который обеспечил такую же самодокументируемость программного кода при разработке «традиционных» REST-API микросервисов. И он, как оказалось, уже существует.
Определим действующих лиц и исполнителей, которые будут задействованы в нашем небольшом примере.
ArangoDB — гибридная, документо+граф-ориентированная база данных.
UPD. Более детальное знакомство с этой базой данных стало поводом для еще одного разочарования. Как оказалось, после превышения базой данных некоиторого лимита, который ограничен свободной оперативной памятью — база начинает не то что тормозить — она просто останавливается вместе с сервером. При этом высказываись робкие предположения о том что переход на новые движки хранения все будет работать лучше, которые пока не подтвердились.
UPD1. Хорошо иногда возвращаться и перепроверять обновленные версии продукта. Вскоре после написания этой статьи вышла версия 3.4, которая по заверению разработчиков пофиксила проблему с производительностью (фактически полную остановку) после превышения коллекцией размера оперативной памяти. Но я еще лично это не перепроверял. После соответствующих экспериментов сделаю очередной апдейт этой статьи. Рад, что arangodb возможно преодолела эту проблему и в этом случае она снова очень привлекательна для разработки приложений на ее основе.
Foxx — микросервисный фреймверк, встроенный в базу данных ArangoDB. Работает на движке JavaScript, который (в отличие от nodejs) может одновременно выполняться в неограниченном количестве параллельных потоков (не блокирующих друг друга), вследствие чего нет необходимости в конструкциях promise/than/canch и async/await. В отличие от mongodb, в которой не рекомендуется злоупотреблять серверными процедурами, и реляционных баз данных, в которых хранимые процедуры используются также осторожно и уж точно не взаимодействуют по REST-API с клиентами (браузерами, мобильными приложениями и т.п.) — микросервисный фреймверк Foxx был разработан как раз для разработки микросервисов которые напрямую общаются по http-протоколу с клиентами.
Swagger — это программная среда с открытым исходным кодом, поддерживаемая большой экосистемой инструментов, которая помогает разработчикам разрабатывать, создавать, документировать и потреблять веб-службы RESTful. Хотя большинство пользователей идентифицируют Swagger с Swagger UI, набор инструментов Swagger включает поддержку автоматической документации, генерации кода и генерации тестовых примеров.
То, что Swagger включает поддержку генерации кода это ситуация противоположная той, которую хотелось бы получить — когда код поддерживает генерацию документации. То что предлагает нам ArangoDB+Foxx как раз включает обратный вариант. Когда по коду микросервисов генерируется схема для Swagger-а. Впрочем, теперь в этом можно убедиться самостоятельно проделав минимум работы.
У Вас должна быть установлена ArangoDB, чтобы выполнить дальнейшие действия.
- Входим в админку и выбираем пункт создания нового микросервиса Services->Add service->New.
- Заполняем в открывшейся форме обязательные реквизиты. В поле «Document Collections» добавляем имя коллекции документов которая будет создана при разворачивании микросервиса. Например, cats.
- Кликаем по кнопке install, заносим в поле url, к которому будет примонтирован микросервис.
При инсталяции микросервиса, для каждой коллекции из поля «Document Collections» (см. п.2) будут созданы роуты, реализующие CRUD операции методами POST, GET, PUT и DELETE. Впрочем, это только заготовки методов, которые можно менять, удалять, добавлять новые. Мы выбрали одну коллекцию при содании микросервиса (cats), хотя могли этого и не деать, а все добавить потом вручную.
Тепрь у нашей коллекции cats есть роуты для CRUD операций, и мы можем начать вызывать эти роуты из админки базы данных выбрав вкладку API (Services->[Имя микросервиса]->API). В этом вкладке расположен привычный интерфейс Swagger-а. Также есть возможность опубликовать интерфейс Swagger-а на внешнем роуте доступном не только через админку, но как обычный URL.
Если попробовать добавить документ в коллекцию cats методом POST {«name»: «Tom»}, то получим статус с ошибкой. Т.к. поле name мы нигде еще не определили. Поэтому продолжим дальше работу с админкой ArangoDB.
4. Для более удобной разработки в ArangoDB предусмотрен режим Development, который включается на вкладке Settings (Services->[Имя микросервиса]->Settings-Set development)
Теперь можно менять код миросервиса и сразу наблюдать результат (без дополнительного деплоя). Каталог, в котором расположен программный код микросервиса можно узнать в админке на вкладке Info (Services->[Имя микросервиса]->Info).
Посмотрим как выглядит определение роута POST
'use strict';
const dd = require('dedent');
const joi = require('joi');
const httpError = require('http-errors');
const status = require('statuses');
const errors = require('@arangodb').errors;
const createRouter = require('@arangodb/foxx/router');
const Cat = require('../models/cat');
const cats = module.context.collection('cats');
const keySchema = joi.string().required()
.description('The key of the cat');
const ARANGO_NOT_FOUND = errors.ERROR_ARANGO_DOCUMENT_NOT_FOUND.code;
const ARANGO_DUPLICATE = errors.ERROR_ARANGO_UNIQUE_CONSTRAINT_VIOLATED.code;
const ARANGO_CONFLICT = errors.ERROR_ARANGO_CONFLICT.code;
const HTTP_NOT_FOUND = status('not found');
const HTTP_CONFLICT = status('conflict');
const router = createRouter();
module.exports = router;
router.tag('cat');
router.post(function (req, res) {
const cat = req.body;
let meta;
try {
meta = cats.save(cat);
} catch (e) {
if (e.isArangoError && e.errorNum === ARANGO_DUPLICATE) {
throw httpError(HTTP_CONFLICT, e.message);
}
throw e;
}
Object.assign(cat, meta);
res.status(201);
res.set('location', req.makeAbsolute(
req.reverse('detail', {key: cat._key})
));
res.send(cat);
}, 'create')
.body(Cat, 'The cat to create.')
.response(201, Cat, 'The created cat.')
.error(HTTP_CONFLICT, 'The cat already exists.')
.summary('Create a new cat')
.description(dd`
Creates a new cat from the request body and
returns the saved document.
`);
Как валидация так и документирование, основаны на использовании схемы объекта. Внесем в нее небольшие изменения, добавив поле name:
'use strict';
const _ = require('lodash');
const joi = require('joi');
module.exports = {
schema: {
// Describe the attributes with joi here
_key: joi.string(),
name: joi.string().description('cat`s name'), // добавили новое поле
},
forClient(obj) {
// Implement outgoing transformations here
obj = _.omit(obj, ['_id', '_rev', '_oldRev']);
return obj;
},
fromClient(obj) {
// Implement incoming transformations here
return obj;
}
};
Перейдя в закладку API, можно убедиться, что схема поменялась и теперь объект с полем name можно добавить в коллекцию cats.
apapacy@gmail.com
12 ноября 2018 года.