[JavaScript, Node.JS] Fastify.js — не только самый быстрый веб-фреймворк для node.js
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Последние 10 лет среди веб-фреймворков для node.js самой большой популярностью пользуется Express.js. Всем, кто с ним работал, известно, что сложные приложения на Express.js бывает сложно структурировать. Но, как говорится, привычка — вторая натура. От Express.js бывает сложно отказаться. Как, например, сложно бросить курить. Кажется, что нам непременно нужна эта бесконечная цепь middleware, и если у нас забрать возможность создавать их по любому поводу и без повода — проект остановится.
Отрадно, что сейчас, наконец, появился достойный претендент на место главного веб-фреймворка всех и вся — я имею в виду не Fastify.js, а, конечно же, Nest.js. Хотя по количественным показателям популярности, до Express.js ему очень и очень далеко.
Таблица. Показатели популярности пакетов по данным npmjs.org, github.com
№
Пакет
Количество загрузок
Количество «звезд»
1
connect
4 373 963
9 100
2
express
16 492 569
52 900
3
koa
844 877
31 100
4
nestjs
624 603
36 700
5
hapi
389 530
13 200
6
fastify
216 240
18 600
7
restify
93 665
10 100
8
polka
71 394
4 700
Express.js по-прежнему работает в более чем в 2/3 веб-приложений для node.js. Более того, 2/3 наиболее популярных веб-фреймворков для node.js используют подходы Express.js. (Точнее было бы сказать, подходы библиотеки Connect.js, на которой до версии 4 базировался Express.js).
В предлагаемом сообщении обсуждаются особенности основных веб-фреймворков для node.js, и что делает Fastify.js фреймворком другого уровня, что позволяет выбрать его как фреймворк для разработки Вашего следующего проекта.
Критика фреймворков, основаных на синхронных middleware
Что же плохого может быть в таком коде?
app.get('/', (req, res) => {
res.send('Hello World!')
})
1. Функция, которая обрабатывает роут, не возвращает значение. Вместо этого необходимо вызвать один из методов объекта response (res). Если это метод не будет вызван явно, даже после возврата из функции клиент и сервер останутся в состоянии ожидания ответа сервера пока для каждого из них не истечет таймаут. Это только «прямые убытки», но есть еще и «упущенная выгода». То что эта функция не возвращает значения, делает невозможным просто реализовать востребованную функциональность, например валидацию или логирование возвращаемых клиенту ответов.
2. Обработка ошибок всегда синхронная. Редкий роут обходится без вызовов асинхронных операций. Так как Express.js создавался в допромисовую эру, стандартный обработчик ошибок не сработает и нужно ошибки обрабатывать так:
app.get('/', async (req, res, next) => {
try {
...
} catch (ex) {
next(ex);
}
})
или так:
app.get('/', (req, res, next) => {
doAcync().catch(next)
})
3. Сложность асинхронной инициализации сервисов. Например, приложение работает с базой данных и обращается к базе данных как к сервису, сохранив ссылку в переменной. Инициализация роутов в Express.js всегда синхронная. Это означает, что когда на роуты начнут приходить первые запросы клиентов, асинхронная инициализация сервиса, вероятно еще не успеет отработать, так что придется «тащить» в роуты асинхронный код с получением ссылки на этот сервис. Все это, конечно, реализуемо. Но слишком далеко уходит от наивной простоты изначального кода:
app.get('/', (req, res) => {
res.send('Hello World!')
})
4. Ну и наконец, последнее но немаловажное. В большинстве Express.js приложений работет примерно такой код:
app.use(someFuction);
app.use(anotherFunction());
app.use((req, res, nexn) => ..., next());
app.get('/', (req, res) => {
res.send('Hello World!')
})
Когда Вы разрабатываете свою часть приложения, то можете быть уверенным что до вашего кода уже успели отработать 10-20 middleware, которые вешают на объект req всевозможные свойства, и, даже, могут модифицировать исходный запрос, ровно как и в том что столько же если не больше middleware может бтоь добавлено после того, как вы разработаете свою часть приложения. Хотя, к слову сказать, в документации Express.js для навешивания дополнительных свойств неоднозначно рекомендуется объект res.locals:
// из документации Express.js
app.use(function (req, res, next) {
res.locals.user = req.user
res.locals.authenticated = !req.user.anonymous
next()
})
Исторические попытки преодоления недостатков Express.js
Не удивительно, что основной автор Express.js и Connect.js — TJ Holowaychuk — оставил проект, чтобы начать разработку нового фреймворка Koa.js. Koa.js добавляет асинхронность в Express.js. Например, такой код избавляет от необходимости перехватывать асинхронные ошибки в коде каждого роута и выносит обработчик в один middleware:
app.use(async (ctx, next) => {
try {
await next();
} catch (err) {
// will only respond with JSON
ctx.status = err.statusCode || err.status || 500;
ctx.body = {
message: err.message
};
}
})
Первые версии Koa.js имели замысел внедрить генераторы для обработки асинхронных вызовов:
// from http://blog.stevensanderson.com/2013/12/21/experiments-with-koa-and-javascript-generators/
var request = Q.denodeify(require('request'));
// Example of calling library code that returns a promise
function doHttpRequest(url) {
return request(url).then(function(resultParams) {
// Extract just the response object
return resultParams[];
});
}
app.use(function *() {
// Example with a return value
var response = yield doHttpRequest('http://example.com/');
this.body = "Response length is " + response.body.length;
});
Внедрение async/await свело на нет полезность этой части Koa.js, и сейчас подобных примеров нет даже в документации фреймворка.
Почти ровесник Express.js — фреймворк Hapi.js. Контроллеры в Hapi.js уже возвращают значение, что является шагом вперед, по сравнению с Express.js. Не получив популярность сравнимую с Express.js, мега-успешной стала составная часть проекта Hapi.js — библиотека Joi, которая имеет количество загрузок с npmjs.org 3 388 762, и сейчас используется как на бэкенде, так и на фронтенде. Поняв, что валидация входящих объектов — это не какой-то особый случай, а необходимый атрибут каждого приложения — валидация в Hapi.js была включена как составляющая часть фреймворка, и как параметр в определении роута:
server.route({
method: 'GET',
path: '/hello/{name}',
handler: function (request, h) {
return `Hello ${request.params.name}!`;
},
options: {
validate: {
params: Joi.object({
name: Joi.string().min(3).max(10)
})
}
}
});
В настоящее время, библиотека Joi выделена в самостоятельный проект.
Если мы определели схему валидации объекта, тем самымы мы определили и сам объект. Остается совсем немного, чтобы создать самодокументируемый роут, в котором изменение в схеме валидации данных приводит к изменению документации, и, таким образом, документация всегда соответствует программному коду.
На сегодняшний день, одно из лучших решений в документации API — swagger/openAPI. Было бы очень удачно, если бы схема, описания с учетом требований swagger/openAPI, могла быть использована и для валидации и для формирования документации.
Fastify.js
Подитожу те требования, который мне кажутся существенными при выборе веб-фреймворка:
1. Наличие полноценных контроллеров (возвращаемое значение функции возвращется клиенту в теле ответа).
2. Удобная обработка синхронных и асинхронных ошибок.
3. Валидация входных параметров.
4. Самодокуметирование на основании определений роутов и схем валидации входных/выходных параметров.
5. Инстанциирование асинхронных сервисов.
6. Расширяемость.
Всем этим пунктам соответствует Nest.js, с которым я сейчас работаю на нескольких проектах. Особенностью Next.js является широкое применение декораторов, что может быть в ряде случаев ограничением, если в технических требованиях указано использовать стандартный JavaScript (а как известно со стандартизацией декораторов в JavaScript сиутация застопорилась несколько лет назад, и, похоже, не скоро найдет свое разрешение).
Поэтому альтернативой может стать фреймворк Fastify.js, особенности применения которого я сейчас разберу.
Fastify.js поддерживает и привычный для разработчиков на Express.js стиль формирования ответа сервера, и более перспективный в форме возвращаемого значения функции, при этом оставляя возможность гибко манипулировать другими параметрами ответа (статусом, заголовками):
// Require the framework and instantiate it
const fastify = require('fastify')({
logger: true
})
// Declare a route
fastify.get('/', (request, reply) => {
reply.send({ hello: 'world' })
})
// Run the server!
fastify.listen(3000, (err, address) => {
if (err) throw err
// Server is now listening on ${address}
})
const fastify = require('fastify')({
logger: true
})
fastify.get('/', (request, reply) => {
reply.type('application/json').code(200)
return { hello: 'world' }
})
fastify.listen(3000, (err, address) => {
if (err) throw err
// Server is now listening on ${address}
})
Обработка ошибок может быть встроенной («из коробки») и кастомной.
const createError = require('fastify-error');
const CustomError = createError('403_ERROR', 'Message: ', 403);
function raiseAsyncError() {
return new Promise((resolve, reject) => {
setTimeout(() => reject(new CustomError('Async Error')), 5000);
});
}
async function routes(fastify) {
fastify.get('/sync-error', async () => {
if (true) {
throw new CustomError('Sync Error');
}
return { hello: 'world' };
});
fastify.get('/async-error', async () => {
await raiseAsyncError();
return { hello: 'world' };
});
}
Оба варианта — и синхронный и асинхронный — отрабатывают одинаково встроенным обработчиком ошибок. Конечно, встроенных возможностей всегда мало. Кастомизируем обработчик ошибок:
fastify.setErrorHandler((error, request, reply) => {
console.log(error);
reply.status(error.status || 500).send(error);
});
fastify.get('/custom-error', () => {
if (true) {
throw { status: 419, data: { a: 1, b: 2} };
}
return { hello: 'world' };
});
Эта часть кода упрощена (ошибка выбрасывает литерал). Аналогично можно выбрасывать и кастомную ошибку. (Определение кастомных сериализуемых ошибок — это отдельная тема, поэтому пример не приводится).
Для валидации Fastify.js использует библиотеку Ajv.js, которая реализует интерфенйс swagger/openAPI. Этот факт делает возможным интеграцию Fastify.js со swagger/openAPI и самодокументирвоание API.
По умолчанию валидация не самая строгая (поля опциональоные и допускаются отсутствующие в схеме поля). Для того чтобы сделать валдиацию строгой необходимо определить параметры в конфигурации Ajv, и в схеме валидации:
const fastify = require('fastify')({
logger: true,
ajv: {
customOptions: {
removeAdditional: false,
useDefaults: true,
coerceTypes: true,
allErrors: true,
strictTypes: true,
nullable: true,
strictRequired: true,
},
plugins: [],
},
});
const opts = {
httpStatus: 201,
schema: {
description: 'post some data',
tags: ['test'],
summary: 'qwerty',
additionalProperties: false,
body: {
additionalProperties: false,
type: 'object',
required: ['someKey'],
properties: {
someKey: { type: 'string' },
someOtherKey: { type: 'number', minimum: 10 },
},
},
response: {
200: {
type: 'object',
additionalProperties: false,
required: ['hello'],
properties: {
value: { type: 'string' },
otherValue: { type: 'boolean' },
hello: { type: 'string' },
},
},
201: {
type: 'object',
additionalProperties: false,
required: ['hello-test'],
properties: {
value: { type: 'string' },
otherValue: { type: 'boolean' },
'hello-test': { type: 'string' },
},
},
},
},
};
fastify.post('/test', opts, async (req, res) => {
res.status(201);
return { hello: 'world' };
});
}
Поскольку схема входящих объектов уже определена, генерация документации swagger/openAPI сводится к инсталляции плагина:
fastify.register(require('fastify-swagger'), {
routePrefix: '/api-doc',
swagger: {
info: {
title: 'Test swagger',
description: 'testing the fastify swagger api',
version: '0.1.0',
},
securityDefinitions: {
apiKey: {
type: 'apiKey',
name: 'apiKey',
in: 'header',
},
},
host: 'localhost:3000',
schemes: ['http'],
consumes: ['application/json'],
produces: ['application/json'],
},
hideUntagged: true,
exposeRoute: true,
});
Валидация ответа также возможна. Для этого необходимо инсталлировать плагин:
fastify.register(require('fastify-response-validation'));
Валидация достаточно гибкая. Например ответ каждого статуса будет проверяться по своей схеме валидации.
Код связанный с написание статьи можно найти здесь.
Дополнительные источники информации
1. blog.stevensanderson.com/2013/12/21/experiments-with-koa-and-javascript-generators
2. habr.com/ru/company/dataart/blog/312638
apapacy@gmail.com
4 мая 2021 года
===========
Источник:
habr.com
===========
Похожие новости:
- [JavaScript, Canvas, ReactJS] Варианты создания интерактивной экскурсии для пользователей
- [JavaScript, Промышленное программирование, TypeScript] Продвинутые дженерики в TypeScript. Доклад Яндекса
- [Разработка игр, Node.JS, Unity, Игры и игровые приставки] Спасибо хабравчанам за участие в Онлайнстрации
- [Мессенджеры, Платежные системы, JavaScript, Node.JS] Оплата в телеграм боте — Платежи 2.0 — Сбербанк + Telegraf + Node.js
- [JavaScript, Google Chrome, WebAssembly] Что вошло в релиз движка V8 версии 9.0 (перевод)
- [Разработка игр, Node.JS, Unity, Игры и игровые приставки] Монстрация-онлайнстрация
- [JavaScript, Программирование] Человеко-читаемый JavaScript: история о двух экспертах (перевод)
- [Node.JS, Serverless] Запускаем приложение на Express.js в Yandex Cloud Functions
- [JavaScript, Angular, ReactJS] Only 39% of the functions in node_modules are unique in the default Angular project (перевод)
- [JavaScript, Angular, ReactJS] Только 39% функций в node_modules уникальны в дефолтном Angular проекте
Теги для поиска: #_javascript, #_node.js, #_fastify, #_nodejs, #_webprogrammirovanie (web-программирование), #_restful_api, #_javascript, #_node.js
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 08:20
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Последние 10 лет среди веб-фреймворков для node.js самой большой популярностью пользуется Express.js. Всем, кто с ним работал, известно, что сложные приложения на Express.js бывает сложно структурировать. Но, как говорится, привычка — вторая натура. От Express.js бывает сложно отказаться. Как, например, сложно бросить курить. Кажется, что нам непременно нужна эта бесконечная цепь middleware, и если у нас забрать возможность создавать их по любому поводу и без повода — проект остановится. Отрадно, что сейчас, наконец, появился достойный претендент на место главного веб-фреймворка всех и вся — я имею в виду не Fastify.js, а, конечно же, Nest.js. Хотя по количественным показателям популярности, до Express.js ему очень и очень далеко. Таблица. Показатели популярности пакетов по данным npmjs.org, github.com № Пакет Количество загрузок Количество «звезд» 1 connect 4 373 963 9 100 2 express 16 492 569 52 900 3 koa 844 877 31 100 4 nestjs 624 603 36 700 5 hapi 389 530 13 200 6 fastify 216 240 18 600 7 restify 93 665 10 100 8 polka 71 394 4 700 Express.js по-прежнему работает в более чем в 2/3 веб-приложений для node.js. Более того, 2/3 наиболее популярных веб-фреймворков для node.js используют подходы Express.js. (Точнее было бы сказать, подходы библиотеки Connect.js, на которой до версии 4 базировался Express.js). В предлагаемом сообщении обсуждаются особенности основных веб-фреймворков для node.js, и что делает Fastify.js фреймворком другого уровня, что позволяет выбрать его как фреймворк для разработки Вашего следующего проекта. Критика фреймворков, основаных на синхронных middleware Что же плохого может быть в таком коде? app.get('/', (req, res) => {
res.send('Hello World!') }) 1. Функция, которая обрабатывает роут, не возвращает значение. Вместо этого необходимо вызвать один из методов объекта response (res). Если это метод не будет вызван явно, даже после возврата из функции клиент и сервер останутся в состоянии ожидания ответа сервера пока для каждого из них не истечет таймаут. Это только «прямые убытки», но есть еще и «упущенная выгода». То что эта функция не возвращает значения, делает невозможным просто реализовать востребованную функциональность, например валидацию или логирование возвращаемых клиенту ответов. 2. Обработка ошибок всегда синхронная. Редкий роут обходится без вызовов асинхронных операций. Так как Express.js создавался в допромисовую эру, стандартный обработчик ошибок не сработает и нужно ошибки обрабатывать так: app.get('/', async (req, res, next) => {
try { ... } catch (ex) { next(ex); } }) или так: app.get('/', (req, res, next) => {
doAcync().catch(next) }) 3. Сложность асинхронной инициализации сервисов. Например, приложение работает с базой данных и обращается к базе данных как к сервису, сохранив ссылку в переменной. Инициализация роутов в Express.js всегда синхронная. Это означает, что когда на роуты начнут приходить первые запросы клиентов, асинхронная инициализация сервиса, вероятно еще не успеет отработать, так что придется «тащить» в роуты асинхронный код с получением ссылки на этот сервис. Все это, конечно, реализуемо. Но слишком далеко уходит от наивной простоты изначального кода: app.get('/', (req, res) => {
res.send('Hello World!') }) 4. Ну и наконец, последнее но немаловажное. В большинстве Express.js приложений работет примерно такой код: app.use(someFuction);
app.use(anotherFunction()); app.use((req, res, nexn) => ..., next()); app.get('/', (req, res) => { res.send('Hello World!') }) Когда Вы разрабатываете свою часть приложения, то можете быть уверенным что до вашего кода уже успели отработать 10-20 middleware, которые вешают на объект req всевозможные свойства, и, даже, могут модифицировать исходный запрос, ровно как и в том что столько же если не больше middleware может бтоь добавлено после того, как вы разработаете свою часть приложения. Хотя, к слову сказать, в документации Express.js для навешивания дополнительных свойств неоднозначно рекомендуется объект res.locals: // из документации Express.js
app.use(function (req, res, next) { res.locals.user = req.user res.locals.authenticated = !req.user.anonymous next() }) Исторические попытки преодоления недостатков Express.js Не удивительно, что основной автор Express.js и Connect.js — TJ Holowaychuk — оставил проект, чтобы начать разработку нового фреймворка Koa.js. Koa.js добавляет асинхронность в Express.js. Например, такой код избавляет от необходимости перехватывать асинхронные ошибки в коде каждого роута и выносит обработчик в один middleware: app.use(async (ctx, next) => {
try { await next(); } catch (err) { // will only respond with JSON ctx.status = err.statusCode || err.status || 500; ctx.body = { message: err.message }; } }) Первые версии Koa.js имели замысел внедрить генераторы для обработки асинхронных вызовов: // from http://blog.stevensanderson.com/2013/12/21/experiments-with-koa-and-javascript-generators/
var request = Q.denodeify(require('request')); // Example of calling library code that returns a promise function doHttpRequest(url) { return request(url).then(function(resultParams) { // Extract just the response object return resultParams[]; }); } app.use(function *() { // Example with a return value var response = yield doHttpRequest('http://example.com/'); this.body = "Response length is " + response.body.length; }); Внедрение async/await свело на нет полезность этой части Koa.js, и сейчас подобных примеров нет даже в документации фреймворка. Почти ровесник Express.js — фреймворк Hapi.js. Контроллеры в Hapi.js уже возвращают значение, что является шагом вперед, по сравнению с Express.js. Не получив популярность сравнимую с Express.js, мега-успешной стала составная часть проекта Hapi.js — библиотека Joi, которая имеет количество загрузок с npmjs.org 3 388 762, и сейчас используется как на бэкенде, так и на фронтенде. Поняв, что валидация входящих объектов — это не какой-то особый случай, а необходимый атрибут каждого приложения — валидация в Hapi.js была включена как составляющая часть фреймворка, и как параметр в определении роута: server.route({
method: 'GET', path: '/hello/{name}', handler: function (request, h) { return `Hello ${request.params.name}!`; }, options: { validate: { params: Joi.object({ name: Joi.string().min(3).max(10) }) } } }); В настоящее время, библиотека Joi выделена в самостоятельный проект. Если мы определели схему валидации объекта, тем самымы мы определили и сам объект. Остается совсем немного, чтобы создать самодокументируемый роут, в котором изменение в схеме валидации данных приводит к изменению документации, и, таким образом, документация всегда соответствует программному коду. На сегодняшний день, одно из лучших решений в документации API — swagger/openAPI. Было бы очень удачно, если бы схема, описания с учетом требований swagger/openAPI, могла быть использована и для валидации и для формирования документации. Fastify.js Подитожу те требования, который мне кажутся существенными при выборе веб-фреймворка: 1. Наличие полноценных контроллеров (возвращаемое значение функции возвращется клиенту в теле ответа). 2. Удобная обработка синхронных и асинхронных ошибок. 3. Валидация входных параметров. 4. Самодокуметирование на основании определений роутов и схем валидации входных/выходных параметров. 5. Инстанциирование асинхронных сервисов. 6. Расширяемость. Всем этим пунктам соответствует Nest.js, с которым я сейчас работаю на нескольких проектах. Особенностью Next.js является широкое применение декораторов, что может быть в ряде случаев ограничением, если в технических требованиях указано использовать стандартный JavaScript (а как известно со стандартизацией декораторов в JavaScript сиутация застопорилась несколько лет назад, и, похоже, не скоро найдет свое разрешение). Поэтому альтернативой может стать фреймворк Fastify.js, особенности применения которого я сейчас разберу. Fastify.js поддерживает и привычный для разработчиков на Express.js стиль формирования ответа сервера, и более перспективный в форме возвращаемого значения функции, при этом оставляя возможность гибко манипулировать другими параметрами ответа (статусом, заголовками): // Require the framework and instantiate it
const fastify = require('fastify')({ logger: true }) // Declare a route fastify.get('/', (request, reply) => { reply.send({ hello: 'world' }) }) // Run the server! fastify.listen(3000, (err, address) => { if (err) throw err // Server is now listening on ${address} }) const fastify = require('fastify')({
logger: true }) fastify.get('/', (request, reply) => { reply.type('application/json').code(200) return { hello: 'world' } }) fastify.listen(3000, (err, address) => { if (err) throw err // Server is now listening on ${address} }) Обработка ошибок может быть встроенной («из коробки») и кастомной. const createError = require('fastify-error');
const CustomError = createError('403_ERROR', 'Message: ', 403); function raiseAsyncError() { return new Promise((resolve, reject) => { setTimeout(() => reject(new CustomError('Async Error')), 5000); }); } async function routes(fastify) { fastify.get('/sync-error', async () => { if (true) { throw new CustomError('Sync Error'); } return { hello: 'world' }; }); fastify.get('/async-error', async () => { await raiseAsyncError(); return { hello: 'world' }; }); } Оба варианта — и синхронный и асинхронный — отрабатывают одинаково встроенным обработчиком ошибок. Конечно, встроенных возможностей всегда мало. Кастомизируем обработчик ошибок: fastify.setErrorHandler((error, request, reply) => {
console.log(error); reply.status(error.status || 500).send(error); }); fastify.get('/custom-error', () => { if (true) { throw { status: 419, data: { a: 1, b: 2} }; } return { hello: 'world' }; }); Эта часть кода упрощена (ошибка выбрасывает литерал). Аналогично можно выбрасывать и кастомную ошибку. (Определение кастомных сериализуемых ошибок — это отдельная тема, поэтому пример не приводится). Для валидации Fastify.js использует библиотеку Ajv.js, которая реализует интерфенйс swagger/openAPI. Этот факт делает возможным интеграцию Fastify.js со swagger/openAPI и самодокументирвоание API. По умолчанию валидация не самая строгая (поля опциональоные и допускаются отсутствующие в схеме поля). Для того чтобы сделать валдиацию строгой необходимо определить параметры в конфигурации Ajv, и в схеме валидации: const fastify = require('fastify')({
logger: true, ajv: { customOptions: { removeAdditional: false, useDefaults: true, coerceTypes: true, allErrors: true, strictTypes: true, nullable: true, strictRequired: true, }, plugins: [], }, }); const opts = { httpStatus: 201, schema: { description: 'post some data', tags: ['test'], summary: 'qwerty', additionalProperties: false, body: { additionalProperties: false, type: 'object', required: ['someKey'], properties: { someKey: { type: 'string' }, someOtherKey: { type: 'number', minimum: 10 }, }, }, response: { 200: { type: 'object', additionalProperties: false, required: ['hello'], properties: { value: { type: 'string' }, otherValue: { type: 'boolean' }, hello: { type: 'string' }, }, }, 201: { type: 'object', additionalProperties: false, required: ['hello-test'], properties: { value: { type: 'string' }, otherValue: { type: 'boolean' }, 'hello-test': { type: 'string' }, }, }, }, }, }; fastify.post('/test', opts, async (req, res) => { res.status(201); return { hello: 'world' }; }); } Поскольку схема входящих объектов уже определена, генерация документации swagger/openAPI сводится к инсталляции плагина: fastify.register(require('fastify-swagger'), {
routePrefix: '/api-doc', swagger: { info: { title: 'Test swagger', description: 'testing the fastify swagger api', version: '0.1.0', }, securityDefinitions: { apiKey: { type: 'apiKey', name: 'apiKey', in: 'header', }, }, host: 'localhost:3000', schemes: ['http'], consumes: ['application/json'], produces: ['application/json'], }, hideUntagged: true, exposeRoute: true, }); Валидация ответа также возможна. Для этого необходимо инсталлировать плагин: fastify.register(require('fastify-response-validation'));
Валидация достаточно гибкая. Например ответ каждого статуса будет проверяться по своей схеме валидации. Код связанный с написание статьи можно найти здесь. Дополнительные источники информации 1. blog.stevensanderson.com/2013/12/21/experiments-with-koa-and-javascript-generators 2. habr.com/ru/company/dataart/blog/312638 apapacy@gmail.com 4 мая 2021 года =========== Источник: habr.com =========== Похожие новости:
|
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 08:20
Часовой пояс: UTC + 5