如何使用AWS Amplify构建无服务器GraphQL和REST API

如何使用AWS Amplify构建无服务器GraphQL和REST API_第1张图片

AWS Amplify使开发人员可以快速创建并连接到云中的强大服务。 在上一教程中,您学习了如何在React项目中设置Amplify以及如何使用身份验证,S3存储和托管 。 如果您需要有关AWS Amplify的简介,请确保首先查看该文章。

在本文中,我们将进一步使用React和AWS Amplify,探索诸如托管GraphQL数据层和lambda函数之类的功能。

添加GraphQL API

让我们看一下如何向我们的项目中添加一个AWS AppSync GraphQL API并从项目中开始使用它。

我们将创建的API将是饭店API,供我们跟上我们喜欢或想要参观的饭店的情况。

要将GraphQL API添加到我们的项目中,我们可以使用以下命令:

amplify add api

系统将提示您回答一些配置问题。 选择以下选项:

  • 服务类型: GraphQL
  • API名称: TutsGraphQLAPI
  • 授权类型: API密钥
  • 带注释的GraphQL模式: N
  • 指导模式创建: Y
  • 什么最能描述您的项目? 具有字段的单个对象(例如具有ID,名称,描述的“ Todo”)
  • 您现在要编辑架构吗? ÿ

出现提示时,将架构更新为以下内容,然后保存文件:

// located at amplify-web-app/amplify/backend/api/TutsGraphQLAPI/schema.graphql

type Restaurant @model {
  id: ID!
  name: String!
  description: String
}

这只会创建一个数据类型,即Restaurant -具有必填的ID和名称字段以及可选的说明。

接下来,让我们将更新推送到我们的帐户:

amplify push

现在,API已创建!

刚刚发生什么事了? AWS Amplify使用内置的GraphQL Transform库来创建完整的GraphQL API,其中包括其他架构,解析器和数据源。

要在创建新的AWS AppSync API之后随时查看它,您可以转到位于https://console.aws.amazon.com/appsync的仪表板,然后单击刚刚创建的API(确保您所在的区域是设置正确)。 在AWS AppSync仪表板中,您可以查看API配置并在API上执行查询和更改。

执行GraphQL突变

接下来,让我们与React应用程序中的API进行交互。

我们要做的第一件事是创建一个突变。 在GraphQL中,突变等效于REST的PUTPUSHDELETE操作。 因为我们的数据库中还没有任何数据,所以我们将创建一个变体来创建一个新的餐厅商品。

为此,我们将从AWS Amplify导入APIgraphqlOperation ,定义一个突变,然后执行该突变。

让我们看一个实现变异的示例应用程序。 App.js ,首先我们导入React,我们的应用CSS和必要的AWS Amplify组件。

import React, { Component } from 'react';
import './App.css';

import { withAuthenticator } from 'aws-amplify-react'
import { API, graphqlOperation } from 'aws-amplify'

接下来,我们定义一个变种来创建一家餐厅。 我们指定该突变接受名称和描述,并命名为createRestaurant 当我们在上方创建Restaurant模式时,会自动定义此突变。 请注意,突变是在GraphQL(一种特定于域的查询语言)中指定的。

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

现在,我们创建我们的应用程序组件。

class App extends Component {
  //create initial state
  state = {name: '', description: ''}
 
  //update state when user types into inputs
  onChange = e => {
    this.setState({ [e.target.name]: e.target.value })
  }
 
  //define function to execute mutation
  //render the component
}

接下来,仍然在App组件中,我们定义一个函数来执行突变。 这通过调用API.graphql执行变异,并传入变异和数据。

//define function to execute mutation
  createRestaurant = async() => {
    if (this.state.name === '' || this.state.description === '') return
    try {
      const restaurant = { name: this.state.name, description: this.state.description }
      await API.graphql(graphqlOperation(CreateRestaurant, restaurant))
      this.setState({ name: '', description: '' })
      console.log('restaurant successfully created!')
    } catch (err) {
      console.log('error creating restaurant...')
    }
  }

然后,我们渲染组件,将更改处理程序和变异函数链接起来。

//render the component
  render() {
    return (
      
) }

最后,我们通过身份验证导出App组件。

