使用 Amazon Neptune 图形数据库和 CDK 在 AWS 上构建 GraphQL API
本教程的视频也可在 YouTube 上观看
在GraphQL 和图形数据库中,Paul Wilton概述了将图形数据库与 GraphQL 相结合的好处,以及如何将 GraphQL 模式与描述图形数据库所表示的图形中的数据的相同本体模型对齐。
Willian Lyon也倡导Grand Stack的理念,它将 React 和 Apollo 等技术与 GraphQL 和 Neo4j 图形数据库相结合。
作为一名 AWS 用户,我对如何利用由图数据库支持的 AppSync GraphQL API 非常感兴趣。市面上有很多不错的选择,包括Neo4j和ArangoDB等,我希望很快也能尝试一下,但这次构建我选择了Amazon Neptune。
Neptune 是一项完全托管的图形数据库服务,可让您轻松构建和运行处理高度互联数据集的应用程序。Amazon Neptune 的核心是一个专门构建的高性能图形数据库引擎,经过优化,可存储数十亿个关系并以毫秒级延迟进行图形查询。
在本教程中,我将介绍如何使用 AWS CDK、AWS AppSync 和 AWS Lambda 构建由 Neptune 支持的 AppSync GraphQL API。
我们将使用 AWS Lambda 直接解析器来编写 API 的业务逻辑,该 API 将使用gremlin通过 Websockets 与 Amazon Neptune 进行交互
该项目的代码位于此处
先决条件
- AWS 账户
- 在本地机器上配置的 CDK
入门
首先,我们将使用 CDK CLI 初始化一个新项目。为此,请创建一个新的空文件夹,并使用 TypeScript 初始化一个新的 CDK 项目:
cdk init --language=typescript
接下来,打开tsconfig.json并设置noImplicitAny
为 false:
"noImplicitAny": false,
现在让我们使用 npm 或 yarn 安装创建基础设施所需的依赖项:
yarn add @aws-cdk/aws-appsync @aws-cdk/aws-lambda @aws-cdk/aws-ec2 @aws-cdk/aws-neptune
接下来,我们将在lib/your-project-name-stack.ts文件中创建我们的堆栈。
首先导入我们将要使用的 CDK 类和构造:
// lib/your-project-name-stack.ts
import * as cdk from '@aws-cdk/core'
import * as appsync from '@aws-cdk/aws-appsync'
import * as lambda from '@aws-cdk/aws-lambda'
import * as ec2 from '@aws-cdk/aws-ec2'
import * as neptune from '@aws-cdk/aws-neptune'
注意 - 我们仅导入
ec2
以创建一个 VPC,我们将在其中放置我们的功能以及我们的 Neptune 实例。
创建 GraphQL API
现在让我们创建 GraphQL API。为此,请将以下代码行添加到堆栈中,位于 调用下方super
:
const api = new appsync.GraphqlApi(this, 'Api', {
name: 'NeptuneAPI',
schema: appsync.Schema.fromAsset('graphql/schema.graphql'),
authorizationConfig: {
defaultAuthorization: {
authorizationType: appsync.AuthorizationType.API_KEY
},
},
})
在这里,我们创建了一个名为的 API并设置了一些基本配置,包括位于graphql/schema.graphqlNeptuneAPI
的 GraphQL 模式的位置。
接下来,继续在根目录创建一个名为graphql的新文件夹,并在其中添加一个名为schema.graphql的文件。在这里,添加以下架构:
type Post {
id: ID!
title: String!
content: String!
}
input PostInput {
title: String!
content: String!
}
type Query {
listPosts: [Post]
}
type Mutation {
createPost(post: PostInput!): Post
}
type Subscription {
onCreatePost: Post
@aws_subscribe(mutations: ["createPost"])
}
该 API 将是一个非常基本的博客 API,允许我们创建和查询帖子。
Lambda 和 VPC
接下来,在 API 代码下方创建 VPC 和 Lambda 函数:
const vpc = new ec2.Vpc(this, 'NeptuneVPC')
const lambdaFn = new lambda.Function(this, 'Lambda Function', {
runtime: lambda.Runtime.NODEJS_14_X,
handler: 'main.handler',
code: lambda.Code.fromAsset('lambda-fns'),
memorySize: 1024,
vpc
})
我们围绕 Lambda 设置了一些基本配置,包括运行时、内存大小以及入口代码(lambda-fns)和处理程序(main)的位置。
接下来,我们将 Lambda 函数作为数据源添加到 AppSync API,并为我们在 GraphQL 架构中定义的查询和变异创建解析器。在 Lambda 函数定义下方添加以下代码:
const lambdaDs = api.addLambdaDataSource('lambdaDatasource', lambdaFn);
lambdaDs.createResolver({
typeName: "Query",
fieldName: "listPosts"
})
lambdaDs.createResolver({
typeName: "Mutation",
fieldName: "createPost"
})
创建 Neptune 数据库
最后一步是创建 Neptune 数据库。我们还将获取对读写端点的引用,使其可用作环境变量,以便我们在 Lambda 函数中引用它们:
const cluster = new neptune.DatabaseCluster(this, 'NeptuneCluster', {
vpc,
instanceType: neptune.InstanceType.R5_LARGE
})
cluster.connections.allowDefaultPortFromAnyIpv4('Open to the world')
const writeAddress = cluster.clusterEndpoint.socketAddress;
const readAddress = cluster.clusterReadEndpoint.socketAddress
lambdaFn.addEnvironment('WRITER', writeAddress)
lambdaFn.addEnvironment('READER', readAddress)
// The next two lines are not required, they just log out the endpoints to your terminal for reference
new cdk.CfnOutput(this, 'readaddress', {
value: readAddress
})
new cdk.CfnOutput(this, 'writeaddress', {
value: writeAddress
})
添加 Lambda 函数代码
当我们创建 Lambda 函数时,我们引用了位于lambda-fns目录中的代码,但我们还没有编写该代码。
首先,创建目录,初始化新的package.json文件,然后安装gremlin。
mkdir lambda-fns
cd lambda-fns
npm init --y
yarn add gremlin
cd ..
接下来在lambda-fns目录中创建以下 4 个文件:
- Post.ts
- 主目录
- createPost.ts
- 列表帖子.ts
让我们为每个文件创建代码:
Post.ts
type Post = {
id: string;
title: string;
content: string;
}
export default Post
createPost.ts
const gremlin = require('gremlin')
import Post from './Post'
const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection
const Graph = gremlin.structure.Graph
const uri = process.env.WRITER
async function createPost(post: Post) {
let dc = new DriverRemoteConnection(`wss://${uri}/gremlin`, {})
const graph = new Graph()
const g = graph.traversal().withRemote(dc)
const data = await g.addV('posts').property('title',post.title).property('content', post.content).next()
post.id = data.value.id
dc.close()
return post
}
export default createPost
列表帖子.ts
const gremlin = require('gremlin')
const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection
const Graph = gremlin.structure.Graph
const uri = process.env.READER
const listPosts = async () => {
let dc = new DriverRemoteConnection(`wss://${uri}/gremlin`, {})
const graph = new Graph()
const g = graph.traversal().withRemote(dc)
try {
let data = await g.V().hasLabel('posts').toList()
let posts = Array()
for (const v of data) {
const _properties = await g.V(v.id).properties().toList()
let post = _properties.reduce((acc, next) => {
acc[next.label] = next.value
return acc
}, {})
post.id = v.id
posts.push(post)
}
dc.close()
return posts
} catch (err) {
console.log('ERROR', err)
return null
}
}
export default listPosts
主目录
import createPost from './createPost';
import listPosts from './listPosts';
import Post from './Post';
type AppSyncEvent = {
info: {
fieldName: string
},
arguments: {
post: Post
}
}
exports.handler = async (event:AppSyncEvent) => {
switch (event.info.fieldName) {
case "createPost":
return await createPost(event.arguments.post);
case "listPosts":
return await listPosts();
default:
return null;
}
}
在main.ts中,我们切换event.info.fieldname
触发函数的 GraphQL 查询或变异,并根据字段名称调用函数。
部署和测试
现在我们已经完成了代码编写,可以部署并测试了。为此,请运行构建,然后部署:
npm run build && cdk deploy
部署完成后,您应该可以进行测试。为此,请访问AppSync 控制台,然后单击左侧菜单中的“查询” 。
执行以下查询来创建并查询来自 Neptune 的数据:
query listPosts {
listPosts {
id
title
content
}
}
mutation createPost {
createPost(post: {
content:"Hello world"
title: "My first post!!"
}) {
id
title
content
}
}
结论
本介绍绝不是深入探讨或指导如何查询和遍历 Neptune 或如何正确处理图形数据库中的数据,而是向您展示如何将所有部分组合在一起以设置基础设施和 API,这样您就可以开始使用这个堆栈。
为了了解更多信息,我将深入研究 gremlin、Neptune 的文档以及如何正确使用图形数据库的一般指南。
鏂囩珷鏉ユ簮锛�https://dev.to/dabit3/building-a-graphql-api-on-aws-with-amazon-neptune-graph-database-and-cdk-428a该项目的代码位于此处