Bloggerのトップレベルドメインが変わってアクセス解析できていなかったという恨みごと

もともとBloggerではトップレベルドメインが、comからjpへリダイレクトされていたようですが、それがされなくなって、逆にjpからcomへ転送されるようになっていました。

おかげで、jpで登録していた Google Analytics や Google Search Console に、データが上がらなくなっていたって話です。

このブログ、ここ半年ぐらい放置していて、先日からボチボチ更新してるのですが、相変わらず アクセスほぼ0。まあそんなものだろうと半ば不貞腐れてはいたのだが、、、

しかしBloggerのダッシュボードで確認できるアクセス数はもうちょっと多い。しかしロボットを数えているにしては数が少ない気がした。

さらに Google Search Console で「なんかおかしい」的なことが表示されていて、さすがにやっぱり何かおかしいのだろうと本腰入れての調査の結果、、、

「なんだ登録しているURLが違ってるやん責任者出てこい」ということに(責任者は自分だろうか?)。

いつからこうなったのか不明です。

API Gatewayのレスポンスボディを非同期Lambdaから返却する

AWS Lambdaで Node.js v8.10(LTS)が使用できるようになっており、Lambdaを新規作成すると、exports.handler が async関数になっています。

API Gatewayからこの最新のAsync な Lambda を呼んでいる場合、returnでobjectを返してやれば、HTTPレスポンスボディとなるようですね。

Node.js v8.10 でのAPI Gateway Lambda スケルトン:

exports.handler = async (event) => {
    var response = {
     param: event, err: null, data: null, };
    try {
        response.data = await foo(event);
    } catch (err) {
        response.err = err;
    }
    return response;//これがレスポンスボディ
};

v6.10の時は、ハンドラーに渡されるcallbackを呼び出していたのですが、もしかしてPromiseを解決した値がレスポンスボディになっていたのか?今更だけど。

exports.handler = (event, context, callback) => {
    var response = {
     param: event, err: null, data: null, };
    foo(event).then( data => {
     response.data = data;
        callback(null, response);
    }).catch( err => {
     response.err = err;
        callback(null, response);
    });
};

AWS S3のバケットからテキストファイルを取り出そうとしてハマった件

AWSのS3の getObject APIで取り出したファイルの内容は、
Bufferクラスのインスタンスとして response.Bodyに収められているので、テキストファイルの中身を文字列として得たいなら、以下のようにすれば一発です。
let text = response.Body.toString("utf-8");
API叩くところも含めると以下のようになる。
"use strict";
const AWS = require("aws-sdk");
const S3 = new AWS.S3();
function S3_getObject(bucket, key) {
    return new Promise( (resolve, reject) => {
        S3.getObject(
            {Bucket: bucket, Key: key },
            (err, response) => {
                if(err) { reject(err); }
                else { resolve(response); }
            }
        );
    });
}
(async ()=> {
    let response = await S3_getObject("mybucket", "foo.json");
    let text = response.Body.toString("utf-8");
    console.log(text);
})();
しかし初めてのS3だったので、変換前に response.BodyをJSON.stringifyで確認すると、{"type":"Buffer", "data":[ ... ]} などと表示され、「なるほど data に生の配列として入ってるのね」と思ってしまい、Buffer.from(response.Body.data) とやってエラーになった。「コンストラクタの第一引数は文字列じゃないと・・・」みたいなエラー。「わけわからん」と response.Body.data を確認すると、なぜかこれが undefinedになっている(上ではJson的にキーがあると表示されているのに)。
いまだに、どうしてこうなるのか理解できないままでいる。
まあ、本質的には「APIの仕様をきちんと把握してから挑みましょう」ということなのだが。
以下、確認コードも含めて再掲(前半部分は端折ってある):
(async ()=> {
    let response = await S3_getObject("mybucket", "foo.json");
    console.log(JSON.stringify(response.Body));
        // ↑ {"type":"Buffer", "data":[ ... ]}
        // などと表示される
    console.log(JSON.stringify(response.Body.type));
        // ↑ undefined なんで?
    console.log(JSON.stringify(response.Body.data));
        // ↑ undefined なんで?
    let textFail = Buffer.from(response.Body.data);
        // ↑ Error undefindから構築できない。 
    let text = response.Body.toString("utf-8");
        // ↑ これが正解
    console.log(JSON.strngify(JSON.parse(text)));
})();

DynamoDBのセット型 BS/SS/NS について

DynamoDBのデータ型のうち「セット型」と呼ばれる特殊な型、 SSNSBS について書いています。

どれも特定の型のデータを複数要素保持できる型。
型名の1文字目が要素の型を表していて、2文字目は “Set” ですね。

DynamoDBのセット型:

  • SS - String Set : 文字列セット (*1)
  • NS - Number Set : 数値セット
  • BS - Binary Set : バイナリセット

(*1) AWS公式日本語ドキュメントでは文字セットとなっていますが、誤解しそうなので「文字列セット」としておきます。

セット型は以下のような特徴をもつ特殊な型です。

  • 複数の要素を保持できる。
  • 要素の型を限定する。
  • 要素の順序は保証されない。
  • 要素の重複は許されない

DynamoDBのAPIのパラメータやレスポンスでは、これらの型のデータは、配列として記述されます。

そのため、私は単に型限定された配列だと思いこんでいたのですが、間違いでした。ユニットテストを書いて気が付いた。テストは偉大。