リンクを投稿できるだけのサイトを作ってみた

AWS Amplify, IT記事

aws amplify の勉強を兼ねてリンクを投稿できるだけのサイトを作ってみた。

https://techlink.d2iaia9h9jeav.amplifyapp.com/

ページ下のフォームから登録できる。

タグをクリックすると、タグ検索ができる。

開発録

createdAtでソート

amplify api では@keyをつけない場合、idがソートキーになる(っぽい。)

type LinkData @model{
  id: ID!
  createdAt: AWSDateTime
  updatedAT: AWSDateTime
}

上記はquery listLinkDatasを呼ぶと、特に作成された順などではなく、バラバラになって返ってきた。

そこでcreatedAtか、updataedAtでソートしたいとして、@keyを以下のように設定する。

type LinkData @model @key(fields:["id","createdAt"]){
  id: ID!
  createdAt: AWSDateTime
  updatedAT: AWSDateTime
}

こうすると、 たぶん先程のクエリでcreatedAtでソート指定をできると思う。しかし今度は、createdAt を createdAt! (non null) にしないとコンパイルできない、と言われる。

non nullになるということは、mutation createLinkDataで作る時に、わざわざcreatedAtを手づから設定することになる、面倒だ。

で、解決の1つとして、@searchableをつけてelasticsearchを使うと、createdAtのままで定義することができて、sortもできる。というのがある。

type LinkData @model @searchable {
  id: ID!
  title: String
  description: String
  url: AWSURL!
  tag: [String]
  createdAt: AWSDateTime
  updatedAT: AWSDateTime
}

クエリでsortを指定する。

import { listLinkDatas, searchLinkDatas } from "./graphql/queries";

      var value = {
        sort: {
          field: "createdAt",
          direction: "desc"
        },
        limit: 10
      };

     this.$Amplify.API.graphql({
        query: searchLinkDatas,
        variables: value
      })
        .then(a => {
          f(a);
        })
        .catch(e => {
           console.log(e)
        });

sort.fieldで指定している。

Elasticsearchの欠点

@searchableをつけると、Amazon Elasticsearch Serviceにテーブルを作り、search~ といったGraphQLクエリができるようになる。

今回はこれで一度、タグ検索っぽいものを作ってみた。

type LinkData @model @searchable {
  id: ID!
  title: String
  description: String
  url: AWSURL!
  tag: [String]
  createdAt: AWSDateTime
  updatedAT: AWSDateTime
}

@searchable 欠点があって、amplify mockがまだ対応していないのと、elasticsearchの料金がかかる(月3000円以上!環境を複数作ると更に増える)。

listクエリでフィルタリング

なのでtag検索をelasticsearchから、listのフィルタで書き換えた。

以下のようなtypeがある、tagが[String]になっている。

type LinkData @model {
  id: ID!
  title: String
  url: AWSURL!
  tag: [String]
  createdAt: AWSDateTime
}

以下のようなクエリで、[String]に検索できるようだ。

query MyQuery {
  listLinkDatas(filter: {tag: {contains: "aws"}}, limit: 10) {
    items {
      id
      tag
      title
      url
      createdAt
    }
  }
}

まだちょっと不便だが、とりあえずこれで。