
Creando una API REST con Node.js y TypeScript
En este artículo, aprenderemos a crear una API REST robusta utilizando Node.js y TypeScript. Implementaremos buenas prácticas, manejo de errores y una estructura de proyecto escalable.
Configuración inicial del proyecto
Primero, necesitamos configurar nuestro proyecto con TypeScript. Aquí está la configuración básica:
npm init -y
npm install express typescript @types/express @types/node
npm install -D ts-node nodemon
npx tsc --init
Configuración de TypeScript (tsconfig.json):
{
"compilerOptions": {
"target": "es2017",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}
Estructura del proyecto
Una buena estructura de proyecto es clave para la mantenibilidad. Aquí está una estructura recomendada:
src/
├── controllers/
├── models/
├── routes/
├── middleware/
├── services/
├── types/
└── app.ts
Implementando un endpoint básico
Veamos cómo implementar un endpoint básico con TypeScript y Express:
// src/types/user.ts
interface User {
id: number;
name: string;
email: string;
}
// src/controllers/userController.ts
import { Request, Response } from 'express';
import { UserService } from '../services/userService';
export class UserController {
constructor(private userService: UserService) {}
async getUsers(req: Request, res: Response) {
try {
const users = await this.userService.getAll();
res.json(users);
} catch (error) {
res.status(500).json({ error: 'Internal server error' });
}
}
async createUser(req: Request, res: Response) {
try {
const user = await this.userService.create(req.body);
res.status(201).json(user);
} catch (error) {
res.status(400).json({ error: 'Invalid user data' });
}
}
}
Middleware para manejo de errores
Es importante tener un manejo de errores consistente en toda la API:
// src/middleware/errorHandler.ts
import { Request, Response, NextFunction } from 'express';
export class ApiError extends Error {
constructor(
public statusCode: number,
message: string
) {
super(message);
this.name = 'ApiError';
}
}
export const errorHandler = (
error: Error,
req: Request,
res: Response,
next: NextFunction
) => {
if (error instanceof ApiError) {
res.status(error.statusCode).json({
error: error.message
});
return;
}
res.status(500).json({
error: 'Internal server error'
});
};
Validación de datos con Zod
Para la validación de datos, podemos usar Zod, que se integra perfectamente con TypeScript:
import { z } from 'zod';
const UserSchema = z.object({
name: z.string().min(2),
email: z.string().email(),
age: z.number().min(18)
});
// Middleware de validación
const validateUser = (req: Request, res: Response, next: NextFunction) => {
try {
UserSchema.parse(req.body);
next();
} catch (error) {
res.status(400).json({ error: 'Invalid user data' });
}
};
Conclusiones
Crear una API REST con TypeScript nos permite:
- Tener un código más seguro y mantenible
- Detectar errores en tiempo de compilación
- Mejorar la experiencia de desarrollo con autocompletado
- Facilitar el trabajo en equipo con tipos bien definidos
Recuerda siempre seguir los principios SOLID y mantener una buena estructura de proyecto para que tu API sea escalable y fácil de mantener.
Tecnología Híbrida
Desarrollo con Cordova permitiendo una única base de código para múltiples plataformas
Experiencia Nativa
Interfaz de usuario optimizada para proporcionar una experiencia similar a las apps nativas
Multiplataforma
Disponible tanto para dispositivos Android como iOS desde una única base de código