# @travetto/express

> Declarative wrapper around express with support for the dependency injection module.

Latest version **0.2.2** (published 2018-08-13) · MIT license · 0 weekly downloads

> **Deprecated.** This package is deprecated.

## Install

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

## Health

**Score 10/100 (F)** — status: deprecated.

Negative: deprecated.

## Facts

| | |
|---|---|
| Version | 0.2.2 |
| Published | 2018-08-13 |
| First published | 2017-10-01 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 11 |
| Unpacked size | 47.8 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 23 |
| Author | Travetto Framework |
| Maintainers | arcsine |
| Keywords | express, dependency-injection, decorators, travetto, typescript |

## Links

- npm: https://www.npmjs.com/package/@travetto/express
- 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/express

## Dependencies (11)

- [express](https://npm.io/package/express.md) ^4.16.3
- [compression](https://npm.io/package/compression.md) ^1.7.2
- [@travetto/di](https://npm.io/package/@travetto/di.md) ^0.2.2
- [@travetto/log](https://npm.io/package/@travetto/log.md) ^0.2.2
- [cookie-parser](https://npm.io/package/cookie-parser.md) ^1.4.3
- [@types/express](https://npm.io/package/@types/express.md) ^4.11.1
- [express-session](https://npm.io/package/express-session.md) ^1.15.6
- [@types/body-parser](https://npm.io/package/@types/body-parser.md) ^1.17.0
- [@types/compression](https://npm.io/package/@types/compression.md) 0.0.36
- [@types/cookie-parser](https://npm.io/package/@types/cookie-parser.md) ^1.4.1
- [@types/express-session](https://npm.io/package/@types/express-session.md) ^1.15.10

## 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

- 0.2.2 (latest) — 2018-08-13
- 0.2.0 — 2018-08-10
- 0.1.11 — 2018-07-17
- 0.1.10 — 2018-07-17
- 0.1.9 — 2018-07-17
- 0.1.8 — 2018-07-17
- 0.1.7 — 2018-07-16
- 0.1.6 — 2018-07-15
- 0.1.5 — 2018-07-15
- 0.1.4 — 2018-07-15
- 0.1.3 — 2018-07-14
- 0.1.2 — 2018-07-14
- 0.1.1 — 2018-07-14
- 0.0.31 — 2018-07-09
- 0.0.30 — 2018-07-03
- … 28 more at https://npm.io/package/@travetto/express/versions

## README

travetto: Express
===
The module provides a declarative API for creating and describing an [`express`](https://expressjs.com) application.  Since the  framework is declarative, decorators are used to configure almost everything. 

## Route management 

### Controller
To define a route, you must first declare a `@Controller` which is only allowed on classes. Controllers can be configured with:
* `title` - The definition of the controller
* `description` - High level description fo the controller

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

### 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`
* `@Post`
* `@Put`
* `@Delete`
* `@Patch`
* `@Head`
* `@Options`

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 annotated return type on the method will also be used to describe the `responseType` if specified.

### Parameters
Endpoints can be configured to describe and enforce parameter behavior.  Request parameters can be defined  in three areas:
* `@PathParam`
* `@QueryParam`
* `@BodyParam`

Each `@*Param` can be configured to indicate:
* `name` - Name of param, field name
* `description` - Description of param
* `required?` - Is the field required?
* `type` - The class of the type to be enforced

[`JSDoc`](http://usejsdoc.org/about-getting-started.html) comments can also be used to describe parameters using `@param` tags in the comment.

### Example
A simple example is:

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

  constructor(private service: MockService) {}

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

  /**
   * Get a user by id
   */
  @Get('/:id')
  @PathParam({ name: 'id', type: Number })
  async doIt(req: Request): string {
    const user = await this.service.fetch(req.params.id);
    return `/simple/name => ${user.first.toLowerCase()}`;
  }


  @Post('/name')
  async doIt(req: Request) {
    const user = await this.service.update({ name: req.body.name });
    return { success : true };
  }

  @Get(/\/img(.*)[.](jpg|png|gif)/)
  @QueryParam({ name: 'w', type: Number })
  @QueryParam({ name: 'h', type: Number })
  async getImage(req: Request, res:Response) {
    const img =  await this.service.fetch(req.path, req.query);
    ... return image ...
  }
}
```

Additionally, the module is predicated upon [`Dependency Injection`](https://github.com/travetto/di), and so all standard di techniques work on controllers.

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

## Input/Output
The module provides standard structure for rendering content on the response.  This includes:
* JSON
* String responses
* Files 

Additionally, there is support for typing requests and request bodies.  This can be utilized by other modules to handle special types of requests.

## Express initialization
When working with express applications, the module provides what is assumed to be a sufficient set of basic filters. Specifically:
* ```compression()```
* ```cookieParser()```
* ```bodyParser.json()```
* ```bodyParser.urlencoded()```
* ```bodyParser.raw({ type: 'image/*' })```
* ```session(this.config.session)```

Additionally it is sometimes necessary to register custom filters.  Filters can be registered with the [`Dependency Injection`](https://github.com/travetto/di) by extending the [`Operator`](./src/service/operator) class.  

```typescript
@Injectable({
  target: ExpressOperator,
  qualifier: AUTH
})
export class LoggingOperator extends ExpressOperator {
  operate(app: ExpressApp) {
    app.get().use(async (req, res, next) => {

      console.log(req.method, req.path, req.query);

      if (next) {
        next();
      }
    });
  }
}
```

## Documentation
As shown above, the controllers and endpoints can be described via decorators, comments, or typings. This only provides the general metadata internally. To generate a usable API doc, a separate module should be used. Currently [`Swagger`](https://github.com/travetto/swagger) is the only module that exists, but other implementations should be available in the future.

## Extensions
Integration with other modules can be supported by extensions.  The dependencies are in `optionalExtensionDependencies` and must be installed directly if you want to use them:

### Context
[`Context`](https://github.com/travetto/context) provides support for automatically injecting an async context into every request. The context management is provided via an `Operator` and is transparent to the programmer.

```typescript
 ...
  @Post('/preferences')
  @SchemaBody(User)
  async save(req: TypedBody<Preferences>) {
    await this.service.update(req.body);
    return { success : true };
  }
 ...
 class PreferenceService {
   private context: Context;

   async update(prefs: Preferences) {
     const userId = this.context.get().userId;
     ... store preferences for user ...
     return;  
   }
 }
```

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