AWS Lambdaではてなブログの記事をQiitaに自動転載した
コード
first commit · k-tokitoh/sync_entries@b05ed9e · GitHub
動機
- なんか個人開発したいな。
- 記事の転載を実現するには両方のサービスのAPIを適当に叩けばできそうだな。
- 定期実行させるにはスクリプトをAWS Lambdaにアップロードして適当に設定すればよさそうだな。
- やる内容がいまの自分のレベル感からしてちょうどよさそうだな(難し過ぎず遊びでできそうだし、簡単過ぎず学びもありそう)。
- AWS Lambdaもはてな/QiitaのAPIも触ったことないから、はじめてのものに触れてたのしそうだな。
- 基本的に好き勝手に書き散らかしたいのでブログに書くことにしているが、多少まとまった記事についてはQiitaにも投稿したら人の目につきそうでうれしいな。
とりあえずの仕様
学んだこと
net/http
はじめてさわった。便利だなあ…。
https通信
Net::HTTP.start(uri.host, use_ssl: true)
req = Net::HTTP::Get.new(uri) req.basic_auth(ENV['HATENA_ID'], ENV['HATENA_API_KEY'])
- アクセストークンをつかった認証
req = Net::HTTP::Get.new(uri) req["Authorization"] = "Bearer #{ENV['QIITA_ACCESS_TOKEN']}"
- getリクエストにパラメータを設定する
uri = URI.parse('https://qiita.com/api/v2/authenticated_user/items') params = {page: 1, per_page: 20} uri.query = URI.encode_www_form(params)
req = Net::HTTP::Post.new(uri) req["Content-Type"] = "application/json" req.body = { "key1": "value1", "key2": "value2", }.to_json
- keep-alive
xml
AWS Lambda
マネジメントコンソールで直書き or zipファイルのアップロードによりスクリプトを設定できる。
実行するメソッド(lambda)を
ファイル名.メソッド名
という形で1つだけ指定する。環境変数もつかえる。
ログもいい感じに出力してくれてハッピー。
その他技術面
- ループでは1回1回ローカル変数のスコープは破棄される。
3.times do p var # => 3回とも`undefined local variable or method `var'` var = 999 end
- zipファイルの作成
zip -r 作成するzipファイル名 圧縮対象とするファイルを抽出するためのパターン
具体的には以下。
zip -r sync_entries ./*
Dir#[*pattern]
でパターンマッチした文字列の配列が返ってくる。dotenv
require 'dotenv'
だとgemの読みこみだけ。require 'dotenv/load'
だとgemの読み込み+ルートディレクトリの.env
のロードまでしてくれる。
設計
拡張性と可読性について
- 書いてると、「こういうことがしたくなるかも、それに対応できるようにするにはどうしたらいいだろう」っていうのがいっぱいでてくる。
- でも例えば「引数を変えるだけで『今後したくなるかもなこと』が実現できる」ような実装はつくらなくていい。使わないオプションは使えるようにしなくていいのだ。
- 「現状で満たすべきことを実現する最低限のコードを」「可読性高く書く」ことだけに集中すればよく、それ以外のことをすべきではない。
- つまり、可読性さえ意識すれば、拡張(可能)性は自然とついてくる。
- 必要なのは拡張(可能)性のみであって、まだ使わない機能ならば実際に拡張すべきではない。
- 可読性高く書くとは、「重複がなく」「変数名が適切で」「クラスやメソッドの責務分担や粒度が適切で」あること。
- そして「そこで何をしているのかを理解するための適切なコメントがあること」。
- このテーゼに関して以下で2つの具体例をみる。
例1: 情報を変数にもたせるか、コメントで残すか
- はてなから取得した記事を要素とする配列の変数名を例に考える。
- 「記事である」という情報は必要なので、変数名はまずentriesをベースにしよう。
- はてなから取得した記事とQiitaから取得した記事を対照して扱う場面が発生しそうなので、「Qiitaではなくはてなの記事である」という情報も変数にもたせた方がよさそうだ。
- hatena_entriesにしよう。
- ちなみにこの配列は下書き記事を含まない予定である。
- しかしもしかすると、今後下書きを含めたい場面が生じるかもしれない。
- では今回の変数に格納された記事たちが下書きを除くものであるという情報を変数に入れるべきだろうか?
- つまり、変数名をhatena_entries_excluding_draftsにすべきだろうか。
- いや、これは2つの理由で必要ない。
- 現在「下書きを含む場合」と「下書きを含まない場合」の片方しかないので、両者を区別する必要がない
- 変数名が冗長である
- こういう理由があるときは、変数名ではなくてコメントに情報を残すのがよさそうだ。
例2: メソッドの切り出し
再び、拡張性と可読性について
- 「現状で満たすべきことを実現する最低限のコードを」「可読性高く書く」ことだけに集中すればよく、それ以外のことをすべきではない。
- そのように書きさえすれば、拡張が必要になったとき、「どこで何をしているかが突き止めやすいので」「どこを修正・追記すればよいのかがわかりやすくて」「修正・追記すべき箇所が少ない」、そのコードをいじればいいのだ。それだけだ。
開発方針
- アジャイル的な考え方を実践した。
あれこれやりたくなるけど、「まずは最低限これができたら公開/実行していいよな」というところを見極めて、まずそれをやる。
とりあえず不完全でも雑でもバグがあっても、
- 「ユーザーにとんでもない迷惑をかけて信用を損なう」とか
- 「中途半端なリリースをしたことで後で修復作業など余計なコストが大きくかかる」という場合を除いては、
とりあえず不完全でも雑でもバグがあっても、リリースしちまうのがいいことだ!
会社のプロダクトでも趣味の個人開発でも、「ユーザーに迷惑をかけて信用を損なう」ことをどれだけ重く受け止めるかが違うだけで、根本的な考え方は同じではないか。
という訳で改善したい箇所はいっぱいあるので気が向いたとき継続的にいじっていきたい。