@e22m4u/ts-rest-router v0.2.9
@e22m4u/ts-rest-router
REST маршрутизатор на основе контроллеров для TypeScript.
Основные возможности
- Декларативное определение маршрутов через декораторы.
- Типизированные параметры запросов (body, query, params).
- Поддержка middleware до и после обработки запроса.
- Валидация входящих данных.
- Поддержка всех HTTP методов (GET, POST, PUT, PATCH и DELETE).
Содержание
Установка
npm install @e22m4u/ts-rest-routerПоддержка декораторов
Для включения поддержки декораторов, добавьте указанные
ниже опции в файл tsconfig.json вашего проекта.
{
"emitDecoratorMetadata": true,
"experimentalDecorators": true
}Базовый пример
Создание контроллера и методов.
import {DataType} from '@e22m4u/ts-rest-router';
import {getAction} from '@e22m4u/ts-rest-router';
import {postAction} from '@e22m4u/ts-rest-router';
import {requestField} from '@e22m4u/ts-rest-router';
import {restController} from '@e22m4u/ts-rest-router';
// объявление контроллера
// и базового пути /users
@restController('users')
class UserController {
// объявление метода POST /users/login
// (использует базовый путь контроллера)
@postAction('login')
async login(
// инъекция значений указанных полей
// извлеизвлекаемых из тела запроса
@requestField('username') username?: string,
@requestField('password') password?: string,
) {
// так как метод возвращает объект,
// результат будет представлен как
// "Content-Type: application/json"
return {
id: 1,
firstName: 'John',
lastName: 'Doe',
};
}
}Регистрация контроллеров и запуск сервера.
import http from 'http';
import {RestRouter} from '@e22m4u/ts-rest-router';
// создание маршрутизатора и регистрация контроллеров
const router = new RestRouter();
router.registerController(UserController);
router.registerController(ProductController);
// создание сервера и регистрация обработчика запросов
const server = new http.Server();
server.on('request', router.requestListener);
// запуск сервера
server.listen('8080', '0.0.0.0', () => {
console.log(`Server is running on http://localhost:8080`);
});Валидация
Указанные ниже декораторы используются для инъекции соответствующих параметров
запроса в качестве аргументов метода контроллера. Каждый из указанных декораторов
имеет параметр schemaOrType, в котором определяется тип ожидаемого значения
или схема для проверки данных.
@requestParam(name: string, schemaOrType?: DataSchema | DataType)
- извлечение URL параметра по названию;@requestQuery(name: string, schemaOrType?: DataSchema | DataType)
- извлечение query параметра по названию;@requestBody(schemaOrType?: DataSchema | DataType)
- извлечение тела запроса;@requestField(name: string, schemaOrType?: DataSchema | DataType)
- извлечение свойства из тела запроса;@requestHeader(name: string, schemaOrType?: DataSchema | DataType)
- извлечение заголовка запроса по названию;@requestCookie(name: string, schemaOrType?: DataSchema | DataType)
- извлечение cookie запроса по названию;
Проверка входящих данных выполняется встроенным модулем @e22m4u/ts-data-schema (не требует установки). Ниже приводятся константы для определения допустимых типов извлекаемого значения.
DataType.ANY- принимает любой типDataType.STRING- строковые значенияDataType.NUMBER- числовые значенияDataType.BOOLEAN- логические значенияDataType.ARRAY- массивыDataType.OBJECT- объекты (не экземпляры)
Для определения дополнительных условий, используется объект DataSchema,
с помощью которого можно определить структуру ожидаемого объекта, допустимые
элементы массива, функции-валидаторы и другие ограничения входящих данных.
type DataSchema = {
type: DataType;
items?: DataSchema;
properties?: {[key: string]: DataSchema};
required?: boolean;
validate?: CallableValidator | CallableValidator[];
default?: unknown;
}Пример проверки передаваемого объекта методом POST:
import {DataType} from '@e22m4u/ts-rest-router';
import {getAction} from '@e22m4u/ts-rest-router';
import {postAction} from '@e22m4u/ts-rest-router';
import {requestField} from '@e22m4u/ts-rest-router';
import {restController} from '@e22m4u/ts-rest-router';
@restController('users')
class UserController {
@postAction() // POST /users
async create(
@requestBody({ // декоратор тела запроса
type: DataType.OBJECT, // в теле запроса ожидается объект
properties: {
name: { // схема свойства "name"
type: DataType.STRING, // свойство должно содержать строку
required: true, // свойство не может содержать undefined или null
validate: v => v.length > 2, // проверка длины строки
},
age: { // схема свойства "age"
type: DataType.NUMBER, // свойство должно являться числом
}
},
})
body: {name: string, age?: number},
) {
return {
id: 1,
name: body.name,
age: body.age,
};
}
}Декораторы
Контроллер и методы:
@restController- определяет класс как контроллер;@restAction- базовый декоратор для методов;@getAction- метод GET;@postAction- метод POST;@putAction- метод PUT;@patchAction- метод PATCH;@deleteAction- метод DELETE;
Хуки запроса:
@beforeAction- middleware перед обработкой запроса;@afterAction- middleware после обработки запроса;
Параметры запроса:
@requestParam- определенный URL параметр;@requestParams- все параметры URL как объект;@requestQuery- определенный query параметр;@requestQueries- все query параметры как объект;@requestBody- тело запроса;@requestField- поле в теле запроса;@requestHeader- определенный заголовок запроса;@requestHeaders- все заголовки запроса как объект;@requestCookie- определенный cookie запроса;@requestCookies- все cookies запроса как объект;@requestContext- доступ к контексту запроса;@requestData- доступ к данным запроса;@httpRequest- экземплярIncomingMessage;@httpResponse- экземплярServerResponse;
@restController(options?: ControllerOptions)
Определение контроллера.
@restController()
class UserController {
// ...
}Определение базового пути.
@restController('users')
class UserController {
// ...
}Дополнительные параметры декоратора.
@restController({
path: 'api', // базовый путь
before: [authMiddleware], // middleware до обработки запроса
after: [loggerMiddleware], // middleware после обработки запроса
})
class UserController {
// ...
}@getAction(path: string, options?: ActionOptions)
Определение метода GET.
@restController('users')
class UserController {
@getAction('whoAmI') // маршрут GET /users/whoAmI
async whoAmI() {
return { // если метод возвращает объект,
name: 'John', // то результат будет представлен
surname: 'Doe', // как "Content-Type: application/json"
};
}
}Дополнительные параметры декоратора.
@restController('users')
class UserController {
@getAction('whoAmI', { // маршрут GET /users/whoAmI
before: [authMiddleware], // middleware до обработки запроса
after: [loggerMiddleware], // middleware после обработки запроса
})
async whoAmI() {
return {
name: 'John',
surname: 'Doe',
};
}
}@requestContext(propertyName?: string)
Доступ к контексту запроса.
import {RequestContext} from '@e22m4u/js-trie-router';
@restController('users')
class UserController {
@getAction(':id')
findById(
@requestContext() // инъекция контекста запроса
ctx: RequestContext, // в качестве аргумента
) {
console.log(ctx.req); // IncomingMessage
console.log(ctx.res); // ServerResponse
console.log(ctx.params); // {id: 10}
console.log(ctx.query); // {include: 'city'}
console.log(ctx.headers); // {cookie: 'foo=bar; baz=qux;'}
console.log(ctx.cookie); // {foo: 'bar', baz: 'qux'}
console.log(ctx.method); // "GET"
console.log(ctx.path); // "/users/10?include=city"
console.log(ctx.pathname); // "/users/10"
// ...
}
}Доступ к свойствам контекста.
import {ServerResponse} from 'http';
import {IncomingMessage} from 'http';
@restController('/users') // путь контроллера
class UserController { // класс контроллера
@getAction('/:id') // маршрут GET /users/:id
findById(
@requestContext('req') // декоратор контекста запроса
req: IncomingMessage, // включающий свойство "req"
@requestContext('res') // декоратор контекста запроса
res: ServerResponse, // включающий свойство "res"
) {
console.log(req); // IncomingMessage
console.log(res); // ServerResponse
}
}Свойства контекста:
container: ServiceContainerэкземпляр сервис-контейнераreq: IncomingMessageнативный поток входящего запросаres: ServerResponseнативный поток ответа сервераparams: ParsedParamsобъект ключ-значение с параметрами путиquery: ParsedQueryобъект ключ-значение с параметрами строки запросаheaders: ParsedHeadersобъект ключ-значение с заголовками запросаcookie: ParsedCookieобъект ключ-значение разобранного заголовкаcookiemethod: stringметод запроса в верхнем регистре, напримерGET,POSTи т.д.path: stringпуть включающий строку запроса, например/myPath?foo=barpathname: stringпуть запроса, например/myMathbody: unknownтело запроса
Отладка
Установка переменной DEBUG включает вывод логов.
DEBUG=tsRestRouter* npm run testТесты
npm run testЛицензия
MIT
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
11 months ago
11 months ago
11 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago