Introducción a servicios

Intermedio
Angular
Angular
Actualizado: 24/09/2025

Introducción a servicios

Los servicios en Angular son clases especializadas que encapsulan lógica de negocio y datos que pueden ser reutilizados en múltiples componentes de nuestra aplicación. Representan uno de los pilares fundamentales de la arquitectura de Angular, permitiendo separar las responsabilidades y mantener nuestros componentes enfocados únicamente en la presentación y la interacción con el usuario.

¿Qué es un servicio?

Un servicio es una clase TypeScript decorada con @Injectable() que contiene funcionalidad específica para una tarea determinada. Mientras que los componentes se encargan de la presentación y la lógica de la interfaz de usuario, los servicios manejan todo lo relacionado con:

  • Lógica de negocio: Operaciones, cálculos y reglas específicas del dominio
  • Gestión de datos: Almacenamiento y manipulación de información
  • Comunicación: Entre componentes que no tienen relación padre-hijo directa
  • Funcionalidades transversales: Logging, autenticación, configuración
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class CalculadoraService {
  
  calcularTotal(precio: number, impuestos: number): number {
    return precio + (precio * impuestos / 100);
  }
  
  aplicarDescuento(precio: number, descuento: number): number {
    return precio - (precio * descuento / 100);
  }
}

¿Por qué usar servicios?

La separación de responsabilidades es el principio fundamental que justifica el uso de servicios. Sin ellos, nuestros componentes se volverían grandes y difíciles de mantener al tener que manejar tanto la presentación como la lógica de negocio.

Ventajas de usar servicios:

  • Reutilización: Una vez creado, un servicio puede ser usado por cualquier componente
  • Mantenibilidad: La lógica está centralizada en un solo lugar
  • Testabilidad: Es más fácil crear pruebas unitarias para lógica aislada
  • Escalabilidad: Permite que la aplicación crezca de forma organizada

El decorador @Injectable()

Todo servicio debe estar marcado con el decorador @Injectable(), que le dice a Angular que esta clase puede ser inyectada como dependencia en otros lugares de la aplicación.

@Injectable({
  providedIn: 'root'
})
export class MensajesService {
  private mensajes: string[] = [];
  
  agregarMensaje(mensaje: string): void {
    this.mensajes.push(mensaje);
  }
  
  obtenerMensajes(): string[] {
    return this.mensajes;
  }
  
  limpiarMensajes(): void {
    this.mensajes = [];
  }
}

La propiedad **providedIn: 'root'** indica que el servicio estará disponible en toda la aplicación como un singleton, es decir, se creará una sola instancia que será compartida por todos los componentes que la utilicen.

Patrón Singleton

Por defecto, los servicios con providedIn: 'root' siguen el patrón singleton, lo que significa que Angular creará una única instancia del servicio para toda la aplicación. Esto es especialmente útil para:

  • Compartir estado entre componentes no relacionados
  • Mantener datos que deben persistir durante la navegación
  • Optimizar recursos evitando crear múltiples instancias innecesarias
@Injectable({
  providedIn: 'root'
})
export class ContadorService {
  private contador = 0;
  
  incrementar(): void {
    this.contador++;
  }
  
  decrementar(): void {
    this.contador--;
  }
  
  obtenerValor(): number {
    return this.contador;
  }
  
  reiniciar(): void {
    this.contador = 0;
  }
}

En este ejemplo, todos los componentes que utilicen ContadorService compartirán el mismo valor del contador, permitiendo que cambios realizados en un componente se reflejen automáticamente en otros.

Casos de uso comunes

Los servicios son ideales para encapsular funcionalidades que se repiten en diferentes partes de la aplicación:

  • Gestión de estado local: Almacenar datos temporales que múltiples componentes necesitan acceder
  • Utilidades y helpers: Funciones de formateo, validación o cálculos
  • Comunicación entre componentes: Cuando no existe relación directa padre-hijo
  • Configuración de la aplicación: Constantes, ajustes y parámetros globales

Los servicios representan una herramienta fundamental para crear aplicaciones Angular bien estructuradas y mantenibles, separando claramente las responsabilidades entre la presentación y la lógica de negocio.

Creación de servicios

Creación mediante Angular CLI

La forma más eficiente y recomendada de crear un servicio en Angular es utilizando el comando ng generate de Angular CLI. Este comando genera automáticamente la estructura básica del servicio con todas las configuraciones necesarias.

Comando básico:

ng generate service nombre-del-servicio

Forma abreviada:

ng g s nombre-del-servicio

Por ejemplo, para crear un servicio que maneje datos de usuarios:

ng generate service services/usuario

Este comando creará dos archivos en la carpeta src/app/services/:

  • usuario.service.ts - El archivo del servicio
  • usuario.service.spec.ts - Archivo de pruebas unitarias

Ejemplo:

Genera los archivos:

Siendo el ProductService:

Estructura generada automáticamente

Cuando utilizas Angular CLI, el servicio generado tendrá la siguiente estructura base:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class UsuarioService {

  constructor() { }

}

Angular CLI ya incluye automáticamente:

  • Import necesario: Injectable desde @angular/core
  • Decorador configurado: @Injectable() con providedIn: 'root'
  • Constructor vacío: Listo para recibir dependencias si las necesitas
  • Clase exportada: Con el nombre en formato PascalCase

Opciones adicionales del CLI

