# Getting started

Save your time by starting your project on one of this kit:

# Installation from scratch

You can get the latest version of Ts.ED using the following npm command:

$ npm install --save-dev typescript @types/express
$ npm install --save express@4 @tsed/core @tsed/di @tsed/common
1
2

TIP

The following modules are also recommended:

$ npm install --save body-parser compression cookie-parser method-override
$ npm install --save-dev ts-node nodemon
1
2

WARNING

It's really important to keep the same version for all @tsed/* packages. To prevent errors, fix the version for each Ts.ED packages:

{
  "dependencies": {
    "@tsed/common": "5.0.7",
    "@tsed/di": "5.0.7",
    "@tsed/core": "5.0.7",
    "@tsed/swagger": "5.0.7",
    "@tsed/testing": "5.0.7"
  }
} 
1
2
3
4
5
6
7
8
9

WARNING

Ts.ED requires Node >= 8, Express >= 4, TypeScript >= 2.0 and the experimentalDecorators, emitDecoratorMetadata, types and lib compilation options in your tsconfig.json file.

{
  "compilerOptions": {
    "baseUrl": ".",
    "outDir": "./dist",
    "target": "es2016",
    "lib": [
      "es2016",
      "dom"
    ],
    "typeRoots": [
      "./node_modules/@types"
    ],
    "module": "commonjs",
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "sourceMap": true,
    "declaration": false,
    "allowSyntheticDefaultImports": true
  },
  "include": [
    "./src/**/*.ts"
  ],
  "exclude": [
    "node_modules",
    "./public",
    "dist",
    "test"
  ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

TIP

You can copy this example of package.json to develop your application:

{
  "name": "@tsed/basic-example",
  "version": "1.0.0",
  "description": "Here an example to configure your server and how to create your first controller.",
  "main": "src/index.js",
  "scripts": {
    "clean": "rimraf '{src,test}/**/*.{js,js.map}'",
    "build": "yarn tsc",
    "test": "yarn clean && yarn test:lint && yarn test:coverage",
    "test:unit": "cross-env NODE_ENV=test mocha",
    "test:coverage": "cross-env NODE_ENV=test nyc mocha",
    "test:lint": "tslint --project tsconfig.json",
    "test:lint:fix": "tslint --project tsconfig.json --fix",
    "travis:deploy-once": "travis-deploy-once",
    "travis:coveralls": "nyc report --reporter=text-lcov | coveralls",
    "tsc": "tsc --project tsconfig.json",
    "tsc:w": "tsc --project tsconfig.json -w",
    "start": "nodemon --watch \"src/**/*.ts\" --ignore \"node_modules/**/*\" --exec ts-node src/index.ts",
    "start:prod": "cross-env NODE_ENV=production node dist/index.js",
    "docker:build": "yarn build && docker-compose build",
    "deploy": "exit 0"
  },
  "author": "",
  "license": "MIT",
  "dependencies": {
    "@tsed/common": "5.34.6",
    "@tsed/core": "5.34.6",
    "@tsed/di": "5.34.6",
    "@tsed/swagger": "5.34.6",
    "@tsed/testing": "5.34.6",
    "@types/swagger-schema-official": "2.0.20",
    "body-parser": "1.19.0",
    "cors": "2.8.5",
    "compression": "1.7.4",
    "concurrently": "5.0.0",
    "cookie-parser": "1.4.4",
    "express": "4.17.1",
    "method-override": "^3.0.0",
    "node-uuid": "1.4.8",
    "cross-env": "6.0.3"
  },
  "devDependencies": {
    "@types/chai": "4.2.5",
    "@types/chai-as-promised": "7.1.2",
    "@types/cors": "2.8.6",
    "@types/express": "4.17.2",
    "@types/http-proxy": "1.17.2",
    "@types/mocha": "5.2.7",
    "@types/node": "12.12.9",
    "@types/request-promise": "4.1.45",
    "@types/sinon": "7.5.0",
    "@types/sinon-chai": "3.2.3",
    "@types/supertest": "2.0.8",
    "chai": "4.2.0",
    "chai-as-promised": "7.1.1",
    "concurrently": "5.0.0",
    "mocha": "6.2.2",
    "nodemon": "1.19.4",
    "nyc": "14.1.1",
    "rimraf": "3.0.0",
    "sinon": "7.5.0",
    "sinon-chai": "3.3.0",
    "supertest": "4.0.2",
    "ts-node": "8.5.2",
    "tslint": "5.20.1",
    "typescript": "3.7.2"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

Then use the command npm install && npm start to start your server.

# Quick start

# Create your express server

Ts.ED provide a class to configure your Express application quickly. Just create a server.ts in your root project, declare a new Server class that extends ServerLoader.

import {GlobalAcceptMimesMiddleware, ServerLoader, ServerSettings} from "@tsed/common";
import bodyParser from "body-parser";
import compress from "compression";
import cookieParser from "cookie-parser";
import methodOverride from "method-override";

const rootDir = __dirname;

@ServerSettings({
  rootDir,
  acceptMimes: ["application/json"]
})
export class Server extends ServerLoader {
  /**
   * This method let you configure the express middleware required by your application to works.
   * @returns {Server}
   */
  public $beforeRoutesInit(): void | Promise<any> {
    this
      .use(GlobalAcceptMimesMiddleware)
      .use(cookieParser())
      .use(compress({}))
      .use(methodOverride())
      .use(bodyParser.json())
      .use(bodyParser.urlencoded({
        extended: true
      }));
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

By default ServerLoader load controllers in ${rootDir}/controllers and mount it to /rest endpoint.

To customize the server settings see Configuration page.

Finally create an index.ts file to bootstrap your server, on the same level of the Server.ts:

import {$log, ServerLoader} from "@tsed/common";
import {Server} from "./Server";

async function bootstrap() {
  try {
    $log.debug("Start server...");
    const server = await ServerLoader.bootstrap(Server);

    await server.listen();
    $log.debug("Server initialized");
  } catch (er) {
    $log.error(er);
  }
}

bootstrap();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

You should have this tree directories:

.
├── src
│   ├── controllers
│   ├── services
│   ├── middlewares
│   ├── index.ts
│   └── Server.ts
└── package.json
1
2
3
4
5
6
7
8

TIP

By default ServerLoader load automatically Services, Controllers and Middlewares in a specific directories. This behavior can be change by editing the componentScan configuration.

TIP

In addiction, it also possible to use node-config or dotenv to load your configuration from file:

import {$log, ServerLoader} from "@tsed/common";
import {Server} from "./Server";

process.env["NODE_CONFIG_DIR"] = __dirname + "/../config";
const config = require("config");

async function bootstrap() {
  try {
    $log.debug("Start server...");
    const server = await ServerLoader.bootstrap(Server, config /* or config.util.toObject() */);

    await server.listen();
    $log.debug("Server initialized");
  } catch (er) {
    $log.error(er);
  }
}

bootstrap();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

You should have this tree directories:

.
├── config
│   └── default.json (or .yaml)
├── src
│   ├── controllers
│   ├── services
│   ├── middlewares
│   ├── index.ts
│   └── Server.ts
└── package.json
1
2
3
4
5
6
7
8
9
10

With dotenv:

import {$log, ServerLoader} from "@tsed/common";
import {Server} from "./Server";

const config = require('dotenv').config({ path: '/full/custom/path/to/your/env/vars' });

async function bootstrap() {
  try {
    $log.debug("Start server...");
    const server = await ServerLoader.bootstrap(Server, config /* or config.util.toObject() */);

    await server.listen();
    $log.debug("Server initialized");
  } catch (er) {
    $log.error(er);
  }
}

bootstrap();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# Create your first controller

Create a new CalendarCtrl.ts in your controllers directory (by default root/controllers). All controllers declared with decorators is considered as an Express router. An Express router require a path (here, the path is /calendars) to expose an url on your server. More precisely, it's a part of path, and entire exposed url depend on the Server configuration (see Configuration) and the children controllers.

In this case, we haven't a dependencies and the root endpoint is set to /rest. So the controller's url will be http://host/rest/calendars.

import {Controller, Get} from "@tsed/common";

@Controller("/calendars")
export class CalendarCtrl {
  @Get()
  findAll(): string {
    return "This action returns all calendars";
  }
}
1
2
3
4
5
6
7
8
9

TIP

Decorators , , , , etc..., supports dynamic pathParams (eg: /:id) and RegExp like Express API.

See Controllers section for more details

WARNING

You have to configure engine rendering if you want to use the decorator .

To test your method, just run your server.ts and send a HTTP request on /rest/calendars/1.

# Ready for More?

We’ve briefly introduced the most basic features of Ts.ED - the rest of this guide will cover them and other advanced features with much finer details, so make sure to read through it all!