构建 NodeJS 客户端应用程序 - AWS AppSync
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

构建 NodeJS 客户端应用程序

AWS AppSync 与 Apollo GraphQL 客户端集成以构建客户端应用程序。AWS 提供 Apollo 插件以实现离线支持、授权和订阅握手。本教程介绍如何在 Node.js 应用程序中直接使用 AWS AppSync 开发工具包以及 Apollo 客户端。

注意:对于 AWS Lambda 函数,请确保在您的 AppSync 客户端构造函数中设置 fetchPolicy: 'network-only' 以及 disableOffline: true

开始前的准备工作

本教程预期采用具有以下结构的 GraphQL 架构:

schema { query: Query mutation: Mutation subscription: Subscription } type Mutation { addPost(id: ID! author: String! title: String content: String url: String): Post! updatePost(id: ID! author: String! title: String content: String url: String ups: Int! downs: Int! expectedVersion: Int!): Post! deletePost(id: ID!): Post! } type Post { id: ID! author: String! title: String content: String url: String ups: Int downs: Int version: Int! } type Query { allPost: [Post] getPost(id: ID!): Post } type Subscription { newPost: Post @aws_subscribe(mutations:["addPost"]) }

此架构来自 DynamoDB 解析程序教程(添加了订阅)。为了遵循完整的流程,您可以选择先通览该教程。如果您想对 GraphQL 解析程序(如使用 DynamoDB 的解析程序)进行更多的自定义,请参阅解析程序映射模板参考

获取 GraphQL API 终端节点

创建 GraphQL API 后,您需要获取 API 终端节点 (URL),这样,您就可以在您的客户端应用程序中使用它。您可以通过以下方法之一获取 API 终端节点:

  • 在 AWS AppSync 控制台中,选择 Settings (设置)。API URL 显示在 API Details (API 详细信息) 部分中。

  • 运行以下 CLI 命令:

aws appsync get-graphql-api --api-id $GRAPHQL_API_ID

以下说明介绍如何使用 AWS_IAM 进行客户端授权。在控制台中,选择左侧的 Settings (设置),然后单击 AWS_IAM

创建客户端应用程序

创建一个新项目并使用 npm 对其进行初始化,同时接受默认值,如下所示:

mkdir appsync && cd appsync touch index.js aws-exports.js npm init

AWS AppSync 支持多种授权类型,您可以在安全中了解更多信息。我们建议使用 Amazon Cognito 联合身份或 Amazon Cognito 用户池中的短期凭证。作为示例,我们演示如何使用 IAM 密钥。您的 aws-exports 文件应类似以下内容:

"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var config = { AWS_ACCESS_KEY_ID: '', AWS_SECRET_ACCESS_KEY: '', HOST: 'URL.YOURREGION.amazonaws.com', REGION: 'YOURREGION', PATH: '/graphql', ENDPOINT: '', }; config.ENDPOINT = "https://" + config.HOST + config.PATH; exports.default = config;

编辑您的 package.json 依赖项文件,并确保它包含以下内容:

"dependencies": { "apollo-cache-inmemory": "^1.1.0", "apollo-client": "^2.0.3", "apollo-link": "^1.0.3", "apollo-link-http": "^1.2.0", "aws-sdk": "^2.141.0", "aws-appsync": "^1.0.0", "es6-promise": "^4.1.1", "graphql": "^0.11.7", "graphql-tag": "^2.5.0", "isomorphic-fetch": "^2.2.1", "ws": "^3.3.1" }

注意:您 _*必须*_ 使用 "ws": "^3.3.1",否则,您将收到 WebSocket 错误。另请注意,您不能在 AWS Lambda 函数中使用 WebSocket 功能,只能使用 GraphQL 查询和更改。

从命令行,运行以下命令:

npm install

现在,将以下代码添加到您的 index.js 文件:

注意:如果您要在 AWS Lambda 函数中使用此示例,必须取消注释并使用 client.query({ query: query, fetchPolicy: 'network-only' }) 语句。您还必须在 AppSync 客户端构造函数中取消注释 disableOffline: true

"use strict"; /** * This shows how to use standard Apollo client on Node.js */ global.WebSocket = require('ws'); require('es6-promise').polyfill(); require('isomorphic-fetch'); // Require exports file with endpoint and auth info const aws_exports = require('./aws-exports').default; // Require AppSync module const AUTH_TYPE = require('aws-appsync/lib/link/auth-link').AUTH_TYPE; const AWSAppSyncClient = require('aws-appsync').default; const url = aws_exports.ENDPOINT; const region = aws_exports.REGION; const type = AUTH_TYPE.AWS_IAM; // If you want to use API key-based auth const apiKey = 'xxxxxxxxx'; // If you want to use a jwtToken from Amazon Cognito identity: const jwtToken = 'xxxxxxxx'; // If you want to use AWS... const AWS = require('aws-sdk'); AWS.config.update({ region: aws_exports.REGION, credentials: new AWS.Credentials({ accessKeyId: aws_exports.AWS_ACCESS_KEY_ID, secretAccessKey: aws_exports.AWS_SECRET_ACCESS_KEY }) }); const credentials = AWS.config.credentials; // Import gql helper and craft a GraphQL query const gql = require('graphql-tag'); const query = gql(` query AllPosts { allPost { __typename id title content author version } }`); // Set up a subscription query const subquery = gql(` subscription NewPostSub { newPost { __typename id title author version } }`); // Set up Apollo client const client = new AWSAppSyncClient({ url: url, region: region, auth: { type: type, credentials: credentials, } //disableOffline: true //Uncomment for AWS Lambda }); client.hydrated().then(function (client) { //Now run a query client.query({ query: query }) //client.query({ query: query, fetchPolicy: 'network-only' }) //Uncomment for AWS Lambda .then(function logData(data) { console.log('results of query: ', data); }) .catch(console.error); //Now subscribe to results const observable = client.subscribe({ query: subquery }); const realtimeResults = function realtimeResults(data) { console.log('realtime data: ', data); }; observable.subscribe({ next: realtimeResults, complete: console.log, error: console.log, }); });

在上面的示例中,如果您想要使用 API 密钥或 Amazon Cognito 用户池,您可以如下所示更新 AUTH_TYPE

const type = AUTH_TYPE.API_KEY const type = AUTH_TYPE.AMAZON_COGNITO_USER_POOLS

您需要根据情况提供密钥或 JWT 令牌。