我想创建并使用slug url,以通过AWS Amplify与在Appsync和DynamoDB之上构建的博客网站一起使用。子弹是文章标题和提示的组合;例如/article/an-interesting-post-on-bats-123abc
将返回标题为“蝙蝠有趣的帖子”的帖子。这将是相对简单的,但有一些限制:
Article
实体数据具有一定的可延展性,因为用户可以更改文章的标题,文本等。标题的更改可能会保证对条目的更改。实际上,用户无需输入标题就可以保存Article
,因此,该条不能成为主键的基础(因为创建项是必需的)。很显然,对于主键来说,该子弹本身是一个糟糕的选择;但是,段是当前可用于创建查询的唯一输入(作为路径参数)。 鉴于这些限制,如果我只有the子,查询Article
的最有效方法是什么?
在这一点上,我在设计阶段就足够早了,可以修改几个资源:(1)文章的网址,(2)DynamoDB设计(即主键和排序键是什么);和(3)Appsync模式。
当前,Article
模式包含:
type Article @model {
id: ID! // the primary key
authorId: String
title: String
text: String
slug: String
}
尽管可以扫描子弹,但这似乎是将Dynamo用作常规访问模式的一种无效方法。我曾经想过要用{来作为主键,将authorId
用作排序键或局部二级索引。这似乎与Medium和StackOverflow创建帖子网址的方式类似。
答案 0 :(得分:0)
您可以在slug属性上创建secondary index。然后,您将必须使用dynamoDB查询操作创建另一个GraphQL查询及其相应的解析程序。查询远比扫描有效。
为此,您有两个选择。在第一个中,您可以遵循查询操作的设计并返回文章列表,而不是单个文章。这可以使用connectionModels或简单地返回列表的类型来实现。
例如
## Schema
type ArticleConnection{
items: [Article]
}
type Query {
getArticle(id: ID!): Article
getArticleBySlug(slug: String): ArticleConnection // Query on secundary index
}
## Resolver
## Request Mapping Template
{
"version": "2017-02-28",
"operation": "Query",
"scanIndexForward": true,
"index" : "slug",
"select" : "ALL_ATTRIBUTES",
"query" : {
"expression" : "slug = :slug",
"expressionValues" : {
":slug" : $util.dynamodb.toDynamoDBJson("${ctx.args.slug}")
}
}
}
## Response Mapping Template
$util.toJson($ctx.result)
或者如果您想与第一个查询保持一致,则可以执行以下操作
## Schema
type Query {
getArticle(id: ID!): Article
getArticleBySlug(slug: String): Article // Query on secundary index
}
## Resolver
## Request Mapping Template
{
"version": "2017-02-28",
"operation": "Query",
"scanIndexForward": true,
"index" : "slug",
"select" : "ALL_ATTRIBUTES",
"query" : {
"expression" : "slug = :slug",
"expressionValues" : {
":slug" : $util.dynamodb.toDynamoDBJson("${ctx.args.slug}")
}
}
}
## Response Mapping Template
#if($ctx.result.items.size() > 0)
$util.toJson($ctx.result.items[0])
#else
null
#end