Introduction: Why TypeScript for REST API?
Modern web development is unthinkable without clear and scalable APIs. TypeScript, being a strictly typed superset of JavaScript, allows you to create reliable REST APIs with a minimum number of runtime errors. In this article, we will practically, step by step, create a full-fledged REST API in TypeScript using the popular Express framework. The entire process will take you no more than 30 minutes, and the result will be ready for use in real projects.
We will cover: project initialization, TypeScript configuration, creating routes, working with middleware, error handling, and endpoint testing. All code examples can be immediately run and adapted to your tasks.
Step 1: Project Initialization and Dependency Installation
First, create a new directory for the project and initialize it. Open your terminal and run:
mkdir my-ts-apicd my-ts-apinpm init -yNow install the necessary packages:
npm install expressnpm install -D typescript @types/node @types/express ts-node nodemonCreate the TypeScript configuration file:
npx tsc --initEdit tsconfig.json to include the following options:
{ "compilerOptions": { "target": "ES2020", "module": "commonjs", "outDir": "./dist", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true }}Add scripts to package.json:
"scripts": { "build": "tsc", "start": "node dist/index.js", "dev": "nodemon --exec ts-node src/index.ts"}Step 2: Creating the Basic Structure and First Endpoint
Create a src folder and inside it a file index.ts. Let's start with a simple server that responds to GET requests:
import express, { Request, Response } from 'express';
const app = express();const PORT = process.env.PORT || 3000;
// Middleware for parsing JSONapp.use(express.json());
// Basic routeapp.get('/', (req: Request, res: Response) => { res.send('REST API in TypeScript is working!');});
app.listen(PORT, () => { console.log(`Server running at http://localhost:${PORT}`);});Start the server with the command npm run dev and open http://localhost:3000. You will see a welcome message.
Creating a Data Model
For a full-fledged API, we need an entity. Let's create a simple user model:
// src/models/user.tsexport interface User { id: number; name: string; email: string; age: number;}
export type CreateUserDto = Omit; Step 3: Implementing CRUD Operations
Now let's create a controller and routes for working with users. Create a file src/routes/users.ts:
import { Router, Request, Response } from 'express';import { User, CreateUserDto } from '../models/user';
const router = Router();let users: User[] = [ { id: 1, name: 'Ivan', email: 'ivan@example.com', age: 28 }, { id: 2, name: 'Maria', email: 'maria@example.com', age: 32 }];let nextId = 3;
// GET /users - get all usersrouter.get('/', (req: Request, res: Response) => { res.json(users);});
// GET /users/:id - get user by IDrouter.get('/:id', (req: Request, res: Response) => { const id = parseInt(req.params.id); const user = users.find(u => u.id === id); if (!user) { return res.status(404).json({ message: 'User not found' }); } res.json(user);});
// POST /users - create a new userrouter.post('/', (req: Request, res: Response) => { const { name, email, age }: CreateUserDto = req.body; if (!name || !email || !age) { return res.status(400).js