Header Ads Widget

Ticker

6/recent/ticker-posts

Creación de un servicio HTTP Ionic 5 / Angular para comunicarse con una API REST

 Este tutorial es parte de una serie de tutoriales titulada ¨Ionic 5, Angular and RxJS Observables: Building an HTTP Service to Communicate with A REST API¨ que contiene los siguientes tutoriales:

  • Introducción y creación del back-end de API
  • Creación de un servicio HTTP para comunicarse con una API REST (esta)
  • Prueba unitaria de servicios angulares con HttpTestingController

En este tutorial veremos cómo crear un servicio / proveedor Angular para encapsular el código para comunicarse con el back-end de la API REST.

Nota : Para obtener un tutorial completo y detallado, consulte:

  • Tutorial de autenticación Ionic 5 JWT: uso de Angular HttpClient con Node & Express.js Server
  • Tutorial de Ionic 5: Creación y creación de temas para una interfaz de usuario de inicio de sesión y registro con formularios angulares

Envío de llamadas a la API en Ionic 5

Las llamadas a la API, que utilizan el módulo HttpClient , son asincrónicas por naturaleza, ya que debe esperar a que la respuesta provenga de los servidores remotos sin bloquear la aplicación cuando todavía está esperando.

Una solicitud HTTP tardará algún tiempo en llegar al servidor de la API y también la respuesta HTTP necesitará tiempo para llegar, por lo que debe ejecutarse en segundo plano antes de que los datos puedan estar listos para ser consumidos.

Con Ionic 5 / Angular puede hacer uso de las API de JavaScript modernas: Promesas y Observables que proporcionan abstracciones de alto nivel para manejar la naturaleza asincrónica de las operaciones de obtención de datos y consumo de API o cualquier otra operación que tarde en finalizar.

¿Qué es una promesa?

El objeto Promise representa la eventual finalización (o falla) de una operación asincrónica y su valor resultante .-- MDN

Una promesa puede ser:

  • pendiente: el estado de espera inicial antes de un eventual cumplimiento o rechazo.
  • cumplido: la operación se ha completado con éxito con un valor.
  • rechazado: la operación ha fallado con un error.

Usted coloca sus acciones asíncronas, ya sea cuando la promesa se ha resuelto con éxito o ha fallado, dentro de los métodos .then (() => {}) y .catch (() => {}) .

Las promesas se pueden encadenar para manejar escenarios complejos

Fuente de imagen

¿Qué es un observable?

Los observables son un estándar más nuevo que las promesas que se agregan a Angular 2+ (y se incluirán en el ES7 ) para permitir que los desarrolladores de Angular manejen casos de uso más avanzados con un código claro y conciso. Por ejemplo, puede cancelar un observable cuando lo necesite sin usar bibliotecas externas como el caso de las promesas y también puede tener múltiples valores de retorno.

Al igual que las promesas, los observables son abstracciones que lo ayudan a lidiar con las operaciones asincrónicas, excepto que manejan la asincronosidad de una manera diferente y brindan más funciones, por lo que se vuelven preferibles a las promesas entre la comunidad JavaScript / Angular.

A diferencia de las promesas, que solo pueden manejar eventos individuales, los observables, por otro lado, pueden pasar más de un evento.

Un Observable se puede representar como un flujo de eventos que se pueden manejar con la misma API y se pueden cancelar (esta función no está disponible para ES6 Promises, por lo que debe usar bibliotecas externas para hacerlo).

Puede usar diferentes operadores similares a matrices, como map () , forEach () y reduce (), etc. para trabajar fácilmente con observables y manejar casos de uso avanzados con una API simple y clara.

Los nuevos métodos Angular HttpClient devuelven objetos observables que también se pueden convertir en promesas (usando el operador toPromise () ) para que pueda usar la abstracción correcta cuando sea apropiado.

Generando un proveedor de servicios

