Introduction to Ts.ED

Kinson Leung
The Startup
Published in
5 min readJul 30, 2020
Photo by Sara Bakhshi on Unsplash

Dependency injection (DI), as a form of inversion of control (IOC), is one of the common software design patterns in object-oriented programming (OOP). DI brings a lot of advantages ranging from higher flexibility, higher reusability to lower dependencies. Undoubtedly, we can apply the DI pattern to our project with Typescript.

There are tons of DI frameworks or libraries out there, for example, InversifyJS, Typescript-ioc. Meanwhile, in HK01, we are using Ts.ED for our recent API gateway revamp project as it boosts our development process and provides comprehensive tools. In this article, we will briefly introduce Ts.ED by building a simple API web server.

Project setup

Let’s say we have to create an API server for our clients to get some secret messages. To commence with, we have to set up the project environment by installing dependencies. Ts.ED provides a CLI to start the project:

We can also install the dependencies one by one, but please note that all @tsed packages must be kept the same version.

After initializing the project, we can see there are two files named index.ts and server.ts. index.ts is used to bootstrap our web server. While in server.ts, @Configuration() decorator is used to defining our server’s configuration, and $beforeRoutesInit() is used to define express middleware. For example, if we would like to make our root endpoint as /api, we can write the following and our API URL will be like: localhost:3000/api

For more Ts.ED configuration, please check here.

Implement controller

After configuring our server, we can add our secret message endpoint. A secret message could be a word or a number, depending on which client we are serving. It is fairly simple to create an endpoint with Ts.ED, like the following:

@Controller() decorator tells Express that the SecretMessageControlleris one of the routers to handle the HTTP request. The parameter /secretMessage is the path of the API URL. Since we have two different types of secret messages, we can further define our path as /word and /number by adding them in decorator @Get()to the respective handler. The path parameter could also be added as above. We can use other HTTP methods such as POST, DELETE, etc, simply changing the decorator provided by Ts.ED to @Post()or @Delete()and their respective required parameters.

Start the server

Hence, we can run yarn start and the following log should appear to tell us the server is running with available endpoints:

When we call /secretMessage/number/22, we will have the following result:

Extracting logic to Service

Until now, everything works fine. However, what if we would like to change our secret number generation logic? We have to directly update the controller every time we change the implementation of a secret message. To make the system more loosely-coupled, we can utilize Ts.ED by implementing separate services and injecting our controller. To do this, we can firstly create a SecretWordService and SecretNumberService:

As you can see, we added @Service()decorator to the class to tell Ts.ED that it is a service provider. Then, we can inject the services to our previous controller:

Tada!🎉 We just separated our secret message generation logic (word & number) into two different services. In the future, we could just edit one class when we would like to change either one of the messages, or even inject another class (e.g. SecretNumberTwoService) in case we would like to change the secret number generation algorithm.

Implement middleware

As a matter of course a secret message has to be protected from unauthorized clients. Therefore, we have to add a middleware to guard our resources. It is simple to implement a middleware with Ts.ED. Add@Middleware() decorator to the class that is going to be the middleware. At this stage, let’s hardcode the token to be abcdef:

Middleware can be used in controller class or endpoint method by adding decorator @UseBefore(), @UseAfter()or @Use(). In our case, we need to check if the client is authorized before giving them our secret word. Therefore, we put our middleware in the SecretMessageController by adding @UseBefore and pass the middleware (AuthMiddleware) as a parameter.

Hence, if we call API without providing correct token, we will get unauthorized error:

Yet, we can get our secret word if we pass the correct token in the header:

Generate Swagger API document

In this stage, our secret message API is completed. However, the client does not know our URL path as well as the response’s data structure. Hence, it is important to provide API documentation. Ts.ED facilitates us to write Swagger documentation by providing a @tsed/swagger package. We can install it by:

yarn add @types/swagger-schema-official @tsed/swagger

Then, we configure it in server.ts :

For instance, we can add the description of the endpoint through decorators @Description() and @Returns().

Finally, swagger.json will be generated and can view through localhost:3000/docs/.

In this article, we have introduced Ts.ED and showcased how easily we can build an API server with decorators.

We have implemented:

  1. Controller router
  2. Service provider
  3. Authentication middleware
  4. Swagger documentation

An example code in this article can be found on https://github.com/kinsonlcy/tsed-express-server-example.

Thanks for your time and feel free to comment below if you have any questions!

--

--