|
|
|
# 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).**
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
## 1. Introducción a la asincronía
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
```ts
|
|
|
|
```typescript
|
|
|
|
console.log('Iniciando petición...');
|
|
|
|
|
|
|
|
setTimeout((): void => {
|
| ... | ... | @@ -18,21 +16,29 @@ setTimeout((): void => { |
|
|
|
console.log('Fin de la petición');
|
|
|
|
```
|
|
|
|
|
|
|
|
El flujo principal no se bloquea; la operación asíncrona se gestiona mediante el **Event Loop**. El **Event Loop** es el mecanismo que permite a Javascript (Typescript por herencia) ejecutar codigo en paralelo. Podría decirse que es un organizador de tareas o hilos.
|
|
|
|
El flujo principal no se bloquea; la operación asíncrona se gestiona mediante el **Event Loop**. El **Event Loop** es el mecanismo que permite a Javascript (Typescript por herencia) ejecutar codigo en paralelo. Podría decirse que es un organizador de tareas o hilos.\
|
|
|
|
Si se quisiera esperar a recibir los datos lo que habría que hacer es:
|
|
|
|
```ts
|
|
|
|
console.log('Iniciando petición...');
|
|
|
|
|
|
|
|
async function getDatos(): Promise<void> {
|
|
|
|
```typescript
|
|
|
|
console.log('Iniciando petición...');
|
|
|
|
|
|
|
|
await retraso();
|
|
|
|
async function retraso(): Promise<string> {
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
console.log('Cargando Datos');
|
|
|
|
setTimeout(() => {
|
|
|
|
resolve('Datos cargados');
|
|
|
|
}, 1500);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log('Datos recibidos del servidor');
|
|
|
|
console.log('Petición enviada');
|
|
|
|
async function ejecutar() {
|
|
|
|
let respuesta = await retraso();
|
|
|
|
console.log(respuesta);
|
|
|
|
console.log('Fin de la petición');
|
|
|
|
}
|
|
|
|
|
|
|
|
getDatos();
|
|
|
|
ejecutar();
|
|
|
|
```
|
|
|
|
|
|
|
|
---
|
| ... | ... | @@ -46,14 +52,13 @@ Las API REST intercambian datos en **formato JSON**, fácilmente mapeables a **i |
|
|
|
---
|
|
|
|
|
|
|
|
## 3. Métodos HTTP más comunes
|
|
|
|
|
|
|
|
| Método | Acción | Ejemplo en la aplicación |
|
|
|
|
| ------ | ------------------- | ------------------------ |
|
|
|
|
| GET | Obtener información | Consultar recursos |
|
|
|
|
| POST | Crear un recurso | Añadir personal |
|
|
|
|
| PUT | Actualizar completo | Editar recurso |
|
|
|
|
| PATCH | Actualizar parcial | Cambiar estado |
|
|
|
|
| DELETE | Eliminar | Dar de baja |
|
|
|
|
| Método | Acción | Ejemplo en la aplicación |
|
|
|
|
|--------|--------|--------------------------|
|
|
|
|
| GET | Obtener información | Consultar recursos |
|
|
|
|
| POST | Crear un recurso | Añadir personal |
|
|
|
|
| PUT | Actualizar completo | Editar recurso |
|
|
|
|
| PATCH | Actualizar parcial | Cambiar estado |
|
|
|
|
| DELETE | Eliminar | Dar de baja |
|
|
|
|
|
|
|
|
---
|
|
|
|
|
| ... | ... | @@ -61,7 +66,7 @@ Las API REST intercambian datos en **formato JSON**, fácilmente mapeables a **i |
|
|
|
|
|
|
|
JSON es el formato estándar de intercambio de datos. En TypeScript, el JSON recibido se transforma en **objetos tipados**.
|
|
|
|
|
|
|
|
```ts
|
|
|
|
```typescript
|
|
|
|
interface RecursoDTO {
|
|
|
|
id: string;
|
|
|
|
unidad: string;
|
| ... | ... | @@ -84,7 +89,7 @@ const obj: RecursoDTO = JSON.parse(json); |
|
|
|
|
|
|
|
`fetch` devuelve una `Promise<Response>`. En TypeScript se tipa explícitamente la respuesta esperada.
|
|
|
|
|
|
|
|
```ts
|
|
|
|
```typescript
|
|
|
|
async function obtenerRecursos(): Promise<RecursoDTO[]> {
|
|
|
|
const respuesta = await fetch('http://localhost:8080/panacea/rest/recursos');
|
|
|
|
|
| ... | ... | @@ -110,7 +115,7 @@ obtenerRecursos() |
|
|
|
|
|
|
|
`async/await` permite escribir código asíncrono con estructura secuencial, manteniendo el tipado.
|
|
|
|
|
|
|
|
```ts
|
|
|
|
```typescript
|
|
|
|
async function cargarRecursos(): Promise<void> {
|
|
|
|
try {
|
|
|
|
const respuesta = await fetch('http://localhost:8080/panacea/rest/recursos');
|
| ... | ... | @@ -128,7 +133,7 @@ cargarRecursos(); |
|
|
|
|
|
|
|
## 7. Envío de datos (POST)
|
|
|
|
|
|
|
|
```ts
|
|
|
|
```typescript
|
|
|
|
async function agregarRecurso(nuevo: RecursoDTO): Promise<RecursoDTO> {
|
|
|
|
const respuesta = await fetch('http://localhost:8080/panacea/rest/recursos', {
|
|
|
|
method: 'POST',
|
| ... | ... | @@ -158,7 +163,7 @@ agregarRecurso({ |
|
|
|
|
|
|
|
### PATCH (actualización parcial)
|
|
|
|
|
|
|
|
```ts
|
|
|
|
```typescript
|
|
|
|
async function actualizarRecurso(id: string, datos: Partial<RecursoDTO>): Promise<void> {
|
|
|
|
await fetch(`http://localhost:8080/panacea/rest/recursos/${id}`, {
|
|
|
|
method: 'PATCH',
|
| ... | ... | @@ -170,7 +175,7 @@ async function actualizarRecurso(id: string, datos: Partial<RecursoDTO>): Promis |
|
|
|
|
|
|
|
### DELETE (eliminación)
|
|
|
|
|
|
|
|
```ts
|
|
|
|
```typescript
|
|
|
|
async function eliminarRecurso(id: string): Promise<void> {
|
|
|
|
await fetch(`http://localhost:8080/panacea/rest/recursos/${id}`, {
|
|
|
|
method: 'DELETE',
|
| ... | ... | @@ -185,7 +190,7 @@ async function eliminarRecurso(id: string): Promise<void> { |
|
|
|
|
|
|
|
CORS es un mecanismo de seguridad del navegador. El servidor debe permitir explícitamente el origen del frontend.
|
|
|
|
|
|
|
|
```
|
|
|
|
```plaintext
|
|
|
|
Access-Control-Allow-Origin: http://localhost:4200
|
|
|
|
```
|
|
|
|
|
| ... | ... | @@ -201,7 +206,7 @@ Access-Control-Allow-Origin: http://localhost:4200 |
|
|
|
<button id="btnCargar">Cargar recursos</button>
|
|
|
|
```
|
|
|
|
|
|
|
|
```ts
|
|
|
|
```typescript
|
|
|
|
const btn = document.getElementById('btnCargar') as HTMLButtonElement;
|
|
|
|
const lista = document.getElementById('lista') as HTMLUListElement;
|
|
|
|
|
| ... | ... | @@ -228,4 +233,4 @@ btn.addEventListener('click', async (): Promise<void> => { |
|
|
|
* Centralizar las llamadas HTTP en **servicios**.
|
|
|
|
* Tipar siempre los datos entrantes y salientes.
|
|
|
|
* Usar `Partial<T>` para actualizaciones.
|
|
|
|
* Manejar errores HTTP explícitamente. |
|
|
|
* Manejar errores HTTP explícitamente. |
|
|
\ No newline at end of file |