Los servicios o services de una aplicación web son aquellos que proveen funcionalidades de una entidad en específico; tuvieron una popularidad con AngularJS y Angular, pero en Vue tal cosa no existe.
En este post te mostraré un ejemplo de un servicio de Vue, que si bien no es obligatorio, es totalmente válido.
Los servicios son un paradigma
Un servicio no es otra cosa más que un módulo aislado que contiene la lógica de determinada entidad. Podríamos tener un servicio de fórmulas, que calcule las cuentas por pagar, por cobrar, etcétera.
También podríamos tener un servicio (y esto es lo más común) para consumir una API REST.
Al final de cuentas, un servicio contiene lógica de determinada cosa. Y es un paradigma que puede ser portado a distintos frameworks o lenguajes.
Ejemplo de servicio en Vue
Es momento de ver el código. Aquí tengo un servicio de Vue, simple, sencillo y limpio; está dentro de la carpeta services, y se llama ClientesService.
Como puedes imaginar, lleva la lógica de la entidad Cliente. Lo único que hace es consumir la API que tengo.
import { HttpClient } from './HttpClient';
export const ClientesService = {
async obtenerClientes() {
return HttpClient.get('/clientes')
.then(clientes => clientes);
},
async agregarCliente(cliente) {
return HttpClient.post('/cliente', cliente)
.then(registrado => registrado);
},
async actualizarCliente(cliente) {
return HttpClient.put('/cliente', cliente)
.then(registrado => registrado);
},
async eliminarCliente(id) {
return HttpClient.delete(`/cliente/${id.toString()}`)
.then(eliminado => eliminado);
},
};
export default { ClientesService };
No te confundas; las funciones usan async
porque son asíncronas. En el apartado de HttpClient tengo un cliente propio que es una envoltura de fetch; el cual, si te interesa, lo dejo aquí:
const RUTA_SERVIDOR = "ruta";
const manejarRespuesta = (respuesta) => {
// Manejar respuesta como se necesite. Yo lo hago así:
if (respuesta.error) {
throw new Error(JSON.stringify(respuesta.error));
}
return respuesta.data;
};
export const HttpClient = {
post: (ruta, datos) => fetch(RUTA_SERVIDOR + ruta, {
credentials: 'include',
method: 'POST',
body: JSON.stringify(datos),
})
.then(r => r.json())
.then(manejarRespuesta),
put: (ruta, datos) => fetch(RUTA_SERVIDOR + ruta, {
credentials: 'include',
method: 'PUT',
body: JSON.stringify(datos),
})
.then(r => r.json())
.then(manejarRespuesta),
get: ruta => fetch(RUTA_SERVIDOR + ruta, {
credentials: 'include',
})
.then(r => r.json())
.then(manejarRespuesta),
delete: ruta => fetch(RUTA_SERVIDOR + ruta, {
credentials: 'include',
method: 'DELETE',
})
.then(r => r.json())
.then(manejarRespuesta),
};
export default { HttpClient };
Usar Servicio en Vue
Ahora que tenemos definido el servicio lo podemos importar en un componente de Vue. Si te fijas, el servicio anterior no depende de ningún framework; es inyectable en JavaScript puro y en otros frameworks.
Como sea; para usarlo, lo importamos:
import { ClientesService } from '../../services/ClientesService';
Después lo podemos usar así:
// Lo siguiente es un método que está dentro de methods en Vue
obtenerClientes() {
return ClientesService.obtenerClientes()
.then((clientes) => {
this.clientes = clientes;
});
},
// ...
Con eso estamos usando services en Vue, de una manera sencilla. Podemos crear cualquier número de servicios y, como lo dije, cada servicio puede hacer mucho más que traer datos de una API.
¿Por qué usar servicios?
Fácilmente podemos prescindir de los servicios, pero son una buena práctica de programación. Además, esto promueve la reutilización de código: si más tarde queremos obtener los clientes en otro componente, invocamos al servicio.
Adicionalmente, debido a que tenemos una única fuente de la verdad, podemos arreglarla en caso de error o en caso de que (específicamente con las apis) la ruta cambie.