Cómo crear API de GraphQL y REST sin servidor con AWS Amplify

AWS Amplify permite a los desarrolladores crear y conectarse rápidamente a servicios poderosos en la nube. En el tutorial anterior, aprendió cómo configurar Amplify en un proyecto React y cómo usar la autenticación, el almacenamiento S3 y el hosting. Si necesita una introducción a AWS Amplify, asegúrese de revisar esa publicación primero.

En esta publicación, iremos más allá con React y AWS Amplify, explorando características como una capa de datos GraphQL administrada y funciones lambda.

Añadiendo una API GraphQL

Veamos cómo agregar una API de AWS AppSync GraphQL a nuestro proyecto y comenzar a usarlo desde nuestro proyecto..

El API que crearemos será un API de restaurante para que nos mantengamos al día con los restaurantes que nos gustan o nos gustaría visitar..

Para agregar la API de GraphQL a nuestro proyecto, podemos usar el siguiente comando:

amplificar añadir api

Se le pedirá que responda algunas preguntas de configuración. Seleccione las siguientes opciones:

  • Tipo de servicio: GraphQL
  • Nombre API: TutsGraphQLAPI
  • tipo de autorización: Clave API
  • Esquema GraphQL anotado: norte
  • Creación de esquemas guiados: Y
  • Lo que mejor describe tu proyecto? Objeto único con campos (por ejemplo, "Todo" con ID, nombre, descripción)
  • ¿Quieres editar el esquema ahora?? Y

Cuando se le solicite, actualice el esquema a lo siguiente y luego guarde el archivo:

// ubicado en amplify-web-app / amplify / backend / api / TutsGraphQLAPI / schema.graphql tipo Restaurant @model id: ID! nombre: String! descripción: cadena

Esto crea un solo tipo de datos-Restaurante-con los campos de identificación y nombre requeridos, así como una descripción opcional.

A continuación, empujemos las actualizaciones a nuestra cuenta:

amplificar empuje

Ahora, la API ha sido creada!

¿Qué acaba de pasar aquí? AWS Amplify usó la biblioteca GraphQL Transform incorporada para crear una API GraphQL completa, que incluye un esquema adicional, resolutores y una fuente de datos.

Para ver la nueva API de AppSync de AWS en cualquier momento después de su creación, puede ir al panel de control en https://console.aws.amazon.com/appsync y hacer clic en la API que se acaba de crear (asegúrese de que su región es ajuste correctamente). Desde el panel de control de AWS AppSync, puede ver la configuración de la API y realizar consultas y mutaciones en la API..

Ejecutando Mutaciones GraphQL

A continuación, interactuemos con la API de nuestra aplicación React..

Lo primero que nos gustaría hacer es crear una mutación. En GraphQL, las mutaciones son equivalentes a las de REST. PONER, EMPUJAR y BORRAR operaciones Debido a que aún no tenemos datos en nuestra base de datos, crearemos una mutación para crear un nuevo elemento de restaurante..

Para ello, estaremos importando. API y graphqlOperation desde AWS Amplify, definiendo una mutación y luego ejecutando la mutación.

Veamos una aplicación de ejemplo que implementa una mutación. En App.js, Primero importamos React, nuestra aplicación CSS y los componentes necesarios de AWS Amplify..

importar React, Componente desde 'reaccionar'; importar './App.css'; importar withAuthenticator desde 'aws-amplify-react' importar API, graphqlOperation desde 'aws-amplify'

A continuación, definimos una mutación para crear un restaurante. Especificamos que la mutación acepta un nombre y una descripción y se llama crearRestaurante. Esta mutación se definió automáticamente cuando creamos el Restaurante esquema de arriba Tenga en cuenta que la mutación se especifica en GraphQL, un lenguaje de consulta específico del dominio..

const CreateRestaurant = 'mutation ($ name: String!, $ description: String) createRestaurant (input: name: $ name description: $ description) id name description'

Ahora, creamos nuestro componente de aplicación..

