Skip to content

GitLab

  • Menu
Projects Groups Snippets
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • E ECMAscript-Typescript
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 11
    • Issues 11
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Monitor
    • Monitor
    • Metrics
    • Incidents
  • Packages & Registries
    • Packages & Registries
    • Package Registry
    • Infrastructure Registry
  • Analytics
    • Analytics
    • CI/CD
    • Repository
    • Value stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • imunnic
  • ECMAscript-Typescript
  • Wiki
  • Modulo 4

Modulo 4 · Changes

Page history
adaptacion sin revision a typescript authored Dec 15, 2025 by imunnic's avatar imunnic
Show whitespace changes
Inline Side-by-side
Showing with 102 additions and 113 deletions
+102 -113
  • Modulo-4.md Modulo-4.md +102 -113
  • No files found.
Modulo-4.md
View page @ bd3be2ea
# Módulo 4 — Uso de Servicios y API REST # Módulo 4 — Uso de Servicios y API REST en TypeScript
**Aplicación práctica: Conexión del sistema de gestión sanitaria con una API REST propia (consulta y actualización de recursos y personal).** **Aplicación práctica: Conexión del sistema de gestión sanitaria con una API REST propia (consulta y actualización de recursos y personal).**
...@@ -6,84 +6,86 @@ ...@@ -6,84 +6,86 @@
## 1. Introducción a la asincronía ## 1. Introducción a la asincronía
JavaScript es un lenguaje **asíncrono y no bloqueante**, lo que significa que **puede ejecutar tareas sin detener el flujo principal** (por ejemplo, esperar la respuesta de un servidor mientras sigue procesando otras acciones). TypeScript hereda el modelo **asíncrono y no bloqueante** de JavaScript, pero añade **tipado estático** que permite detectar errores en el manejo de promesas y datos remotos antes de ejecutar la aplicación.
Esto es posible gracias al **Event Loop** y a las **promesas (Promises)**, que permiten manejar operaciones que tardan tiempo, como peticiones a una API o lectura de archivos. ```ts
console.log('Iniciando petición...');
```javascript setTimeout((): void => {
console.log("Iniciando petición..."); console.log('Datos recibidos del servidor');
setTimeout(() => {
console.log("Datos recibidos del servidor");
}, 2000); }, 2000);
console.log("Petición enviada");
console.log('Petición enviada');
``` ```
> El flujo **no se detiene** esperando la respuesta del servidor. > El flujo principal no se bloquea; la operación asíncrona se gestiona mediante el **Event Loop**.
> Se ejecuta el `setTimeout` de forma asíncrona.
--- ---
## 2. Qué es una API REST ## 2. Qué es una API REST
Una **API REST** (Representational State Transfer) permite **comunicarse entre aplicaciones a través de HTTP**. Una **API REST (Representational State Transfer)** permite la comunicación entre aplicaciones a través de **HTTP**. En una aplicación sanitaria, una API REST expone recursos como **personal, material, activaciones o inventario**.
Tu app de gestión sanitaria puede usar una API REST para **consultar pacientes, recursos o personal** almacenados en un servidor remoto.
Las API REST suelen **intercambiar datos en formato JSON**. Las API REST intercambian datos en **formato JSON**, fácilmente mapeables a **interfaces TypeScript**.
--- ---
## 3. Métodos HTTP más comunes ## 3. Métodos HTTP más comunes
| Método | Acción | Ejemplo en la app | | Método | Acción | Ejemplo en la aplicación |
| ---------- | ------------------------------- | --------------------------------------- | | ------ | ------------------- | ------------------------ |
| **GET** | Obtener información | Consultar la lista de recursos | | GET | Obtener información | Consultar recursos |
| **POST** | Crear nuevo elemento | Añadir un nuevo paciente | | POST | Crear un recurso | Añadir personal |
| **PUT** | Actualizar un registro completo | Editar los datos de un recurso | | PUT | Actualizar completo | Editar recurso |
| **PATCH** | Actualizar parcialmente | Cambiar solo la cantidad de mascarillas | | PATCH | Actualizar parcial | Cambiar estado |
| **DELETE** | Eliminar un registro | Eliminar un paciente dado de alta | | DELETE | Eliminar | Dar de baja |
--- ---
## 4. Qué es JSON ## 4. Qué es JSON
**JSON (JavaScript Object Notation)** es el formato estándar de intercambio de datos entre cliente y servidor. JSON es el formato estándar de intercambio de datos. En TypeScript, el JSON recibido se transforma en **objetos tipados**.
Se basa en **pares clave–valor**, muy similar a los objetos literales de JavaScript. ```ts
interface RecursoDTO {
id: string;
unidad: string;
tipoRecurso: 'HUMANO' | 'MATERIAL';
}
```javascript const recurso: RecursoDTO = {
// Objeto literal id: '1hd72h3kw8fhs7dh34',
const recurso = { unidad: 'JMAPER',
id: "1hd72h3kw8fhs7dh34", tipoRecurso: 'HUMANO',
unidad: "JMAPER",
tipoRecurso: "HUMANO"
}; };
// Conversión a JSON const json: string = JSON.stringify(recurso);
const json = JSON.stringify(recurso); const obj: RecursoDTO = JSON.parse(json);
console.log(json); // '{"id":"1hd72h3kw8fhs7dh34","unidad":"JMAPER","tipoRecurso":"HUMANO"}'
// Convertir JSON a objeto
const obj = JSON.parse(json);
console.log(obj.id); //"1hd72h3kw8fhs7dh34"
``` ```
--- ---
## 5. Peticiones HTTP con `fetch()` ## 5. Peticiones HTTP con `fetch`
`fetch` devuelve una `Promise<Response>`. En TypeScript se tipa explícitamente la respuesta esperada.
La función **`fetch()`** permite realizar peticiones HTTP de forma asíncrona. ```ts
Devuelve una **Promise**, lo que significa que podemos usar `.then()` o `async/await`. async function obtenerRecursos(): Promise<RecursoDTO[]> {
const respuesta = await fetch('https://api.panacea.com/recursos');
### Ejemplo: obtener recursos del servidor if (!respuesta.ok) {
throw new Error(`Error HTTP: ${respuesta.status}`);
}
return respuesta.json();
}
```javascript obtenerRecursos()
fetch("https://api.panacea.com/recursos") .then((recursos: RecursoDTO[]) => {
.then(res => res.json()) console.log('Recursos disponibles:', recursos);
.then(data => {
console.log("Recursos disponibles:", data);
}) })
.catch(error => { .catch((error: Error) => {
console.error("Error al obtener los datos:", error); console.error('Error al obtener los datos:', error.message);
}); });
``` ```
...@@ -91,79 +93,74 @@ fetch("https://api.panacea.com/recursos") ...@@ -91,79 +93,74 @@ fetch("https://api.panacea.com/recursos")
## 6. Uso de `async` y `await` ## 6. Uso de `async` y `await`
La sintaxis `async/await` simplifica el manejo de promesas, haciéndolo más legible y cercano al código secuencial. `async/await` permite escribir código asíncrono con estructura secuencial, manteniendo el tipado.
```javascript ```ts
async function cargarRecursos() { async function cargarRecursos(): Promise<void> {
try { try {
const respuesta = await fetch("https://api.panacea.com/recursos"); const respuesta = await fetch('https://api.panacea.com/recursos');
const datos = await respuesta.json(); const datos: RecursoDTO[] = await respuesta.json();
console.table(datos); console.table(datos);
} catch (error) { } catch (error) {
console.error("Error al cargar recursos:", error); console.error('Error al cargar recursos', error);
} }
} }
cargarRecursos(); cargarRecursos();
``` ```
> `await` detiene la ejecución dentro de la función **asíncrona** hasta que se resuelve la promesa.
--- ---
## 7. Envío de datos (POST) ## 7. Envío de datos (POST)
```javascript ```ts
async function agregarRecurso() { async function agregarRecurso(nuevo: RecursoDTO): Promise<RecursoDTO> {
const nuevo = { const respuesta = await fetch('https://api.panacea.com/recursos', {
id: "17d263hf84j6sh3h9sjd", method: 'POST',
unidad: "JMAPER", headers: { 'Content-Type': 'application/json' },
tipoRecurso: "HUMANO" body: JSON.stringify(nuevo),
};
const respuesta = await fetch("https://api.panacea.com/recursos", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(nuevo)
}); });
const resultado = await respuesta.json(); if (!respuesta.ok) {
console.log("Recurso agregado:", resultado); throw new Error('Error al crear el recurso');
}
return respuesta.json();
} }
agregarRecurso(); agregarRecurso({
id: '17d263hf84j6sh3h9sjd',
unidad: 'JMAPER',
tipoRecurso: 'HUMANO',
}).then((resultado: RecursoDTO) => {
console.log('Recurso agregado:', resultado);
});
``` ```
--- ---
## 8. Actualización y eliminación ## 8. Actualización y eliminación
### PATCH (actualizar registro completo) ### PATCH (actualización parcial)
```javascript
async function actualizarRecurso(id) {
const recursoActualizado = {
id: "17d263hf84j6sh3h9sjd",
unidad: "JMAPER",
tipoRecurso: "MATERIAL"
};
```ts
async function actualizarRecurso(id: string, datos: Partial<RecursoDTO>): Promise<void> {
await fetch(`https://api.panacea.com/recursos/${id}`, { await fetch(`https://api.panacea.com/recursos/${id}`, {
method: "PATCH", method: 'PATCH',
headers: { "Content-Type": "application/json" }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(recursoActualizado) body: JSON.stringify(datos),
}); });
} }
``` ```
### DELETE (eliminar registro) ### DELETE (eliminación)
```javascript ```ts
async function eliminarRecurso(id) { async function eliminarRecurso(id: string): Promise<void> {
await fetch(`https://api.panacea.com/recursos/${id}`, { await fetch(`https://api.panacea.com/recursos/${id}`, {
method: "DELETE" method: 'DELETE',
}); });
console.log("Recurso eliminado correctamente"); console.log('Recurso eliminado correctamente');
} }
``` ```
...@@ -171,16 +168,13 @@ async function eliminarRecurso(id) { ...@@ -171,16 +168,13 @@ async function eliminarRecurso(id) {
## 9. CORS (Cross-Origin Resource Sharing) ## 9. CORS (Cross-Origin Resource Sharing)
**CORS** es un mecanismo de seguridad que controla qué dominios pueden acceder a los recursos de una API. CORS es un mecanismo de seguridad del navegador. El servidor debe permitir explícitamente el origen del frontend.
Si tu frontend (`http://localhost:3000`) intenta acceder a una API en otro dominio (`https://api.panacea.com`), el servidor debe **permitir explícitamente** esa conexión.
Ejemplo de encabezado que el servidor debe devolver:
``` ```
Access-Control-Allow-Origin: http://localhost:3000 Access-Control-Allow-Origin: http://localhost:4200
``` ```
> Si CORS no está configurado, el navegador **bloqueará la petición por seguridad**. > En Angular, este aspecto se gestiona principalmente en el **backend** o mediante **proxies de desarrollo**.
--- ---
...@@ -192,36 +186,31 @@ Access-Control-Allow-Origin: http://localhost:3000 ...@@ -192,36 +186,31 @@ Access-Control-Allow-Origin: http://localhost:3000
<button id="btnCargar">Cargar recursos</button> <button id="btnCargar">Cargar recursos</button>
``` ```
```javascript ```ts
const btn = document.getElementById("btnCargar"); const btn = document.getElementById('btnCargar') as HTMLButtonElement;
const lista = document.getElementById("lista"); const lista = document.getElementById('lista') as HTMLUListElement;
btn.addEventListener("click", async () => { btn.addEventListener('click', async (): Promise<void> => {
try { try {
const res = await fetch("https://api.panacea.com/recursos"); const recursos = await obtenerRecursos();
const recursos = await res.json(); lista.innerHTML = '';
lista.innerHTML = ""; // limpiar lista previa
recursos.forEach(r => { recursos.forEach((r: RecursoDTO) => {
const li = document.createElement("li"); const li = document.createElement('li');
li.textContent = `${r.tipo}: ${r.cantidad}`; li.textContent = `${r.tipoRecurso}: ${r.unidad}`;
lista.appendChild(li); lista.appendChild(li);
}); });
} catch (error) { } catch {
alert("Error al cargar recursos"); alert('Error al cargar recursos');
} }
}); });
``` ```
> Este ejemplo conecta la **interfaz del DOM** con la **API REST**, mostrando datos dinámicamente desde el servidor.
--- ---
## 11. Buenas prácticas ## 11. Buenas prácticas en TypeScript
- Usa `async/await` para código más legible.
- Maneja siempre los **errores** con `try...catch` al hacer peticiones a servicios externos.
- No compartas claves o URLs sensibles en el frontend.
- Define funciones reutilizables para las peticiones.
- Asegúrate de que tu servidor tenga configurado **CORS** correctamente.
* Centralizar las llamadas HTTP en **servicios**.
* Tipar siempre los datos entrantes y salientes.
* Usar `Partial<T>` para actualizaciones.
* Manejar errores HTTP explícitamente.
Clone repository

Índice

  • Inicio
  • Modulo 1. Sitaxis básica
  • Modulo 2. Importaciones en Javascript
  • Modulo 3. Interacción con el BOM y con el DOM
  • Modulo 4. Uso de servicios y API REST