export default withAuthenticator(App, { includeGreetings: true });

您应该能够运行此代码,并开始在API中创建新的餐厅商品。

要查看实际数据源以查看数据是否存在,请打开AWS AppSync仪表板 ,选择您的API,单击左侧菜单中的Data Sources ,然后单击Resource Name 这将打开Amazon DynamoDB表。 在表中,您可以在“ 项目”选项卡中查看数据。

运行GraphQL查询

接下来,让我们看看如何从API查询数据。 我们将分三步实施:

  1. 定义查询
  2. 应用加载时执行查询
  3. 将查询结果保存为我们的状态,并在用户界面中呈现

首先,让我们在 一个新的组件。 再次,我们使用GraphQL语言指定查询。 我们使用的是在推送Restaurants模式时自动定义的listRestaurants查询。 下面的代码段指定我们希望看到一个项目列表,每个项目都有一个ID,名称和描述。

const ListRestaurants = `
  query {
    listRestaurants {
      items {
        id name description
      }
    }
  }

接下来,我们需要添加一些其他的初始状态来容纳从服务器返回的餐馆阵列。

state = { name: '', description: '', restaurants: [] }

我们还需要添加一个componentDidMount生命周期事件,以从GraphQL服务器查询数据。 从服务器返回餐厅列表时,此异步方法将更新组件状态。

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)
  }
}

最后,我们将创建一个组件,将restaurants数组从组件状态映射到HTML。

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

{r.name}

{r.description}

)) }

现在,当我们运行该应用程序时,我们将看到来自API的数据正在屏幕上的列表中呈现。 但是,当数据更新时(例如,当您添加新餐厅时),该应用程序将不会显示任何更改。

因此,对于初学者来说,让我们更新createRestaurant方法以提供对UI的乐观响应。 现在,当我们创建一个新项目时,数据库会更新,但是UI尚不知道新项目。 为了解决这个问题,我们将在createRestaurant方法中通过将新项添加到数组来更新restaurant数组:

createRestaurant = async() => {
  if (this.state.name === '' || this.state.description === '') return
  try {
    const restaurant = { name: this.state.name, description: this.state.description }
    const restaurants = [...this.state.restaurants, restaurant]
    this.setState({ name: '', description: '', restaurants })
    await API.graphql(graphqlOperation(CreateRestaurant, restaurant))
    console.log('restaurant successfully created!')
  } catch (err) {
    console.log('error creating restaurant...')
  }
}

实时数据订阅

接下来,我们希望能够处理实时数据。 在GraphQL中,订阅使您可以实时侦听数据。 当有新数据可用时,将触发订阅,然后通过订阅将新数据向下传递。 客户端应由我们来处理这些新数据。

在我们的应用程序中,我们将订阅一系列餐厅,并创建一个onCreateRestaurant订阅,该订阅将在创建新餐厅时触发。 然后,我们将从订阅中获取新项目,更新我们现有的数组,并调用setState以便使用新数据重新呈现UI。

与变异和查询一样,我们首先以GraphQL域特定语言定义订阅。

// define the subscription
const OnCreateRestaurant = `
  subscription {
    onCreateRestaurant {
      id name description
    }
  }