Un proveedor de servicios es una abstracción angular que se puede utilizar en cualquier otro componente, página o servicio a través de la inyección de dependencia angular o DI. Puede usar proveedores para encapsular el código que es común entre muchos lugares de su aplicación, por lo que en lugar de repetir la misma lógica en muchos lugares, puede aislar ese código en su propio servicio e inyectarlo donde quiera usarlo. Esto le permitirá cumplir con el principio DRY (Don't Repeat Yourself). Si no sabe qué es DRY, aquí está su definición de Wikipedia

En ingeniería de software, no te repitas (DRY) es un principio de desarrollo de software que tiene como objetivo reducir la repetición de patrones de software, reemplazándolos con abstracciones; y varias copias de los mismos datos, utilizando la normalización de datos para evitar la redundancia.

Siguiendo el principio DRY, coloca el código que interactúa con su API de back-end en un lugar, lo que hace que la aplicación sea fácil de mantener.

Ahora generemos nuestro servicio de interfaz API usando Ionic CLI 5. Regrese a su terminal o símbolo del sistema y luego ejecute el siguiente comando para generar un proveedor de servicios


ionic g provider rest

Este comando creará una nueva carpeta en su proyecto src/providersy agregará su proveedor recién creado a la matriz de proveedores en src/app/app.module.ts(si no está agregado, asegúrese de hacerlo manualmente).


/* Other imports */

import { HttpClientModule } from  '@angular/common/http';

import { RestProvider } from  '../providers/rest/rest';

@NgModule({

/* ... */

providers: [

StatusBar,

SplashScreen,

{provide:  ErrorHandler, useClass:  IonicErrorHandler},

RestProvider  //this is our provider entry

]

})

export  class  AppModule {}

El servicio Angular HttpClient

La nueva API Angular HttpClient se introdujo en Angular 4.3+. Es una mejor alternativa a la API HTTP existente que vive en su propio paquete @angular/common/http.

En Angular 5, el antiguo cliente HTTP que vive en él @angular/httpestá en desuso, por lo que los desarrolladores de Angular e Ionic 5 deben migrar sus aplicaciones existentes para usar la nueva API HttpClient .

HttpClient tiene muchos cambios y características sobre la API anterior, como:

  • la respuesta es un objeto JSON de forma predeterminada, por lo que no es necesario analizarlo manualmente

  • la introducción de la requestProgress interfaz para listenning para la descarga y operaciones de carga progreso

  • la introducción de la interfaz HttpInterceptor para crear interceptores: middlewares que se pueden colocar en la tubería de solicitud / respuesta

El servicio Angular HttpClient está disponible como una clase inyectable desde la que se puede importar @angular/common/http.

HttpClient proporciona métodos para enviar solicitudes HTTP POST, GET, PUT y DELETE, etc., que devuelven Observables.

Ejemplo de implementación de nuestro proveedor de servicios

Basándonos en los puntos finales expuestos por nuestro back-end simple del servidor json , podemos crear una implementación de ejemplo de nuestro servicio Angular


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

import { HttpClient } from  '@angular/common/http';



@Injectable()

export  class  RestProvider {

baseUrl:string = "http://localhost:3000";

constructor(private  httpClient : HttpClient) { }

// Sending a GET request to /products

public  getProducts(){

}

// Sending a POST request to /products

public  createProduct(product: Product) {

}

// Sending a GET request to /products/:id

public  getProductById(productId: number) {

}

// Sending a PUT request to /products/:id

public  updateProduct(product: Product){

}

// Sending a DELETE request to /products/:id

public  deleteProductById(productId: number) {

}

}

Hemos importado el decorador inyectable para transformar esta clase de TypeScript en un servicio inyectable. Luego importamos el HttpClient para realizar las solicitudes HTTP.

A continuación, hemos declarado la variable baseUrl para contener la dirección de su API back-end. A continuación, inyectamos HttpClient como httpClient .

Antes de que pueda implementar con éxito los métodos de servicio, debe asegurarse de importar las siguientes dependencias de la biblioteca RxJS:


import { Observable } from  'rxjs/Observable';

import  'rxjs/add/operator/catch';

import  'rxjs/add/operator/map';

También debe declarar y definir un modelo de producto , ya sea en el mismo archivo que el servicio o en un archivo separado y luego importarlo:


export  class  Product {

id: number;

name: string;

cost: number;

quantity: number;

constructor(values: Object = {}) {

Object.assign(this, values);

}

}

Veamos ahora cómo implementar cada uno de estos métodos.

Implementación de getProducts () para obtener todos los productos

El getProducts()método se utilizará para obtener todos los productos del punto final de la API correspondiente:


public  getProducts(): Observable<Product[]> {

return  this.httpClient

.get(this.baseUrl + '/products')

.map(products  => {

return  products.map((product) =>  new  Product(product));

})

.catch((err)=>{

console.error(err);

});

}

Primero llamamos al .get()método para enviar la solicitud GET al punto final correspondiente que devolverá un punto final

Luego usamos el map()operador RxJS en el Observable devuelto para convertirlo de ObservableObservable es decir, una variedad de productos.

También usamos el .catch()método para registrar cualquier error lanzado.

Implementación de getProductById () para obtener productos individuales

Se getProductById()utilizará para obtener un solo producto por su id.


public  getProductById(productId: number): Observable<Product> {

return  this.httpClient

.get(this.baseUrl + '/products/' + productId)

.map(response  => {

return  new  Product(response);

})

.catch((err)=>{

console.error(err);

});

}

Implementación de createProduct () para crear nuevos productos

El createProduct()método se utilizará para crear un nuevo producto enviando una solicitud POST, con los datos del producto, al punto final correspondiente.


public  createProduct(product: Product): Observable<Product> {

return  this.httpClient

.post(this.baseUrl + '/products', product)

.map(response  => {

return  new  Product(response);

})

.catch((error)=>{

console.error(error);

});

}

Implementación de updateProduct () para actualizar productos existentes

Se updateProduct()utilizará para actualizar un producto por su ID , enviando una solicitud PUT al punto final correspondiente y luego convertirá la respuesta en un nuevo Producto utilizando el .map()operador RxJS .


public  updateProduct(product: Product): Observable<Product> {

return  this.httpClient

.put(this.baseUrl + '/products/' + product.id, product)

.map(response  => {

return  new  Product(response);

})

.catch((err)=>{

console.error(err);

});

}

Implementación de deleteProductById () para eliminar productos

El deleteProductById()método se utilizará para eliminar productos individuales por id , enviando una solicitud DELETE al punto final correspondiente:


public  deleteProductById(productId: number) {

return  this.httpClient

.delete(this.baseUrl+ '/products/' + productId)

.catch((e)=>{

console.error(e);

});

}

Uso del servicio de API Rest

Después de implementar el servicio para interactuar con nuestro back-end REST, veamos ahora cómo usar el servicio en nuestra aplicación.

Todos los métodos que hemos implementado previamente en el servicio devuelven RxJS Observables

Llamar a cualquier método en nuestros componentes no enviará ninguna solicitud HTTP. Necesitamos suscribirnos al Observable devuelto para enviar la solicitud correspondiente al back-end de la API.

Para suscribirnos a un Observable, necesitamos usar el .subscribe()método, que toma 3 argumentos:

  • onNext: se llama cuando el Observable emite un nuevo valor

  • onError: se llama cuando el Observable arroja un error

  • onCompleted: se llama cuando el Observable ha terminado con gracia

Agregar la página de productos

Utilice Ionic CLI 5 para generar una página para agregar operaciones CRUD (Crear, Leer, Actualizar y Eliminar) que llamarán a los métodos correspondientes en el servicio creado anteriormente.

Entonces, primero necesitamos importar el servicio usando:


import { RestProvider } from  './../../providers/rest/rest';

A continuación, inyectamos el servicio como restProvider :


constructor(public  navCtrl: NavController, public  restProvider: RestProvider) { }

A continuación, declaramos una matriz para contener los productos:


private  products : Product[] = [];

Luego llamamos a este código, para obtener todos los productos y almacenarlos en la matriz de productos, cuando la vista ingresa o en el constructor:


this.restProvider.getProducts().subscribe((products : Product[])=>{

this.products = products;

});

A continuación, necesitamos tres métodos para crear, actualizar y eliminar productos:

onCreateProduct()se llama cuando necesitamos crear un producto a través de un formulario. Este método simplemente se suscribe al método correspondiente en el servicio y concatena el producto recién creado con la matriz de productos.


onCreateProduct(product) {

this.restProvider

.createProduct(product)

.subscribe(

(newProduct) => {

this.products = this.products.concat(newProduct);

}

);

}

onUpdateProduct() se debe llamar cuando necesite actualizar un producto existente:


onUpdateProduct(product) {

this.restProvider

.updateProduct(product)

.subscribe(

(updatedProduct) => {

/* You can assign back the updated product to the model holding the form's product*/

}

);

}

onRemoveProduct()se puede llamar cuando necesite eliminar un producto. Este método es el método de matriz .filter()para filtrar el producto eliminado de la matriz de productos:


onRemoveProduct(product) {

this.restProvider

.deleteProductById(product.id)

.subscribe(

() => {

this.products = this.products.filter((e) =>  e.id !== product.id);

}

);

}

Conclusión

Este es el final de este tutorial donde hemos visto cómo realizar solicitudes HTTP en su aplicación Ionic 5 / Angular. El siguiente tutorial de esta serie de tutoriales es: Prueba unitaria de servicios angulares con HttpTestingController

Publicar un comentario

0 Comentarios