# @travetto/rest

> Declarative api for RESTful APIs with support for the dependency injection module.

Latest version **5.1.0** (published 2025-01-26) · MIT license · 0 weekly downloads

## Install

```sh
npm install @travetto/rest
pnpm add @travetto/rest
yarn add @travetto/rest
bun add @travetto/rest
```

## Health

**Score 40/100 (D)** — status: stable.

Positive: no vulnerabilities; high maintenance score.

Warnings: low downloads; no types; no esm support.

Negative: stale.

## Facts

| | |
|---|---|
| Version | 5.1.0 |
| Published | 2025-01-26 |
| First published | 2018-08-19 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 12 |
| Unpacked size | 142.7 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 23 |
| Author | Travetto Framework |
| Maintainers | arcsine |
| Keywords | rest, dependency-injection, decorators, travetto, typescript |

## Links

- npm: https://www.npmjs.com/package/@travetto/rest
- Repository: https://github.com/travetto/travetto
- Homepage: https://travetto.io
- Issues: https://github.com/travetto/travetto/issues
- npm.io page: https://npm.io/package/@travetto/rest

## Dependencies (12)

- [cookies](https://npm.io/package/cookies.md) ^0.9.1
- [raw-body](https://npm.io/package/raw-body.md) ^3.0.0
- [inflation](https://npm.io/package/inflation.md) ^2.1.0
- [@travetto/di](https://npm.io/package/@travetto/di.md) ^5.1.0
- [@types/cookies](https://npm.io/package/@types/cookies.md) ^0.9.0
- [@travetto/config](https://npm.io/package/@travetto/config.md) ^5.1.0
- [@travetto/schema](https://npm.io/package/@travetto/schema.md) ^5.1.0
- [@types/inflation](https://npm.io/package/@types/inflation.md) ^2.0.4
- [@travetto/context](https://npm.io/package/@travetto/context.md) ^5.1.0
- [@travetto/runtime](https://npm.io/package/@travetto/runtime.md) ^5.1.0
- [@travetto/registry](https://npm.io/package/@travetto/registry.md) ^5.1.0
- [@types/express-serve-static-core](https://npm.io/package/@types/express-serve-static-core.md) ^5.0.5

## Alternatives

- [@openai/codex-sdk](https://npm.io/package/@openai/codex-sdk.md) — 731.4K weekly downloads
- [babel-plugin-transform-react-jsx](https://npm.io/package/babel-plugin-transform-react-jsx.md) — 565.0K weekly downloads
- [babel-helper-remove-or-void](https://npm.io/package/babel-helper-remove-or-void.md) — 508.5K weekly downloads
- [@pnpm/store-controller-types](https://npm.io/package/@pnpm/store-controller-types.md) — 186.9K weekly downloads
- [react-native-signature-canvas](https://npm.io/package/react-native-signature-canvas.md) — 155.6K weekly downloads

## Recent versions

- 5.1.0 (latest) — 2025-01-26
- 6.0.0-rc.1 (rc) — 2025-02-04
- 2.0.0-alpha.18 (alpha) — 2021-05-05
- 1.1.0-rc.0 (next) — 2020-09-20
- 1.0.0-beta.10 (beta) — 2019-10-04
- 6.0.0-rc.0 — 2025-01-31
- 5.0.20 — 2025-01-16
- 5.0.19 — 2025-01-16
- 5.0.18 — 2025-01-01
- 5.0.17 — 2024-11-16
- 5.0.16 — 2024-10-26
- 5.0.15 — 2024-10-24
- 5.0.14 — 2024-10-20
- 5.0.13 — 2024-10-10
- 5.0.12 — 2024-10-06
- … 322 more at https://npm.io/package/@travetto/rest/versions

## README

<!-- This file was generated by @travetto/doc and should not be modified directly -->
<!-- Please modify https://github.com/travetto/travetto/tree/main/module/rest/DOC.tsx and execute "npx trv doc" to rebuild -->
# RESTful API

## Declarative api for RESTful APIs with support for the dependency injection module.

**Install: @travetto/rest**
```bash
npm install @travetto/rest

# or

yarn add @travetto/rest
```

The module provides a declarative API for creating and describing an RESTful application.  Since the framework is declarative, decorators are used to configure almost everything. The module is framework agnostic (but resembles [express](https://expressjs.com) in the [Request](https://github.com/travetto/travetto/tree/main/module/rest/src/types.ts#L31) and [Response](https://github.com/travetto/travetto/tree/main/module/rest/src/types.ts#L161) objects). This module is built upon the [Schema](https://github.com/travetto/travetto/tree/main/module/schema#readme "Data type registry for runtime validation, reflection and binding.") structure, and all controller method parameters follow the same rules/abilities as any [@Field](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L25) in a standard [@Schema](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/schema.ts#L14) class.

## Routes: Controller
To define a route, you must first declare a [@Controller](https://github.com/travetto/travetto/tree/main/module/rest/src/decorator/controller.ts#L9) which is only allowed on classes. Controllers can be configured with:
   *  `title` - The definition of the controller
   *  `description` - High level description fo the controller
Additionally, the module is predicated upon [Dependency Injection](https://github.com/travetto/travetto/tree/main/module/di#readme "Dependency registration/management and injection support."), and so all standard injection techniques (constructor, fields) work for registering dependencies. 

[JSDoc](http://usejsdoc.org/about-getting-started.html) comments can also be used to define the `title` attribute.

**Code: Basic Controller Registration**
```typescript
import { Controller } from '@travetto/rest';

@Controller('/simple')
class SimpleController {
  // routes
}
```

## Routes: Endpoints
Once the controller is declared, each method of the controller is a candidate for routing.  By design, everything is asynchronous, and so async/await is natively supported. 

The HTTP methods that are supported via:
   *  [@Get](https://github.com/travetto/travetto/tree/main/module/rest/src/decorator/endpoint.ts#L32)
   *  [@Post](https://github.com/travetto/travetto/tree/main/module/rest/src/decorator/endpoint.ts#L39)
   *  [@Put](https://github.com/travetto/travetto/tree/main/module/rest/src/decorator/endpoint.ts#L46)
   *  [@Delete](https://github.com/travetto/travetto/tree/main/module/rest/src/decorator/endpoint.ts#L59)
   *  [@Patch](https://github.com/travetto/travetto/tree/main/module/rest/src/decorator/endpoint.ts#L53)
   *  [@Head](https://github.com/travetto/travetto/tree/main/module/rest/src/decorator/endpoint.ts#L65)
   *  [@Options](https://github.com/travetto/travetto/tree/main/module/rest/src/decorator/endpoint.ts#L71)
Each endpoint decorator handles the following config:
   *  `title` - The definition of the endpoint
   *  `description` - High level description fo the endpoint
   *  `responseType?` - Class describing the response type
   *  `requestType?` - Class describing the request body
[JSDoc](http://usejsdoc.org/about-getting-started.html) comments can also be used to define the `title` attribute, as well as describing the parameters using `@param` tags in the comment. 

Additionally, the return type of the method will also be used to describe the `responseType` if not specified manually.

**Code: Controller with Sample Route**
```typescript
import { Get, Controller } from '@travetto/rest';

class Data { }

@Controller('/simple')
class SimpleController {

  /**
   * Gets the most basic of data
   */
  @Get('/')
  async simpleGet() {
    let data: Data | undefined;
    //
    return data;
  }
}
```

**Note**: In development mode the module supports hot reloading of `class`es.  Routes can be added/modified/removed at runtime.

### Parameters
Endpoints can be configured to describe and enforce parameter behavior.  Request parameters can be defined in five areas:
   *  [@Path](https://github.com/travetto/travetto/tree/main/module/rest/src/decorator/param.ts#L44) - Path params
   *  [@Query](https://github.com/travetto/travetto/tree/main/module/rest/src/decorator/param.ts#L50) - Query params
   *  [@Body](https://github.com/travetto/travetto/tree/main/module/rest/src/decorator/param.ts#L62) - Request body (in it's entirety), with support for validation
   *  [@Header](https://github.com/travetto/travetto/tree/main/module/rest/src/decorator/param.ts#L56) - Header values
   *  [@Context](https://github.com/travetto/travetto/tree/main/module/rest/src/decorator/param.ts#L38) - Special values exposed (e.g. [Request](https://github.com/travetto/travetto/tree/main/module/rest/src/types.ts#L31), [Response](https://github.com/travetto/travetto/tree/main/module/rest/src/types.ts#L161), etc.)
Each [@Param](https://github.com/travetto/travetto/tree/main/module/rest/src/decorator/param.ts#L25) can be configured to indicate:
   *  `name` - Name of param, field name, defaults to handler parameter name if necessary
   *  `description` - Description of param, pulled from [JSDoc](http://usejsdoc.org/about-getting-started.html), or defaults to name if empty
   *  `required?` - Is the field required?, defaults to whether or not the parameter itself is optional
   *  `type` - The class of the type to be enforced, pulled from parameter type
[JSDoc](http://usejsdoc.org/about-getting-started.html) comments can also be used to describe parameters using `@param` tags in the comment.

**Code: Full-fledged Controller with Routes**
```typescript
import { Get, Controller, Post, Query, Request } from '@travetto/rest';
import { Integer, Min } from '@travetto/schema';

import { MockService } from './mock';

@Controller('/simple')
export class Simple {

  service: MockService;

  constructor(service: MockService) {
    this.service = service;
  }

  /**
   * Get a random user by name
   */
  @Get('/name')
  async getName() {
    const user = await this.service.fetch();
    return `/simple/name => ${user.first.toLowerCase()}`;
  }

  /**
   * Get a user by id
   */
  @Get('/:id')
  async getById(id: number) {
    const user = await this.service.fetch(id);
    return `/simple/id => ${user.first.toLowerCase()}`;
  }

  @Post('/name')
  async createName(person: { name: string }) {
    await this.service.update({ name: person.name });
    return { success: true };
  }

  @Get('img/*')
  async getImage(
    req: Request,
    @Query('w') @Integer() @Min(100) width?: number,
    @Query('h') @Integer() @Min(100) height?: number
  ) {
    const img = await this.service.fetchImage(req.path, { width, height });
    return img;
  }
}
```

### Body and QuerySchema
The module provides high level access for [Schema](https://github.com/travetto/travetto/tree/main/module/schema#readme "Data type registry for runtime validation, reflection and binding.") support, via decorators, for validating and typing request bodies. 

[@Body](https://github.com/travetto/travetto/tree/main/module/rest/src/decorator/param.ts#L62) provides the ability to convert the inbound request body into a schema bound object, and provide validation before the controller even receives the request.

**Code: Using Body for POST requests**
```typescript
import { Schema } from '@travetto/schema';
import { Controller, Post, Body } from '@travetto/rest';

@Schema()
class User {
  name: string;
  age: number;
}

@Controller('/user')
class UserController {

  private service: {
    update(user: User): Promise<User>;
  };

  @Post('/saveUser')
  async save(@Body() user: User) {
    user = await this.service.update(user);
    return { success: true };
  }
}
```

The framework provides the ability to convert the inbound request query into a schema bound object, and provide validation before the controller even receives the request.

**Code: Using Query + Schema for GET requests**
```typescript
import { Schema } from '@travetto/schema';
import { Controller, Get } from '@travetto/rest';

@Schema()
class SearchParams {
  page: number = 0;
  pageSize: number = 100;
}

@Controller('/user')
class UserController {

  private service: {
    search(query: SearchParams): Promise<number[]>;
  };

  @Get('/search')
  async search(query: SearchParams) {
    return await this.service.search(query);
  }
}
```

Additionally, schema related inputs can also be used with `interface`s and `type` literals in lieu of classes. This is best suited for simple types:

**Code: Using QuerySchema with a type literal**
```typescript
import { Controller, Get } from '@travetto/rest';

type Paging = {
  page?: number;
  pageSize?: number;
};

@Controller('/user')
class UserController {

  private service: {
    search(query: Paging): Promise<number>;
  };

  @Get('/search')
  async search(query: Paging = { page: 0, pageSize: 100 }) {
    return await this.service.search(query);
  }
}
```

## Input/Output
The module provides standard structure for rendering content on the response.  This includes:
   *  JSON
   *  String responses
   *  Files
Per the [Runtime](https://github.com/travetto/travetto/tree/main/module/runtime#readme "Runtime for travetto applications.") module, the following types automatically have rest support as well:
   *  `Error` - Serializes to a standard object, with status, and the error message.
   *  `AppError` - Serializes like `Error` but translates the error category to an HTTP status
Additionally, the [Schema](https://github.com/travetto/travetto/tree/main/module/schema#readme "Data type registry for runtime validation, reflection and binding.") module supports typing requests and request bodies for run-time validation of requests.

## Running an App
By default, the framework provides a default [@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/decorators.ts#L84) for [RestApplication](https://github.com/travetto/travetto/tree/main/module/rest/src/application/rest.ts#L19) that will follow default behaviors, and spin up the REST server.

**Terminal: Standard application**
```bash
$ trv run:rest

Initialized {
  manifest: {
    main: {
      name: '@travetto-doc/rest',
      folder: './doc-exec'
    },
    workspace: {
      name: '@travetto-doc/rest',
      path: './doc-exec',
      mono: false,
      manager: 'npm',
      type: 'commonjs',
      defaultEnv: 'local'
    }
  },
  runtime: {
    env: 'local',
    debug: false,
    production: false,
    dynamic: false,
    resourcePaths: [ './doc-exec/resources' ],
    profiles: []
  },
  config: {
    sources: [ { priority: 999, source: 'memory://override' } ],
    active: {
      RestAcceptsConfig: { types: {} },
      RestAsyncContextConfig: {},
      RestBodyParseConfig: { limit: '1mb', parsingTypes: {} },
      RestConfig: {
        serve: true,
        port: 3000,
        trustProxy: false,
        hostname: 'localhost',
        bindAddress: '0.0.0.0',
        baseUrl: 'http://localhost:3000',
        defaultMessage: true
      },
      RestCookieConfig: { signed: true, httpOnly: true, sameSite: 'lax' },
      RestCorsConfig: {},
      RestGetCacheConfig: {},
      RestLogRoutesConfig: {},
      RestSslConfig: { active: false }
    }
  }
}
Listening { port: 3000 }
```

### Creating a Custom CLI Entry Point
To customize a REST server, you may need to construct an entry point using the [@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/decorators.ts#L84) decorator. This could look like:

**Code: Application entry point for Rest Applications**
```typescript
import { Env } from '@travetto/runtime';
import { CliCommand } from '@travetto/cli';
import { DependencyRegistry } from '@travetto/di';
import { RootRegistry } from '@travetto/registry';
import { RestApplication, RestSslConfig } from '@travetto/rest';

@CliCommand({ runTarget: true })
export class SampleApp {

  preMain(): void {
    Env.TRV_ENV.set('prod');
    Env.NODE_ENV.set('production');
  }

  async main() {
    console.log('CUSTOM STARTUP');
    await RootRegistry.init();
    const ssl = await DependencyRegistry.getInstance(RestSslConfig);
    ssl.active = true;

    // Configure server before running
    return DependencyRegistry.runInstance(RestApplication);
  }
}
```

And using the pattern established in the [Command Line Interface](https://github.com/travetto/travetto/tree/main/module/cli#readme "CLI infrastructure for Travetto framework") module, you would run your program using `npx trv run:rest:custom`.

**Terminal: Custom application**
```bash
$ trv run:rest:custom

CUSTOM STARTUP
Initialized {
  manifest: {
    main: {
      name: '@travetto-doc/rest',
      folder: './doc-exec'
    },
    workspace: {
      name: '@travetto-doc/rest',
      path: './doc-exec',
      mono: false,
      manager: 'npm',
      type: 'commonjs',
      defaultEnv: 'local'
    }
  },
  runtime: {
    env: 'prod',
    debug: false,
    production: true,
    dynamic: false,
    resourcePaths: [ './doc-exec/resources' ],
    profiles: []
  },
  config: {
    sources: [ { priority: 999, source: 'memory://override' } ],
    active: {
      RestAcceptsConfig: { types: {} },
      RestAsyncContextConfig: {},
      RestBodyParseConfig: { limit: '1mb', parsingTypes: {} },
      RestConfig: {
        serve: true,
        port: 3000,
        trustProxy: false,
        hostname: 'localhost',
        bindAddress: '0.0.0.0',
        baseUrl: 'http://localhost:3000',
        defaultMessage: true
      },
      RestCookieConfig: { signed: true, httpOnly: true, sameSite: 'lax' },
      RestCorsConfig: {},
      RestGetCacheConfig: {},
      RestLogRoutesConfig: {},
      RestSslConfig: { active: true }
    }
  }
}
Listening { port: 3000 }
```

## Interceptors
[RestInterceptor](https://github.com/travetto/travetto/tree/main/module/rest/src/interceptor/types.ts#L28)s  are a key part of the rest framework, to allow for conditional functions to be added, sometimes to every route, and other times to a select few. Express/Koa/Fastify are all built around the concept of middleware, and interceptors are a way of representing that.

**Code: A Trivial Interceptor**
```typescript
import { RestInterceptor, SerializeInterceptor, FilterContext } from '@travetto/rest';
import { Injectable } from '@travetto/di';

@Injectable()
export class HelloWorldInterceptor implements RestInterceptor {

  dependsOn = [SerializeInterceptor];

  intercept(ctx: FilterContext) {
    console.log('Hello world!');
  }
}
```

**Note**: The example above defines the interceptor to run after another interceptor class. The framework will automatically sort the interceptors by the before/after requirements to ensure the appropriate order of execution.
Out of the box, the rest framework comes with a few interceptors, and more are contributed by other modules as needed.  The default interceptor set is:

### BodyParseInterceptor
[BodyParseInterceptor](https://github.com/travetto/travetto/tree/main/module/rest/src/interceptor/body-parse.ts#L38) handles the inbound request, and converting the body payload into an appropriate format.Additionally it exposes the original request as the raw property on the request.

**Code: Body Parse Config**
```typescript
export class RestBodyParseConfig extends ManagedInterceptorConfig {
  /**
   * Max body size limit
   */
  limit: string = '1mb';
  /**
   * How to interpret different content types
   */
  parsingTypes: Record<string, ParserType> = {};
}
```

### SerializeInterceptor
[SerializeInterceptor](https://github.com/travetto/travetto/tree/main/module/rest/src/interceptor/serialize.ts#L14) is what actually sends the response to the requestor. Given the ability to prioritize interceptors, another interceptor can have higher priority and allow for complete customization of response handling.

### CorsInterceptor
[CorsInterceptor](https://github.com/travetto/travetto/tree/main/module/rest/src/interceptor/cors.ts#L45) allows cors functionality to be configured out of the box, by setting properties in your `application.yml`, specifically, `rest.cors.active: true`

**Code: Cors Config**
```typescript
export class RestCorsConfig extends ManagedInterceptorConfig {
  /**
   * Allowed origins
   */
  origins?: string[];
  /**
   * Allowed http methods
   */
  methods?: Request['method'][];
  /**
   * Allowed http headers
   */
  headers?: string[];
  /**
   * Support credentials?
   */
  credentials?: boolean;

  @Ignore()
  resolved: {
    origins: Set<string>;
    methods: string;
    headers: string;
    credentials: boolean;
  };
}
```

### CookiesInterceptor
[CookiesInterceptor](https://github.com/travetto/travetto/tree/main/module/rest/src/interceptor/cookies.ts#L72) is responsible for processing inbound cookie headers and populating the appropriate data on the request, as well as sending the appropriate response data

**Code: Cookies Config**
```typescript
export class RestCookieConfig extends ManagedInterceptorConfig {
  /**
   * Are they signed
   */
  signed = true;
  /**
   * Supported only via http (not in JS)
   */
  httpOnly = true;
  /**
   * Enforce same site policy
   */
  sameSite: cookies.SetOption['sameSite'] | 'lax' = 'lax';
  /**
   * The signing keys
   */
  @Secret()
  keys = ['default-insecure'];
  /**
   * Is the cookie only valid for https
   */
  secure?: boolean;
  /**
   * The domain of the cookie
   */
  domain?: string;
}
```

### GetCacheInterceptor
[GetCacheInterceptor](https://github.com/travetto/travetto/tree/main/module/rest/src/interceptor/get-cache.ts#L16) by default, disables caching for all GET requests if the response does not include caching headers.  This can be disabled by setting `rest.disableGetCache: true` in your config.

### LoggingInterceptor
[LoggingInterceptor](https://github.com/travetto/travetto/tree/main/module/rest/src/interceptor/logging.ts#L19) allows for logging of all requests, and their response codes.  You can deny/allow specific routes, by setting config like so

**Code: Control Logging**
```yaml
rest.log:
- '/controller1'
- '!/controller1:*'
- '/controller2:/path'
- '!/controller3:/path/*'
```

### AsyncContextInterceptor
[AsyncContextInterceptor](https://github.com/travetto/travetto/tree/main/module/rest/src/interceptor/context.ts#L18) is responsible for sharing context across the various layers that may be touched by a request. There is a negligible performance impact to the necessary booking keeping and so this interceptor can easily be disabled as needed.

### Custom Interceptors
Additionally it is sometimes necessary to register custom interceptors.  Interceptors can be registered with the [Dependency Injection](https://github.com/travetto/travetto/tree/main/module/di#readme "Dependency registration/management and injection support.") by implementing the [RestInterceptor](https://github.com/travetto/travetto/tree/main/module/rest/src/interceptor/types.ts#L28) interface.  The interceptors are tied to the defined [Request](https://github.com/travetto/travetto/tree/main/module/rest/src/types.ts#L31) and [Response](https://github.com/travetto/travetto/tree/main/module/rest/src/types.ts#L161) objects of the framework, and not the underlying app framework.  This allows for Interceptors to be used across multiple frameworks as needed. A simple logging interceptor:

**Code: Defining a new Interceptor**
```typescript
import { FilterContext, RestInterceptor } from '@travetto/rest';
import { Injectable } from '@travetto/di';

class Appender {
  write(...args: unknown[]): void { }
}

@Injectable()
export class LoggingInterceptor implements RestInterceptor {

  appender: Appender;

  constructor(appender: Appender) {
    this.appender = appender;
  }

  async intercept({ req }: FilterContext) {
    // Write request to database
    this.appender.write(req.method, req.path, req.query);
  }
}
```

A `next` parameter is also available to allow for controlling the flow of the request, either by stopping the flow of interceptors, or being able to determine when a request starts, and when it is ending.

**Code: Defining a fully controlled Interceptor**
```typescript
import { RestInterceptor, FilterContext, FilterNext } from '@travetto/rest';
import { Injectable } from '@travetto/di';

@Injectable()
export class LoggingInterceptor implements RestInterceptor {
  async intercept(ctx: FilterContext, next: FilterNext) {
    const start = Date.now();
    try {
      await next();
    } finally {
      console.log('Request complete', { time: Date.now() - start });
    }
  }
}
```

Currently [Rest Upload Support](https://github.com/travetto/travetto/tree/main/module/rest-upload#readme "Provides integration between the travetto asset and rest module.") is implemented in this fashion, as well as [Rest Auth](https://github.com/travetto/travetto/tree/main/module/auth-rest#readme "Rest authentication integration support for the Travetto framework").

### Configuring Interceptors
All framework-provided interceptors, follow the same patterns for general configuration.  This falls into three areas:

#### Enable/disable of individual interceptors via configuration

**Code: Sample interceptor disabling configuration**
```yaml
rest:
  cors:
    disabled: true
```

#### Path-based control for various routes within the application

**Code: Sample interceptor path managed configuration**
```yaml
rest:
  cors:
    paths: 
      - '!/public/user'
      - '/public/*'
```

#### Route-enabled control via decorators

**Code: Sample controller with route-level allow/deny**
```typescript
import { Controller, Get, Query, ConfigureInterceptor, CorsInterceptor } from '@travetto/rest';

@Controller('/allowDeny')
@ConfigureInterceptor(CorsInterceptor, { disabled: true })
export class AlowDenyController {

  @Get('/override')
  @ConfigureInterceptor(CorsInterceptor, { disabled: false })
  cookies(@Query() value: string) {

  }
}
```

The resolution logic is as follows:
   *  Determine if interceptor is disabled, this takes precedence.
   *  Check the route against the path allow/deny list.  If matched (positive or negative), this wins.
   *  Finally check to see if the interceptor has custom applies logic.  If it does, match against the configuration for the route.
   *  By default, if nothing else matched, assume the interceptor is valid.

## Cookie Support
[express](https://expressjs.com)/[koa](https://koajs.com/)/[fastify](https://www.fastify.io/) all have their own cookie implementations that are common for each framework but are somewhat incompatible.  To that end, cookies are supported for every platform, by using [cookies](https://www.npmjs.com/package/cookies).  This functionality is exposed onto the [Request](https://github.com/travetto/travetto/tree/main/module/rest/src/types.ts#L31)/[Response](https://github.com/travetto/travetto/tree/main/module/rest/src/types.ts#L161) object following the pattern set forth by Koa (this is the library Koa uses).  This choice also enables better security support as we are able to rely upon standard behavior when it comes to cookies, and signing.

**Code: Sample Cookie Usage**
```typescript
import { GetOption, SetOption } from 'cookies';

import { Controller, Get, Query, Request, Response } from '@travetto/rest';

@Controller('/simple')
export class SimpleRoutes {

  private getOptions: GetOption;
  private setOptions: SetOption;

  @Get('/cookies')
  cookies(req: Request, res: Response, @Query() value: string) {
    req.cookies.get('name', this.getOptions);
    res.cookies.set('name', value, this.setOptions);
  }
}
```

## SSL Support
Additionally the framework supports SSL out of the box, by allowing you to specify your public and private keys for the cert.  In dev mode, the framework will also automatically generate a self-signed cert if:
   *  SSL support is configured
   *  [node-forge](https://www.npmjs.com/package/node-forge) is installed
   *  Not running in prod
   *  No keys provided
This is useful for local development where you implicitly trust the cert. 

SSL support can be enabled by setting `rest.ssl.active: true` in your config. The key/cert can be specified as string directly in the config file/environment variables.  The key/cert can also be specified as a path to be picked up by [RuntimeResources](https://github.com/travetto/travetto/tree/main/module/runtime/src/resources.ts#L8).

## Full Config
The entire [RestConfig](https://github.com/travetto/travetto/tree/main/module/rest/src/application/config.ts#L12) which will show the full set of valid configuration parameters for the rest module.

---
_Source: https://npm.io/package/@travetto/rest · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