`

在我们已经设置的GraphQL查询之前或之后,将在componentDidMount生命周期方法中创建订阅:

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({ restaurants })
      }
    })
  }

现在,如果您打开两个浏览器窗口,则应该可以在一个屏幕上创建一个变体,并在所有其他屏幕上看到更新。

如果查看在.filter中创建新的餐厅数组时使用的.filter方法,则可以看到我们正在检查是否存在重复的名称和描述都相同的重复项。 也许在生产环境中执行此操作的更好方法是创建一个唯一的客户端ID,该客户端ID也存储在数据库中,并根据该标识符进行过滤。

使用AWS Lambda创建REST API

GraphQL是一种出色的尖端技术,但是有时我们的项目会要求我们创建传统的REST API。 借助AWS Lambda和Amplify,使用CLI创建无服务器REST API也很容易。

创建GraphQL API时,我们使用了amplify create api命令。 该命令使我们可以选择创建GraphQL API或REST API。 可以将REST API配置为使用独立的无服务器Express函数或预先配置为与Amazon DynamoDB CRUD操作一起使用的无服务器JavaScript函数。

我们将用于此API的选项是无服务器Express函数。

让我们继续添加新功能:

amplify add api

与往常一样,这将提示您填写一些配置详细信息。 提供以下选项:

  • 服务类型: REST
  • 输入将在项目中使用的资源名称:例如amplifyrestapi
  • 输入REST端点的路径:例如/ people
  • Lambda源: 创建一个新的Lambda函数
  • AWS Lambda函数名称: amplifyrestapifunction
  • 函数模板: 无服务器表达函数(与Amazon API Gateway集成)
  • 现在编辑本地lambda函数? ÿ

现在,您将能够在本地编辑lambda函数。 在文件中,我们将使用以下内容替换现有的app.get('/people')方法:

// amplify-web-app/amplify/backend/function/amplifyrestapi/src/app.js

app.get('/people', function(req, res) {
  const people = [
    { name: "Nader" }, { name: "Amanda" }, { name: "Chris" }, { name: "" }
  ]
  res.json({
    success: true,
    people
  })
});

这只是出于演示目的而返回一个常数名称列表。 保存此文件,然后继续以下回答:

  • 限制API访问?
  • 谁应该访问? 仅经过身份验证的用户
  • 您想要经过身份验证的用户使用哪种访问方式?
  • 添加其他路径? ñ

这样就在本地创建了一个新的Lambda函数,我们将能够根据需要更新并推送到我们的帐户。 此lambda函数的代码位于amplify / backend / function / amplifyrestapi / src中

现在,让我们将更新推送到我们的帐户:

amplify push

从客户端查询REST API

现在,我们的Lambda函数已启动并正在运行,我们可以开始与它进行交互了!

首先,让我们从新API查询数据并将其显示在我们的UI中。 为此,我们将使用Amplify的API类,调用API.get 在上一节中,我们使用API.graphql向GraphQL API发出请求,但是API类中有很多可用的方法。 您可以在官方文档中了解有关API类的更多信息 。

import { API } from 'aws-amplify'

// 1. in the initial state, create an empty array of people
state = { people: [] }

// 2. in componentDidMount, we will fetch this data using the API class
try {
  const peopleData = await API.get('amplifyrestapi', '/people')
  this.setState({ people: peopleData.people })
} catch (err) {
  console.log('error fetching from Lambda API')
}

// 3. render the people data to the UI in the render method
{
  this.state.people.map((person, index) => (
    

{person.name}

)) }

现在,我们应该能够运行该应用程序,从我们的API中获取人员数据,并将其呈现到屏幕上。

从CLI更新Lambda函数

除了创建新的Lambda函数外,我们还可以从CLI更新我们的Lambda函数。

让我们更改函数以访问API并获取数据,而不是硬编码常量。 为此,我们将使用axios库发出HTTP请求,并从Star Wars API中获取数据。

要使用axios,我们需要导航到放大/后端/功能/ amplifyrestapi / src   并安装在那里 Axios安装在Lambda函数的项目文件夹中,而不是安装在主应用程序文件夹中,因为它将在Lambda函数服务器端运行。

yarn add axios

# or

npm install axios

现在已经安装了axios ,我们将更新Lambda函数以从Star Wars API中获取数据:

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
      })
    })
});

现在,保存文件并从主项目文件夹运行amplify push以在云中更新Lambda函数:

amplify push

现在,我们的API已更新,随时可以使用!

刷新应用程序后,现在应该可以看到《星际大战》 API返回的数据。

结论

在本系列中,您学习了如何开始使用AWS Amplify并将其添加到React项目中,以及如何添加身份验证,存储,托管以及GraphQL或REST API-所有这些都无需手动编写代码或配置服务器。 对于应用程序开发人员来说,这是巨大的力量!

我希望这些帖子能启发您使用无服务器技术和AWS Amplify构建自己的无服务器Web应用程序! 在下面的评论中让我们知道您的想法。

翻译自: https://code.tutsplus.com/tutorials/how-to-build-serverless-graphql-and-rest-apis-using-aws-amplify--cms-31873

你可能感兴趣的:(如何使用AWS Amplify构建无服务器GraphQL和REST API)