El comando ng generate service acepta varias opciones útiles para personalizar la creación:

Especificar carpeta de destino:

ng g s shared/services/notificaciones

Omitir archivos de prueba:

ng g s usuario --skip-tests

Crear en carpeta específica con estructura:

ng g s core/auth/autenticacion

Ejemplo práctico: Servicio de tareas

Vamos a crear un servicio completo para gestionar una lista de tareas:

ng generate service services/tareas

Una vez creado, podemos implementar la funcionalidad:

import { Injectable } from '@angular/core';

interface Tarea {
  id: number;
  titulo: string;
  completada: boolean;
  fechaCreacion: Date;
}

@Injectable({
  providedIn: 'root'
})
export class TareasService {
  private tareas: Tarea[] = [
    {
      id: 1,
      titulo: 'Aprender Angular',
      completada: false,
      fechaCreacion: new Date()
    },
    {
      id: 2,
      titulo: 'Crear mi primera app',
      completada: true,
      fechaCreacion: new Date()
    }
  ];

  private siguienteId = 3;

  constructor() { }

  obtenerTareas(): Tarea[] {
    return [...this.tareas]; // Devolvemos una copia para evitar mutaciones
  }

  agregarTarea(titulo: string): void {
    const nuevaTarea: Tarea = {
      id: this.siguienteId++,
      titulo,
      completada: false,
      fechaCreacion: new Date()
    };
    this.tareas.push(nuevaTarea);
  }

  marcarComoCompletada(id: number): void {
    const tarea = this.tareas.find(t => t.id === id);
    if (tarea) {
      tarea.completada = true;
    }
  }

  eliminarTarea(id: number): void {
    this.tareas = this.tareas.filter(t => t.id !== id);
  }

  contarPendientes(): number {
    return this.tareas.filter(t => !t.completada).length;
  }
}

Creación manual de servicios

Aunque Angular CLI es la opción recomendada, también puedes crear servicios manualmente. Solo necesitas seguir estos pasos:

1. Crear el archivo TypeScript:

// src/app/services/configuracion.service.ts
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class ConfiguracionService {
  private configuracion = {
    tema: 'claro',
    idioma: 'es',
    notificaciones: true
  };

  constructor() { }

  obtenerTema(): string {
    return this.configuracion.tema;
  }

  cambiarTema(nuevoTema: string): void {
    this.configuracion.tema = nuevoTema;
  }

  obtenerConfiguracion() {
    return { ...this.configuracion };
  }
}

2. Asegurarte de que esté disponible:

Con providedIn: 'root', el servicio estará automáticamente disponible en toda la aplicación sin necesidad de configuración adicional.

Organización de servicios

Una buena práctica es organizar los servicios en carpetas según su funcionalidad:

src/app/
├── services/
│   ├── core/
│   │   ├── auth.service.ts
│   │   └── config.service.ts
│   ├── shared/
│   │   ├── notificaciones.service.ts
│   │   └── utilidades.service.ts
│   └── feature/
│       ├── productos.service.ts
│       └── pedidos.service.ts

Comandos para esta estructura:

ng g s services/core/auth
ng g s services/shared/notificaciones  
ng g s services/feature/productos

Convenciones de nomenclatura

Al crear servicios, sigue estas convenciones establecidas:

  • Nombres descriptivos: UsuarioService, ProductoService, NotificacionService
  • Sufijo Service: Siempre termina en "Service"
  • PascalCase: Para el nombre de la clase
  • kebab-case: Para el nombre del archivo (usuario.service.ts)

Los servicios creados con Angular CLI ya siguen automáticamente estas convenciones, garantizando consistencia en tu proyecto y facilitando el mantenimiento del código.

En Angular 20 se introduce cambio de nomenclatura, ya no genera archivos con el sufijo .service. lo que significa que Angular recomienda nombres específicos del dominio o basados en el rol.

Nombres de archivo (kebab-case):

// Convenciones Angular 20
product-store.ts     // Para manejo de estado
user-api.ts          // Para llamadas HTTP
auth-client.ts       // Para autenticación
notification-hub.ts  // Para notificaciones
cache-manager.ts     // Para gestión de cache

Nombres de clase (PascalCase):

// ✅ Recomendado en Angular 20
export class ProductStore { }
export class UserApi { }
export class AuthClient { }
export class NotificationHub { }
export class CacheManager { }

// ❌ Evitar nombres genéricos
export class ProductService { } // Muy genérico
export class Product { }        // Se confunde con modelo

Ejemplo de estructura para un proyecto de Angular moderno con estas nuevas recomendaciones:

src/app/
├── core/
│   ├── auth-client.ts
│   └── error-handler.ts
├── domains/
│   ├── products/
│   │   ├── product-store.ts
│   │   ├── product-api.ts
│   │   └── product.ts
│   └── users/
│       ├── user-store.ts
│       └── user-api.ts
└── shared/
    ├── cache-manager.ts
    └── notification-hub.ts
Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Angular es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Angular

Explora más contenido relacionado con Angular y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

  • Comprender qué es un servicio en Angular y su función principal.
  • Aprender a crear servicios usando Angular CLI y manualmente.
  • Entender el uso del decorador @Injectable() y el patrón singleton.
  • Identificar casos de uso comunes para servicios en aplicaciones Angular.
  • Conocer buenas prácticas para la organización y nomenclatura de servicios.