Marc Benito
API REST con Node.js y TypeScript

Creando una API REST con Node.js y TypeScript

10 de marzo de 2024

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