la aplicación de la clase extiende el Componente // crear estado de estado inicial = nombre: ", descripción:" // actualizar el estado cuando el usuario ingresa entradas en Cambio = e => this.setState ([e.target.name]: e .target.value) // define la función para ejecutar la mutación // procesa el componente

A continuación, todavía dentro de la Aplicación Componente, definimos una función para ejecutar la mutación. Esto ejecuta la mutación llamando API.graphql, Pasando en la mutación y los datos..

 // define la función para ejecutar la mutación createRestaurant = async () => if (this.state.name === "|| this.state.description ===") return try const restaurant = name: this.state .nombre, descripción: this.state.description aguarda API.graphql (graphqlOperation (CreateRestaurant, restaurant)) this.setState (name: ", description:") console.log ('restaurant exitosamente creado!') catch (err) console.log ('error al crear el restaurante ...')

Luego renderizamos el componente, vinculando nuestro controlador de cambios y las funciones de mutación..

 // renderizar el componente render () return ( 
)

Finalmente, exportamos el Aplicación componente, con autenticacion.

exportación predeterminada con autenticador (aplicación, includeGreetings: true);

Debería poder ejecutar este código y comenzar a crear nuevos artículos de restaurante en la API.

Para ver la fuente de datos real para ver si los datos están allí, abra el panel de control de AWS AppSync, elija su API, haga clic en Fuentes de datos en el menú de la izquierda, y luego haga clic en el Nombre del recurso. Esto abrirá la tabla de Amazon DynamoDB. En la tabla, puede ver los datos en la Artículos lengüeta.

Ejecutando consultas GraphQL

A continuación, veamos cómo consultar datos de la API. Implementaremos esto en tres pasos:

  1. definir una consulta
  2. Ejecutar la consulta cuando se carga la aplicación.
  3. guardar el resultado de la consulta en nuestro estado y representarlo en la interfaz de usuario

Primero, definamos la consulta en Un nuevo componente. Una vez más, estamos usando el lenguaje GraphQL para especificar la consulta. Estamos usando el listaRestaurantes consulta que se definió automáticamente cuando empujamos el Los restaurantes esquema. El fragmento de código a continuación especifica que estamos esperando una lista de elementos, cada uno con una identificación, nombre y descripción..

const ListRestaurants = 'query listRestaurants items id name description

A continuación, debemos agregar un estado inicial adicional para mantener la variedad de restaurantes devueltos desde el servidor.

estado = nombre: ", descripción:", restaurantes: []

También necesitaremos agregar un componentDidMount evento del ciclo de vida para consultar datos del servidor GraphQL. Este método asíncrono actualizará el estado del componente cuando la lista de restaurantes se devuelva desde el servidor.

async componentDidMount () try const restaurants = await API.graphql (graphqlOperation (ListRestaurants)) console.log ('restaurants:', restaurants) this.setState (restaurants: restaurants.data.listRestaurants.items) catch ( err) console.log ('error al obtener datos:', err)

Finalmente, crearemos un componente que mapea el restaurantes matriz desde el estado del componente a HTML.

this.state.restaurants.map ((r, i) => ( 

r.name

r.descripción

))

Ahora, cuando ejecutemos la aplicación, veremos que los datos de la API se representan en una lista en la pantalla. Sin embargo, la aplicación no mostrará ningún cambio cuando se actualicen los datos, por ejemplo, cuando agrega un nuevo restaurante. 

Así que para empezar, vamos a actualizar el crearRestaurante Método para proporcionar una respuesta optimista a la interfaz de usuario. En este momento, cuando creamos un nuevo elemento, la base de datos se actualiza, pero la interfaz de usuario aún no conoce el nuevo elemento. Para solucionar esto, actualizaremos la gama de restaurantes en el crearRestaurante Método añadiendo el nuevo elemento a la matriz:

createRestaurant = async () => if (this.state.name === "|| this.state.description ===") return intente const restaurant = name: this.state.name, description: this. state.description const restaurants = [… this.state.restaurants, restaurant] this.setState (name: ", description:", restaurants) esperan API.graphql (graphqlOperation (CreateRestaurant, restaurant)) console.log (' restaurante creado con éxito! ') catch (err) console.log (' error al crear restaurant ... ')

Suscripciones de datos en tiempo real

A continuación, queremos poder trabajar con datos en tiempo real. En GraphQL, las suscripciones le permiten escuchar datos en tiempo real. Cuando hay nuevos datos disponibles, la suscripción se activa y los nuevos datos se transmiten a través de la suscripción. Depende de nosotros del lado del cliente manejar estos nuevos datos..

En nuestra aplicación, nos suscribiremos a la variedad de restaurantes y crearemos una enCreateRestaurante Suscripción que se activará cada vez que se cree un nuevo restaurante. Luego tomaremos el nuevo elemento de la suscripción, actualizaremos nuestra matriz existente y llamaremos setState con el fin de volver a representar la interfaz de usuario con los nuevos datos.

Al igual que para las mutaciones y consultas, comenzamos por definir la suscripción en el lenguaje específico del dominio GraphQL.

// define la suscripción const OnCreateRestaurant = 'abono onCreateRestaurant id name description'

La suscripción será creada en el componentDidMount El método del ciclo de vida antes o después de la consulta GraphQL que ya hemos configurado:

async componentDidMount () try const restaurants = await API.graphql (graphqlOperation (ListRestaurants)) console.log ('restaurants:', restaurants) this.setState (restaurants: restaurants.data.listRestaurants.items) catch ( err) console.log ('error fetching data:', err) API.graphql (graphqlOperation (OnCreateRestaurant)) .subscribe (next: eventData => const data = eventData.value.data.onCreateRestaurant console.log ( 'data:', data) const restaurants = [… this.state.restaurants.filter (r => r.name! == data.name && r.description! == data.description), data] this.setState ( restaurantes))

Ahora, si abres dos ventanas del navegador, deberías poder crear una mutación en una pantalla y ver cómo ocurre la actualización en todas las demás pantallas..

Si nos fijamos en el .filtrar En el método que usamos para crear la nueva matriz de restaurantes en la suscripción, puede ver que estamos comprobando si hay duplicados que contengan el mismo nombre y la misma descripción. Tal vez una mejor manera de hacer esto en producción sería crear un ID de cliente único que también se almacene en la base de datos y el filtro basado en ese identificador.

Creación de una API REST con AWS Lambda

GraphQL es una maravillosa tecnología de vanguardia, pero a veces nuestro proyecto requerirá que creemos una API REST tradicional. Con AWS Lambda y Amplify, también es fácil crear API REST sin servidor utilizando la CLI.

Cuando creamos la API GraphQL, usamos el amplificar crear api mando. Este comando nos da la opción de crear una API GraphQL o una API REST. La API REST puede configurarse para usar una función Express sin servidor independiente o una función JavaScript sin servidor que está preconfigurada para trabajar con las operaciones de Amazon DynamoDB CRUD.

La opción que usaremos para esta API es una función Express sin servidor..

Sigamos adelante y agreguemos la nueva característica:

amplificar añadir api

Como de costumbre, esto le pedirá que complete algunos detalles de configuración. Suministre las siguientes opciones:

  • Tipo de servicio: DESCANSO
  • ingrese un nombre de recurso que se utilizará dentro del proyecto: por ejemplo,. amplificar
  • ingrese una ruta para los puntos finales REST: por ejemplo,. /gente
  • Fuente lambda: Crear una nueva función Lambda
  • Nombre de la función de AWS Lambda: amplificar la función de reposo
  • plantilla de función: Función Express sin servidor (Integración con Amazon API Gateway)
  • edita la función lambda local ahora? Y

Ahora, podrás editar la función lambda localmente. En el archivo, reemplazaremos el existente. app.get ('/ personas') Método con lo siguiente:

