Building Scalable Server-Side Applications with Ts.ED

Benefits of Using Ts.ED

Before diving into the tutorial, let’s consider some of the reasons why Ts.ED is a great choice for web developers:

  • Faster Development: Ts.ED enables you to create REST APIs quickly with OpenSpec and JSON Schema compliance.
  • Rich CLI Tool: The Ts.ED CLI tool allows you to create a pre-configured server, saving you time and effort.
  • Extensive Plugin Ecosystem: Ts.ED has a wide range of plugins that you can choose from to create your stack.
  • Class-Based Framework: Ts.ED is a class-based framework, making it easy to create controllers, pipes, and middlewares as classes.
  • Embedded Testing Features: Ts.ED has built-in testing features that make it easier to test your applications.

Setting Up a New Project

To get started with Ts.ED, you’ll need to install the Ts.ED CLI tool using the following command:

npm install -g @tsed/cli

Once installed, create a new project using the following command:

tsed init.

This will prompt you to select your desired configurations. For this tutorial, choose the following options:

  • Target Platform: Express
  • Architecture: Ts.ED
  • Convention File Styling: Ts.ED
  • Features: Database
  • ORM: TypeORM
  • TypeORM Database: MySQL
  • Package Manager: Yarn

Project Structure

After setting up your project, Ts.ED will create the following folder structure:

  • src/: The source code folder
  • src/config/: The configuration folder
  • src/datasource/: The data source configuration folder
  • src/controllers/: The controllers folder

Updating the Data Source

To connect to your MySQL database, update the src/datasources/MysqlDatasource.ts file with the following code:


import { DataSource } from "typeorm";

const datasource = new DataSource({
  type: "mysql",
  host: "localhost",
  port: 3306,
  username: "root",
  password: "password",
  database: "blog",
  entities: [__dirname + "/../*/.entity{.ts,.js}"],
  synchronize: true,
});

export default datasource;

Creating an Entity Model

Create a new entity model for your blog database using the following command:

tsed generate model

Name the model Blog and add the following code to the src/models/Blog.entity.ts file:


import { Entity, Column, PrimaryGeneratedColumn } from "typeorm";

@Entity()
export class Blog {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  title: string;

  @Column()
  content: string;
}

Configuring Multer

To allow users to upload cover images for each blog post, configure Multer in the src/Server.ts file with the following code:


import { MulterOptions } from "@tsed/multer";
import { diskStorage } from "multer";

const multerOptions: MulterOptions = {
  storage: diskStorage({
    destination: "./uploads/",
    filename: (req, file, cb) => {
      const randomString = Math.random().toString(36).substr(2, 15);
      const fileName = `${randomString}-${Date.now()}-${file.originalname}`;
      cb(null, fileName);
    },
  }),
};

Creating a Service

Create a new service for your blog database using the following command:

tsed generate service

Name the service BlogService and add the following code to the src/services/BlogService.ts file:


import { Injectable } from "@tsed/di";
import { Inject } from "@tsed/di";
import { DataSource } from "typeorm";

@Injectable()
export class BlogService {
  private readonly dataSource: DataSource;

  constructor(@Inject(DataSource) dataSource: DataSource) {
    this.dataSource = dataSource;
  }

  async createBlog(blog: Blog): Promise<void> {
    return await this.dataSource.getRepository(Blog).save(blog);
  }

  async getAllBlogs(): Promise<Blog[]> {
    return await this.dataSource.getRepository(Blog).find();
  }
}

Creating a Controller

Create a new controller for your blog database using the following command:

tsed generate controller

Name the controller BlogController and add the following code to the src/controllers/BlogController.ts file:


import { Controller, Get, Post, Put, Delete } from "@tsed/di";
import { BlogService } from "../services/BlogService";
import { Blog } from "../models/Blog.entity";

@Controller("/blog")
export class BlogController {
  private readonly blogService: BlogService;

  constructor(private blogService: BlogService) {}

  @Get("/")
  async getAllBlogs(): Promise<Blog[]> {
    return await this.blogService.getAllBlogs();
  }

  @Post("/")
  async createBlog(@BodyParams() blog: Blog): Promise<void> {
    return await this.blogService.createBlog(blog);
  }
}

Serving Static Files

To serve static files, such as cover images, configure the src/Server.ts file with the following code:


import { StaticsOptions } from "@tsed/platform-express";

const staticsOptions: StaticsOptions = {
  root: "public",
  prefix: "/static/",
};

Testing the Application

Test your application using Postman by sending a POST request to http://localhost:8083/blog/ with the following JSON body:


{
  "title": "My First Blog Post",
  "content": "This is my first blog post.",
  "coverImage": "/path/to/cover/image.jpg"
}

This should create a new blog post with the specified title, content, and cover image.

Leave a Reply