GitHub ActionsとGitHub PagesでつくるWeb API(郵便番号検索)
GitHubが値下げと無料の「Free」プランの拡充を発表しました。昨年はCI/CD機能であるGitHub Actionsをリリースしたり、GitHub Pages(静的サイトホスティング)やPackages(パッケージホスティング)、Projects(プロジェクト管理)などがすでにあり、機能がどんどん充実していきます。
アプリケーションを動かすことはまだできないのですが、GitHub Actionsでプログラムを動かせるようになったので、GitHub Pagesと組み合わせれば、簡単なWeb APIもできます。
さっそく郵便番号から住所を返すAPIを作ってみます。
- GitHubが無料の「Free」プランを拡充
- GitHubだけでWeb API
- 郵便番号検索API
- GitHub Pages
- 郵便番号データ作成プログラム
- GitHub Actions
- APIの確認
- まとめ
GitHubが無料の「Free」プランを拡充
GitHubは2020年4月14日に値下げを行い、無料の「Free」プランを拡充してくれました。
github.blog
個人だけでなく組織でも、無制限のプライベートリポジトリと無制限のコラボレーターが無料で使えるようになったのです。
GitHubは今やgitレポジトリだけでなく、静的サイトのホスティング(GitHub Pages)やCI/CD(GitHub Actions)もついていて、進化が止まりませんね。他のgitレポジトリサービスはどんどん差がついてきついんじゃないかと思われます。
Free Plan
https://github.com/pricing
- Unlimited public/private repositories
- Unlimited collaborators
- 2,000 Actions minutes/month(Free for public repositories)
- 500MB of GitHub Packages storage(Free for public repositories)
- Community Support
GitHubだけでWeb API
GitHubにはGitHub Pagesという静的サイトのホスティングサービスはありますが、herokuやfirebase、GAEのようなアプリケーションプラットフォーム(PaaS)は用意されていません。
ちょっとしたWeb APIをGitHubでつくれるようになるといいなと思います。
Web APIはデータベースから(検索して)データを返すだけなので、gitレポジトリをデータベース代わりにして、APIをGitHub PagesでつくられるURLから提供すれば簡単なAPIを作ることはできます。
そして、今、GitHubにはGitHub Actionsがあります。GitHub Actionsはリクエストに応じた実行こそできませんが、いろいろなタイミング(トリガー)でさまざまなプログラムを実行することができます。そのタイミングでデータを更新する(データを取得してレポジトリにコミット/プッシュ)くらいはできてしまいます。これを利用して、最新のデータを維持したWeb APIを作ってみましょう。
郵便番号検索API
郵便番号から住所を表示するというよくあるアレです。
↓
mizumotok.github.io
〒100-0001は皇居がある住所(東京都千代田区千代田)の郵便番号です。
/api/100/0001.json
こんなパスで、返すようにしてみます。
api/100/0001.json
ファイルをGitHub Pagesで表示できるところに置くだけです。
郵便番号データは郵便局のウェブサイトからCSV形式でダウンロードできます。このデータをGitHub Actionsで定期的にダウンロードして、json形式に変換して、然るべき場所に保存して、レポジトリにプッシュすればいいわけです。
GitHub Pages
GitHub Pagesは「gh-pages」ブランチ、「master」ブランチ、または「master」ブランチの「docs」ディレクトリのいずれかに静的コンテンツをおくことで、表示することができます。
help.github.com
今回は「master」ブランチ上でデータ作成プログラムをつくって、そこのdocsディレクトリにjsonデータを保存するようにしてみました。
GitHub Pagesはトップページにindex.htmlがないとGitHub Pagesとして認識されないようなので、index.htmlは作っておく必要があります。
せっかくGitHub Pagesをつくるので、Jekyllという静的サイトジェネレータを使ってつくると、それっぽいトップページがちゃちゃっとできます。
help.github.com
もちろんJelyllなしでindex.htmlを作るのもOK。
docsディレクトリはこんな感じになります。
zipcode/docs at master · mizumotok/zipcode · GitHub
郵便番号データ作成プログラム
api/100/0001.json
のようなファイルを郵便番号の数(全国12万件)だけつくります。
処理の流れ
- 郵便局のウェブサイトからファイルをダウンロード
- zip形式なので、zipファイルの中からファイルを取り出す
- 文字コードはshift-jisなので、utf-8に変換
- CSVをパース
- 1行ずつjsonに変換してファイルに保存
という流れになります。
データをダウンロードするプログラム
export default async function updateJsonData() { const res = await fetch('https://www.post.japanpost.jp/zipcode/dl/kogaki/zip/ken_all.zip'); const buffer = await res.buffer(); const zip = await JSZip.loadAsync(buffer); const fileName = Object.keys(zip.files)[0]; const converterStream = iconv.decodeStream('shift_jis'); zip.file(fileName).nodeStream().pipe(converterStream) .pipe(csv({ headers: false })) .on('data', (data) => createFile(data)); }
ファイルを保存するプログラム
function createFile(data: string[]) { try { const dir = data[2].slice(0, 3); const file = data[2].slice(3); if (dir.length !== 3 || file.length !== 4) { console.log(`unknown postal code: ${data[2]}`); return; } fs.mkdirSync(`docs/api/${dir}`, { recursive: true }); fs.writeFileSync( `docs/api/${dir}/${file}.json`, JSON.stringify({ local_government_code: data[0], zip_code: data[2], address: [data[6], data[7], data[8]], address_kana: [data[3], data[4], data[5]] }), ); } catch (err) { console.log(err); } }
GitHub Actions
郵便番号データ作成プログラムをGitHub Actions上で実行させます。
GitHub Actionsをトリガーするイベント
GitHub Actionsをトリガーするイベントは3つあります。
今回はデータの更新は頻繁には必要ないので、1ヶ月に1回程度スケジュールイベントを発生させれば十分でしょう。
webhookイベント
CI/CDでよく使われる、プッシュやプルリクエストで発生するイベントです。
developer.github.com
スケジュールしたイベント
特定の時刻に起動する、いわゆるcronです。記述もcronライクです。
# 15分ごとに実行する例 on: schedule: - cron: '*/15 * * * *'
外部イベント
GitHub API を使って、repository_dispatch
と呼ばれる webhook イベントをトリガーできます。GitHub外部から起動した場合に使います。
GitHub Actionsのつくりかた
.github/workflows
に、ワークフローのため .yml または .yaml ファイルを追加します。
仮想環境の準備
仮想環境にはUbuntu、Windows、MacOSがサポートされています。
仮想環境 | YAMLのワークフローラベル |
---|---|
Windows Server 2019 | windows-latest or windows-2019 |
Ubuntu 18.04 | ubuntu-latest またはubuntu-18.04 |
Ubuntu 16.04 | ubuntu-16.04 |
macOS Catalina 10.15 | macos-latest or macos-10.15 |
郵便番号データ作成プログラムはTypescriptで書いたので、Node.jsが実行できればよく、無難にUbuntu 18.04
にしておきます。
実行するアクション
仮想環境を指定したら、アクション(タスク)を実行順に記述します。
アクションは自分でプログラムを書いて、runコマンドで実行することができますが、GitHub Marketplaceで多くのアクションが公開されていて、それらを利用することもできます。
以下の順にアクションをつくれば完成です。
- レポジトリからチェックアウト(actions/checkout)
- Node.js環境の設定(actions/setup-node)
- npmパッケージのインストール(runコマンド)
- 郵便番号データ作成プログラムの実行(runコマンド)
- 作成されたデータをコミット(runコマンド)
- レポジトリにプッシュ(ad-m/github-push-action)
作成したワークフローファイル
name: update ZIP Code on: schedule: - cron: '5 20 7 * *' jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Use Node.js uses: actions/setup-node@v1 with: node-version: '12.x' - run: yarn install - name: Update ZIP Code run: yarn main - name: Commit files run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" git add ./docs/api/ git commit -m "Update data `date +%Y-%m-%d`" -a - name: Push changes uses: ad-m/github-push-action@master with: github_token: ${{ secrets.GITHUB_TOKEN }}