集中したい

最近全然時間がありません
打ち合わせや割り込みがない時間が1日のうちで連続3時間ほしい...

今日の作業

10:00-10:30 ★FREE
10:30-11:30 MTG
13:00-14:00 MTG
14:00-15:00 ★FREE
15:00-16:00 ペア作業
16:00-17:00 MTG
17:00-18:00 ★FREE

こんなんじゃ集中して作業できねぇよ

TRY: 打ち合わせを15時までにする

15時以降をフリーにする

jsのクラスってコンストラクタに全部書いた方がよくね?

jsのクラスはこんな感じで書きます

class Position {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  getX() {
    return this.x;
  }

  getY() {
    return this.y;
  }

  getDistance() {
    return Math.sqrt(this.x * this.x + this.y * this.y);
  }
}

この書き方の辛いところ

  • フィールドをprivateにできないからxとyが外から丸見え。セッター呼び放題
  • フィールドが増えるたびにthis.v = v;をコンストラクタに書く必要がある

それならこっちの方がよくね?

class Position {
  constructor(x, y) {
    this.getX = () => x;
    this.getY = () => y;
    this.getDistance = () => Math.sqrt(x * x + y * y);
  }
}

辛いところは全部解消されてる

しかもコンストラクタ引数をconstな変数に入れたらimmutableにもできる

class ImmutablePosition {
  constructor(_x, _y) {
    const x = _x, y = _y;
    this.getX = () => x;
    this.getY = () => y;
    this.getDistance = () => Math.sqrt(x * x + y * y);
  }
}

どや

マルっとサクッとパラメータを受け取る

最近PHP+slimでAPIをたくさん作ってますがAPIの実装が面倒になってきた
たとえばアクセストークンを使って認証的なことをやろうとした場合、IF仕様はこうなる

アクセストークンは、リクエストヘッダー、または、GETの場合はクエリーパラメータ、または、POSTの場合はbodyに入れること

いろんなところから取得しなきゃでめんどくせーー

欲しいのはパラメータ

で、欲しいのはそのパラメータであって、それがヘッダーだろうとなんだろうと別にどうでもいい
なのでパラメータの取得方法を考えなくてもよくするミドルウェアを作った

$app->add(function ($request, $response, $next) {
  $params = [];
  forEach($request->getHeaders() as $key => $value) {
    $params[$key] = $value;
  }
  if($request->getQueryParams() != null) {
    forEach($request->getQueryParams() as $key => $value) {
      $params[$key] = $value;
    }
  }
  if($request->getParsedBody() != null) {
    forEach($request->getParsedBody() as $key => $value) {
      $params[$key] = $value;
    }
  }
  
  $request = $request->withAttribute('params', $params);
  return $next($request, $response);
});

取得するときはこんな感じ

$params = $request->getAttribute('params');

APIの実装が楽になった
めでたし、めでたし

データを保存できるWebAPIを作ったら楽になった

最近は無料で使えるナントカ as a serviceが増えてきて、サービスを簡単に作れるようになって楽しい
例えばロジックはheroku + javaで堅牢に作れるし、定期実行はgoogle apps script(以下、GAS)でできる
あと足りないのはデータストア

てことで自分の身の回りでデータストアとして使えそうなものを探したら、サクラのレンタルサーバがあった!
プランがライトプランなのでsqliteしか使えないけど、なんとかなるはず!
てことで、データストア的なwebサービスを作ってみた

仕様

要するにwebAPI経由でデータの追加・更新・参照ができるサービスです
詳細はこんな感じ

  • IDと状態を保存できる
  • 状態を更新できる
  • ID指定で状態を取得できる
  • 過去の状態遷移履歴も取れる
  • データは投入から1ヶ月で消える
  • 認証はリクエストに固定のトークンを入れることで行う
  • 環境: PHP + slim + SQLite

データが1ヶ月で消える仕様がミソ
sqliteだから大量データを保持したくないって理由もあるけど、実際1ヶ月くらい保持してくれるだけで十分なサービスがたくさんあるのでこの仕様で問題なし

利用例:ブログ更新通知サービス

せっかくなのでデータストアを使ったブログ更新通知サービスを作ってみた
使うのはGAS

基本的に定期的にRSSをクロールしてチャットに通知すればイイだけですが、すでに通知済みの記事は通知して欲しくない
そうなると通知したものを貯めるデータストアが必要になる
そこで今回作ったデータストアを使う
通知した記事のIDをデータストアに保存して、次回クロール時はデータストアにすでにあるかを確認してなかったら通知する
1ヶ月でデータが消える仕様があるので、翌月に同じ記事を通知してしまう可能性はあるけど、そこは日付見て「1ヶ月以上たった記事は通知しない」て処理いれれば問題なし

ロジックをまとめるとこんな感じ

  • 定期的にRSSを取得する
  • 記事の投稿日時が1ヶ月以内のものを抽出する
  • 記事IDでデータストアに問い合わせてチャットに通知済みかどうかをチェックする
  • 未通知だったら
    • 記事をチャットに通知する
    • データストアに通知済みとして保存

作った

GASで簡単に作れた
このデータストアは汎用的に使えて良さそう
APIのインターフェースとか認証周りとかをもう少し整理して公開できる状態まで持っていきたい
認証サービスを作ればいいのか?
結局AWSみたいにマイクロサービスがたくさん作られそうな予感

まとめ

データストアサービスを作ったら新たなサービス作りが簡単になった
この他にもマイクロサービスのアイデアがいくつか浮かんで楽しくなってきた

PHPで1970年からのミリ秒を取得する

サーバサイドをPHP + SQLiteにしてフロントをjavascriptで作るなら、日時はlong型で1970年からのミリ秒にしておいた方が良さそう でもPHPの標準関数でその値を取得する方法がなかったのでメモ 使えそうなものが2つ見つかった

現在日時から取得

$t = (int)floor(microtime(true) * 1000);

リクエスト日時から取得

$t2 = (int)floor($_SERVER['REQUEST_TIME_FLOAT'] * 1000);

【問題】ゼロ埋め

入力エリアのTODOの部分にプログラムを書いて、下記にある入力に対する出力条件を満たすようにしなさい

入力に対する出力条件

入力a 入力b 出力(return)
3 1 '3'
4 2 '04'
5 3 '005'
65 3 '065'
765 2 '65'

テスト項目

assert('テスト0', zerofill(3, 1) === '3');
assert('テスト1', zerofill(4, 2) === '04');
assert('テスト2', zerofill(5, 3) === '005');
assert('テスト3', zerofill(65, 3) === '065');
assert('テスト4', zerofill(765, 2) === '65');

確認

ボタンを押すと、プログラムが正解か不正解かがわかるよ

【問題】サイクルする数字

入力エリアのTODOの部分にプログラムを書いて、下記にある入力に対する出力条件を満たすようにしなさい

入力に対する出力条件

入力(num) 出力(return)
0 0
1 1
2 2
3 0
4 1
5 2
6 0
7 1
8 2

テスト項目

assert('チェック0', exec(0) === 0);
assert('チェック1', exec(1) === 1);
assert('チェック2', exec(2) === 2);
assert('チェック3', exec(3) === 0);
assert('チェック4', exec(4) === 1);
assert('チェック5', exec(5) === 2);
assert('チェック6', exec(6) === 0);
assert('チェック7', exec(7) === 1);
assert('チェック8', exec(8) === 2);

確認

ボタンを押すと、プログラムが正解か不正解かがわかるよ