LoginSignup
12
2

More than 1 year has passed since last update.

【クソアプリ】Amplifyで作る CGI風アクセスカウンター

Last updated at Posted at 2021-12-09

この記事は「クソアプリ Advent Calendar 2021 2」の10日目の記事です。

去年はこちらで参加しました。

概要

今年下半期はAmplifyに大変悩まされたので、復習も兼ねてシンプルなアプリを作ってみました。

image.png

動作サンプル
https://dev.d1nlszba0lmhed.amplifyapp.com/

ポイント

CGI風の呼び出し

  • ContentType: image/***のレスポンスを返すCGI風のエンドポイント
  • 最上位パスは無駄に/cgi-bin/
  • IMGタグで描画する懐かしのパターン
<div id="counterBox">
  <span>ようこそ。あなたは</span>
  <img src="https://ENDPOINT/cgi-bin/counter">
  <span>人目のお客様です</span>
</div>

キリ番機能

  • 下一桁が0の時ゾロ目の時はキリ番
  • キリ番の時はダサめの装飾付き画像(クリスマス風)に変わります
    • image.png
  • それ以外は通常デザイン
    • image.png

CGIカウンター風のデータ構造

  • 理想的には、1アクセス毎に「1」という1バイト文字列をテキストファイルに追記していき、テキストファイルのバイト数を調べることでカウントを得られるという例のアレがやりたい
  • S3とか使えばできるような気もしたが、今回はAmplifyということで無駄にDynamoDBを使っていく
  • アクセス毎に1レコードを無駄に追加していき、DynamoDBのAPIでテーブル全件カウントするという無茶な感じにしてみる

Amplifyで実装

amplifyコマンドで以下の構成を作っていきます。

resource type memo
backend/api/cgibin REST CGI風のエンドポイントを作るAPI Gateway
backend/api/kiricounter GraphQL カウントをするDBとDB操作用のAppSync
backend/function/counter Lambda CGI部分の実装
backend/function/appsync Lambda Layer aws-appsync等諸々のパッケージをLayer化
backend/hosting/amplify-hosting 動作サンプルサイト

ポイント

AppSync用のLambda Layer

  • 今回特に分ける必要もないが、今後実際に使うときには分けておいた方がよさそうなので練習がてら作ってみる
  • aws-appsyncgraphqlかどちらか忘れたが)最新版を入れすぎると動かなかったので現状動いたものをメモ
package.json
{
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "dependencies": {
    "aws-appsync": "^4.1.4",
    "aws-sdk": "^2.1030.0",
    "graphql": "^15.7.0",
    "graphql-tag": "^2.12.6",
    "isomorphic-fetch": "^3.0.0"
  },
  "devDependencies": {}
}

Lambda Layerを使う

  • amplify function update からそれっぽいものを選んでいくだけ。便利
  • メインのLambda自体の容量も小さくなるため、AWSのコンソールで直接編集もできるようになって便利

LambdaからAppSyncとDynamoDBを使う

  • amplify function updatepermission関係のところから同様に選んでいく
  • AppSyncはGraphQLのAPIを指定するとパーミッションが貰える
  • DynamoDBはstorageカテゴリに属している(わかりにくい)ため、そこから選んでいく
    • 使いたいDynamoDBテーブルをスペースで複数選択していく
    • 欲しいものだけ貰えて便利
  • パーミッションが貰えるとsrc/index.jsに環境変数が書き込まれる
  • 便利
backend/function/counter/src/index.js
/* Amplify Params - DO NOT EDIT
    API_KIRICOUNTER_COUNTERTABLE_ARN
    API_KIRICOUNTER_COUNTERTABLE_NAME
    API_KIRICOUNTER_GRAPHQLAPIENDPOINTOUTPUT
    API_KIRICOUNTER_GRAPHQLAPIIDOUTPUT
    ENV
    REGION
Amplify Params - DO NOT EDIT */

require('isomorphic-fetch')
const aws = require('aws-sdk')
const gql = require('graphql-tag')
const AWSAppSyncClient = require('aws-appsync').default
const { AUTH_TYPE } = require('aws-appsync')

const client = new AWSAppSyncClient({
  url: process.env['API_KIRICOUNTER_GRAPHQLAPIENDPOINTOUTPUT'],
  region: process.env['REGION'],
  auth: {
    type: AUTH_TYPE.AWS_IAM,
    credentials: ()=> aws.config.credentials
  },
  disableOffline: true
})

const incrementMutation = gql
  `mutation MyMutation {
    createCounter(input: {count: "1"}) {
      createdAt
    }
  }
  `

const increment = () => {
  return client.mutate(
    {
      mutation: incrementMutation
    }
  ).then((result) => {
    if (result) {
      // console.log('result', result)
      return result
    } else {
      Promise.reject('error. increment result is null')
    }
  }).catch(console.error)
}

const docmentClient = new aws.DynamoDB.DocumentClient()

const count = () => {
  const params = {
    TableName: process.env['API_KIRICOUNTER_COUNTERTABLE_NAME'],
    Select:'COUNT'
  };
  return docmentClient.scan(params).promise()
  .then((data) => {
    if (data) {
      console.log('count result', data)
      return data
    } else {
      Promise.reject('error. count result is null')
    }
  }).catch(console.error)
}

気を付けるポイント

  • amplify addで出来る設定はupdateでも大体やり直せる
    • 名前とかは無理そうだが、それ以外は何度でもやり直せるので気にせずガシガシやって大丈夫
  • amplify removeする時は依存関係から先に消す
    • 依存しているAuthやLayerやPermissionが残っている状態で消そうとすると泣きそうになるくらいのエラーになるので気を付ける
  • amplify pushするとデプロイした情報がローカルに保存される
    • team-provider-info.jsonなどに差分が出るため、忘れずにコミットする
    • 見やすさのため、pushで出た差分は作業のコミットとは分けてコミットしておく

終わり

いやー 便利ですね

12
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
2