// amplify-web-app / amplify / backend / function / amplifyrestapi / src / app.js app.get ('/ people', function (req, res) const people = [name: "Nader",  nombre: "Amanda", nombre: "Chris", nombre: ""] res.json (success: true, people));

Esto solo devuelve una lista constante de nombres para propósitos de demostración. Guarde este archivo y continúe con las siguientes respuestas:

  • restringir el acceso a la API? 
  • quien debe tener acceso? Solo usuarios autenticados
  • ¿Qué tipo de acceso desea para los usuarios autenticados?? leer
  • agregar otro camino? norte

Esto ha creado una nueva función Lambda local que podremos actualizar y enviar a nuestra cuenta según sea necesario. El código para esta función lambda se encuentra en amplificar / backend / function / amplifyrestapi / src.

Ahora, empujemos las actualizaciones a nuestra cuenta:

amplificar empuje

Consultar la API REST desde el cliente

Ahora, nuestra función Lambda está en funcionamiento y podemos comenzar a interactuar con ella.!

Primero, consultemos los datos de la nueva API y mostrémoslos en nuestra interfaz de usuario. Para ello, utilizaremos el API clase de amplificar, llamando API.get. En la sección anterior, utilizamos API.graphql para realizar solicitudes a nuestra API GraphQL, pero hay muchos métodos que están disponibles en la clase API. Puedes aprender más sobre la clase API en los documentos oficiales.

importe API desde 'aws-amplify' // 1. en el estado inicial, cree una matriz vacía de personas state = people: [] // 2. en componentDidMount, buscaremos estos datos usando la clase API try const peopleData = aguarda API.get ('amplifyrestapi', '/ people') this.setState (people: peopleData.people) catch (err) console.log ('recuperación de errores de Lambda API') / / 3. renderiza los datos de personas a la IU en el método de render this.state.people.map ((person, index) => ( 

person.name

))

Ahora, deberíamos poder ejecutar la aplicación, obtener los datos de personas de nuestra API y mostrarlos en la pantalla.

Actualización de una función Lambda desde la CLI

Además de crear una nueva función Lambda, también podemos actualizar nuestra función Lambda desde la CLI.

Cambiemos la función para golpear una API y obtener datos en lugar de constantes de codificación. Para ello, utilizaremos el axios biblioteca para realizar las solicitudes HTTP, y recuperaremos datos de la API de Star Wars.

Para usar axios, tendremos que navegar a amplificar / backend / function / amplifyrestapi / srce instalarlo allí. Axios se instala en la carpeta de proyectos de la función Lambda, no en la carpeta principal de la aplicación, ya que se ejecutará en el lado del servidor de la función Lambda.

hilo agregar axios # o npm instalar axios

Ahora eso axios está instalado, actualizaremos la función Lambda para recuperar datos de la API de Star Wars:

var axios = require ('axios') app.get ('/ people', function (req, res) axios.get ('https://swapi.co/api/people/') .then (response => res.json (success: true, people: response.data.results)) .catch (error => res.json (success: false, error)));

Ahora, guarde el archivo y ejecute amplificar empuje desde la carpeta principal del proyecto para actualizar su función Lambda en la nube:

amplificar empuje

Ahora, nuestra API está actualizada y lista para funcionar.!

Cuando actualizamos la aplicación, ahora deberíamos ver los datos que se devuelven desde la API de Star Wars.

Conclusión

En esta serie, aprendió cómo comenzar a usar AWS Amplify y agregarlo a su proyecto React, así como a agregar autenticación, almacenamiento, alojamiento y una API GraphQL o REST, todo sin tener que codificar o aprovisionar manualmente un servidor. . Eso es mucho poder para los desarrolladores de aplicaciones.! 

Espero que estas publicaciones te hayan inspirado para crear tus propias aplicaciones web sin servidor utilizando tecnología sin servidor y AWS Amplify. Háganos saber lo que piensa en los comentarios a continuación..