Vue.jsでルーツ音楽診断ゲームを作ってみた

こんにちは。フロントエンドエンジニアの田渕です。
2015年4月に中途入社して早3年目です。
前職はWeb制作会社でディレクター兼マークアップエンジニアをしてました。

最近流行りのVue.jsを使ってちょっとした診断ゲームを作ったので紹介します。
まずは以下を実際に遊んでみてください。

ルーツ音楽診断

はい。趣味丸出しです。
ルーツ・ミュージックに興味を持ってくれる人が一人でも増えたらいいなと思います。

技術的な話

Vue.jsを使ったメリットは以下です。

  • ページ遷移を非同期でおこなえる
  • ページ遷移時にトランジション(アニメーション効果)をつけられる

Vue.jsでできることはまだまだありますが、Webサイトのページ遷移にちょっとした効果がついているだけでもそれっぽくなるかと思います。

実際に使ったものは以下です。

  • Vue.js(JavaScriptフレームワーク)
  • webpack(モジュールバンドラー)
  • pug(Node製テンプレートエンジン)
  • Sass(AltCSS)
  • babel(JavaScriptの次世代の標準機能のトランスパイル)
  • yarn(パッケージマネージャ)

パッケージは他にも使ってますが主要なものは大体こんな感じ。
現時点でのフロントエンド開発で比較的オーソドックスな組み合わせだと思います。
もちろん環境に合わせてそれぞれ違うものを導入するので、一例くらいに考えていただければと思います。

Vue.js

Vue.jsはページ単位、コンポーネント単位で管理できるので割りと気に入ってます。
pugとSassは効率的に書けて良い感じです。
babelは新規で作るなら使っていきたいですね。
Vue.jsのコンポーネントはこんな感じです。 GlobalHeader.vue

<template lang="pug">
  header.contentHeader.container
    p.contentHeader_title
      | ルーツ音楽診断
</template>
<style lang="scss">
.contentHeader {
  text-align: center;
  &_title {
    margin: 40px 0 70px;
    color: #fff;
    font-size: 38px;
    font-weight: bold;
    line-height: 1;
    text-shadow:
      -3px -3px 0 #222,
       3px -3px 0 #222,
      -3px 3px 0 #222,
       3px 3px 0 #222,
       4px 4px 0 #fff,
       5px 5px 0 #fff,
       6px 6px 0 #fff,
       7px 7px 0 #fff;
  }
}
</style>

vueファイルにHTML, CSS, JavaScriptをまとめて書けます。
今回はpugとSassを使うためlang属性で指定しています。
使いたいページや親コンポーネントにコンポーネントを入れることで、複数ページに同じようなコードが散乱することを回避できます。

Vue.jsを使うには大抵webpackを使うことになります。
webpackでいろんなファイルを一つにまとめます。vueファイルとかjsファイルとか。
Vue.jsを勉強していると思ったら、いつの間にかwebpackを勉強していた。な…何を言っているのかわからねーと思うが(ry
みたいな楽しいことになります。
元ネタがわからない人は「ありのまま今起こったこと」でぐぐってください。

トランスパイル言語

pug、Sass、babelはプロジェクトに合わせて選べば良いと思います。

  • Rubyでの開発だからpugではなくslim。
  • Node製で固めたいのでSassではなくStylus。
  • 型が欲しいのでbabelではなくTypeScript。

みたいな感じ。
実際の開発への導入だと、開発スピードやプロジェクトメンバー、好み等によって判断することが多いかと思います。
自分の周りの状況に合わせて勉強すると効率的ですね。

yarn

yarnはいいぞ。

さいごに

新しい技術や初めての技術に触れるのはとても楽しいですね。
今回一番テンション上がってたのは、コンテンツ内容を考えてる時でした。←
技術も楽しいですが企画も楽しいです。
いろんな技術を学んでいくことでエンジニアならではの企画を思いつくこともあると思います。
ただ技術を学ぶだけでなく、ぜひ何か新しいことができないか妄想しながら考えながら学んでみてください。

楽しくモノ作りしていきましょう。

SublimeText3 + PlantUML + Windowsで快適なモデリング!

こんにちは、飯野です。
主に社内ツールの開発を行う部署に所属している、アドウェイズ歴1年目のアプリエンジニアです。

昨年まではSIerで客先常駐という働き方をしていたので、エンドユーザに納品しない開発というものを弊社で初めて行っているのですが、まず驚いたことが。

設計書が無い。

Web系の会社でスクラム組んでいるチームだとこういった開発体制も相応にあると思います。
ごりごりのウォーターフォールに浸かっていた私にとっては、なかなか衝撃的なものです。

そんなこんなでNo設計書状態(コードが全てじゃ!)でチーム開発を行っていたのですが、とあるメンバーからこんな提案が。

I氏 「今のクラス設計、複雑で不透明なのでモデリングやってみたいんですけど。」

私 「いいですね、やっちゃってください!」

というわけで、最近抽象について考えまくっているI氏(通称:沼さん)に依頼してクラスのモデリング作業を行ってもらいました。

いやー、いいですね。モデリング。
私の開発チームはDDDを採用している所以もあり1機能に関わるクラス数が多いんですが、UMLがあることで、クラス同士の関連や依存関係が可視化できます。
構造の理解も進みますし、改善すべき点も見つけやすい(はず)です。
今回モデリングの土台が出来たことで、今後は実装前にモデリングを行う開発フローにしました。

ここからが本題なんですが、せっかくモデリング作業を行うなら、日頃から使用しているエディタで行いたいですよね?
私は開発にSublimeText3を使用しているので、今回は SublimeText3 + PlantUML + Windows の構成でモデリング作業を実践する環境を作ってみました。

動作環境

  • Windows7 Pro 64bit
  • SublimeText3 Build 3126

PlantUMLとは

テキストからダイアグラムを作図できるオープンソースのjava製ツールです。
対応しているUMLも多く、以下のような図がテキストでお手軽に作成できます。

  • シーケンス図
  • ユースケース図
  • クラス図
  • アクティビティ図
  • コンポーネント図
  • 状態遷移図
  • オブジェクト図

公式サイト

GUIで図を書かなくともテキストでUMLを表現できるため、バージョン管理しやすいという利点があります。
書き方さえマスターしてしまえば、チームでの共同作業も捗りますね。

セットアップ

前述の通り、PlantUMLはjavaで動作するので、javaが必要です。
「えっ、javaから入れるの、、」と億劫になってしまうそこのアナタ!(=私)
Chocolateyを使用してお手軽にインストールしてしまいましょう。

Chocolateyインストール

コマンドプロンプトを立ち上げ、公式サイトに掲載されているコマンドを実行します。

f:id:AdwaysEngineerBlog:20170525144553p:plain

赤枠で囲んでいる部分をコピーして貼り付け、実行してください。
無事コマンドが通れば、インストール完了です。

choco -v

インストールとバージョンの確認は上記で。

javaインストール

さっそくChocolateyを使用してjavaをインストールしてみましょう。
同じくコマンドプロンプトで、以下コマンドを実行してください。

choco install -y jdk8

数十秒~数分でインストールが完了します。

java -version

インストールとバージョンの確認は上記で。
パスの設定までしてくれて凄いですね、Windowsでjavaの環境構築に数時間かかっていたあの頃の自分に教えてあげたいです。

Graphvizインストール

PlantUMLを使用するには、描画ツールのGraphvizも必要です。
同じくコマンドプロンプトで、インストールしましょう。

choco install -y graphviz

こちらも数十秒でインストール完了です。

dot -V

インストールとバージョンの確認は上記で。
※Graphvizは自動でパスが通らなかったので、Windowsで実行する方は適宜設定してください。

SublimeText3にPlantUMLを追加

ライブラリのセットアップが完了したら、PlantUMLを動かすためのプラグインをSublimeText3に追加します。
Ctrl + Shift + Pでコマンドパレットを立ち上げてください。

f:id:AdwaysEngineerBlog:20170525143454p:plain

Add Repositoryを選択し、下記リポジトリを追加してください。

続けてコマンドパレットを立ち上げ、Install Packageを選択。

f:id:AdwaysEngineerBlog:20170525143903p:plain

下記プラグインを追加してください。

  • sublime_diagram_plugin

f:id:AdwaysEngineerBlog:20170525143917p:plain

インストールが完了したら、セットアップは終了です。

さっそく使ってみましょう

PlantUMLの構文はこちらでは詳しく書きませんが、以下サンプルを用意しました。
ファイルをDiagram形式に指定すると、シンタックスも変化します。

@startuml

class Shape {
  +setLocation()
  +getLocation()
  +display()
  +fill()
  +undisplay()
}
class Point {
  +display()
  +fill()
  +undisplay()
}
class Line {
  +display()
  +fill()
  +undisplay()
}
class Square {
  +display()
  +fill()
  +undisplay()
}
class Circle {
  +display()
  +fill()
  +undisplay()
}

Shape <|-- Point : 継承
Shape <|-- Line
Shape <|-- Square
Shape <|-- Circle

@enduml

Alt + Mを実行してみると、、

f:id:AdwaysEngineerBlog:20170525143946p:plain

png形式で画像出力してくれます!
調査含めなんと、30分ほどでここまで到達しました。便利。

まとめ

モデリング環境の構築いかがでしたか?
PlantUMLの情報は結構落ちているんですが、Windows + SublimeText3の動作環境は情報が無かったので、今回まとめてみました。
開発で使用するエディタをそのまま設計にも活かせる(AtomもVimも使えます!)のでロスがないですし、何よりテキストで記述できるのでGitで管理すればチーム開発も行いやすいですね。
是非みなさんも開発フローに加えてみてください。

最後に、モデリング実践してくれた沼さん、抽象についていつかブログで熱く披露してくださいね。

Rails5.1 + Webpacker + Vue.js で開発

こんにちは、最近「業務改善ユニット」に異動した渡部です。

業務改善ユニットでは営業の方々が行なっている日々の業務の改善用のシステムを作成しています。

ユニット異動に伴い、あるシステムの開発を任されました。

今後のメンテナンス性・拡張性のために記事名にあるRails5.1とVue.jsを使い始めたのですが、開発に到るまで思った以上に苦戦したので今回はその共有です。

今回はOSはCentOS 7.3.1611、Ruby 2.4.1を使っていますので、環境はそれぞれで合わせてください。

$ rails new . –webpack=vue に至るまで

最初につまずいたのは、Railsをインストールする段階でした(はやっ

今までの開発ではRails 3を使っていたので、Rubyが入っていればRailsのインストールはできるだろうと思っていたのです。

Qiitaなどを調べてみて、初期設定を行なっている記事を見つけたので、嬉々として

$ rails new . --webpack=vue

を叩いたのですが、途中でエラーが起こりました。

エラー内容としては

  • Node.js がない!
  • Yarnがない!(?)

と言ったものでした。

よくよく考えたら、WebpackはNode.js上で動いています。

Node.jsが必要なのは当然でした。

Railsをインストールする時点で、Webpack系のモジュールをインストールしたりしているのでしょう。

そうなると至極当然、Yarnも必要なのでありましょう。

Yarnというのは、

Yarnは……

Yarnってなんだ……。

Yarnとは

渡部はYarnがわかりませんでした。

名は体を表すと言いますが、外国の方には通用しないようで、ツール名からは何をするためのツールかすらわかりませんでした。

ということで続いての僕の行動はYarnについて調べることでした。

簡単にまとめると、YarnはFacebook社がGoogleなどとコラボして作った、npmに代わる新しいJavaScriptパッケージマネージャです。

(公式サイトのトップページにはJavaScriptのパッケージマネージャとか書いてないけど……)

npmと互換性があり、package.json にインストールしたモジュールが追記されていきます。Gemfile.lockと同じようにyarn.lockができたりと違いはありますが、ほとんどnpmと同じ感覚で使うことができます。

Rails5.1+からJavaScriptの管理をYarnでできるようになったようです。

YarnでインストールしたものはAsset Pipelineでも共通して使用できるようという特徴があるようです。

Yarnのインストール

RailsではWebpackerというWebpackのラッパーGemでVue.jsファイルをトランスパイルしているようで、そのWebpackerでは、Yarn 0.20.1以上が必要とされていたので、先にYarnをインストールする必要があるようです。

インストールは公式ドキュメントを参考にしました。

# npm install -g yarn でもいけるっぽい
$ sudo wget https://dl.yarnpkg.com/rpm/yarn.repo -O /etc/yum.repos.d/yarn.repo
$ sudo yum install -y yarn

Node.jsとYarnを揃えたら、あとは rails new . --database=mysql --webpack=vue としたら今度はエラーなくインストールすることができました。

Webpackerを試してみる

JavaScriptファイルの読み込み

WebpackerではJavaScriptをロードするために、javascript_pack_tag というヘルパーメソッドを追加してくれます。

このメソッドはViewファイルで

<head>
...
<%= javascript_pack_tag 'hello_vue' %>
...
</head>

という具合にすると、app/javascript/packs 以下にあるファイルをロードしてくれます。

javascript_pack_tag で生成されるHTMLは普通の <script src="..."></script> タグなので、JavaScriptでECMA6以上の文法を使う場合、現在のブラウザ環境でも使用できるようにトランスパイルをする必要があります。

Railsでは開発時用に bin/webpack-dev-server という開発用のサーバーが用意されています。

webpack-dev-server では app/javascript/packs 以下のファイルの変更を検知して、自動的にBabelでトランスパイルをかけ、ブラウザで開いているページを自動的に更新してくれるとても便利な機能があります。

デフォルトではwebpack-dev-serverを起動すると localhost:8080 でトランスパイル済のファイルを配信してくれます。

設定を変えたい場合は、config/webpack/development.server.yml を修正すると良いようです。

default: &default
  enabled: true
  host: 0.0.0.0    # 仮想ゲストマシンで開発しているのでIPアドレス指定でアクセスできるように変更
  port: 3001        # 8080ポートは使われていたので、3001に変更

development:
  <<: *default

test:
  <<: *default
  enabled: false

production:
  <<: *default
  enabled: false

変更後、bin/webpack-dev-serverの再起動すると、javascript_pack_tag で生成されるURLのポートなどが変わってくれます。

このサーバーは rails s で起動するサーバーとは別で起動しておく必要があるので注意です。

$ rails s

$ bundle exec rails s -b 0.0.0.0 -p 3000

Rails5.1からPumaというRackサーバーがデフォルトで付いてきます。

Pumaにはバグがあるらしく、開発用サーバー起動時に -b 0.0.0.0 オプションをつけるとなぜか9292ポートをリッスンし始めます。

解決策として、-p 3000 をつければこれまで通り、3000ポートでアクセスできるようです。

余談

Yarnに関する注意

Yarnの存在を知らなかったので、最初に見たときは新しいRailsのJavaScript管理用のコマンドラインツールかと思いました。

注意点として、YARNという語はHadoop関連でも使われているようで、ググってみるとそちらの方の記事も出てきます。

YARNは"Yet-Another-Resource-Negotiator"の略称で、汎用的なクラスタリソース管理フレームワーク

「え、クラスタ??? JavaScript用のツールじゃないの???(゚ペ;)」となりますが、別物です!

感想

今回は開発環境をガラリと変えたので、つまずくところは一通りつまずいた気がします。

Rails5.1+、Yarn、Webpackerと色々ありましたがなんとか開発にまでこぎつけました。

Vue.js もしっかりとは使ったことがなかったので現在進行形で詰まりまくっているのですが、今後はそちらについて色々勉強していこうと思います。

それでは、同じような苦労をする人が減りますように、Rails wayでお会いましょう(-人-)ナムナム

Monacaで作るポモドーロタイマー

初めまして!
16年入社の府金です

今回は、フロントエンド言語でスマホアプリを作成できちゃう プラットフォーム 【Monaca】 を利用してみたいと思います。

こちらですね!

ja.monaca.io

無料版でも、3プロジェクトまでは作れるみたいなので
今回はそれで試します!

一先ずサインアップを行い、ログインした画面がこちらになります。
f:id:AdwaysEngineerBlog:20170511122605p:plain 何か最初からHello Worldアプリが入っていますね。
とりあえず無視します。

ではプロジェクトの作成を行って見ましょう!

  • 新規プロジェクトの作成をクリックするとテンプレート選択画面が表示されます f:id:AdwaysEngineerBlog:20170511122821p:plain

  • フレームワークと併用することもできます。今回は何も使わず No Framework でいきましょう。 f:id:AdwaysEngineerBlog:20170511122831p:plain

で、肝心な何を作るかですがここでタイトルに戻ります。

今回はPomodoro Timer(ポモドーロタイマー)を作ります!

ポモドーロタイマーとは?

ポモドーロテクニックという生産性アップ術に用いるタイマーです。

ポモドーロテクニックの概要は以下のような感じですね!
* ステップ1:達成しようとするタスクを選ぶ
* ステップ2:タイマーで25分を設定する
* ステップ3:タイマーが鳴るまでタスクに集中する
* ステップ4:少し休憩する(5分程度でOK)
* ステップ5:ステップ2~4を4回繰り返したら、少し長め(15~30分)に休憩する

このように作業と休憩のサイクルを繰り返すことで、作業効率を上げていくというものですね!

ということで、この画期的なタイマー(ただの25分計)を作成したいと思います。

開発画面はこのような感じですね。
f:id:AdwaysEngineerBlog:20170511122900p:plain

                    

今回は、1500秒(25分)→300秒(5分)のサイクルで通知が出るようにするところまで実装します。

<!DOCTYPE HTML>
<html lang="ja-JP">
<head>
   <meta charset="UTF-8">
   <title>Pomodoro Timer(ポモドーロタイマー)</title>
   <script type="text/javascript">
       var workTime = 1500;
       var state = "work";
       var timer;

       function timerStart(){
           document.getElementById("current_time").innerText = workTime;
           timer = setInterval(timeCount,1000);
           document.getElementById("start").style.backgroundColor="#BAD3FF";
           document.getElementById("stop").style.backgroundColor="#EEEEEE";
           document.getElementById("reset").style.backgroundColor="#EEEEEE";
       }

       function timerStop(){
           clearInterval(timer);
           document.getElementById("start").style.backgroundColor="#EEEEEE";
           document.getElementById("stop").style.backgroundColor="#BAD3FF";
           document.getElementById("reset").style.backgroundColor="#EEEEEE";
       }

       function timerReset(){
           clearInterval(timer);
           workTime = 1500;
           restTime = 30;
           document.getElementById("current_time").innerText = workTime;
           document.getElementById("start").style.backgroundColor="#EEEEEE";
           document.getElementById("stop").style.backgroundColor="#EEEEEE";
           document.getElementById("reset").style.backgroundColor="#BAD3FF";
       }

       function timeCount(t){
           workTime--;
           document.getElementById("current_time").innerText = workTime;
           if(workTime <= 0) {
               clearInterval(timer);
               if(state == "work"){
                   alert("休憩しましょう!!!!");
                   state = "rest";
                   workTime = 300;
               }else if(state == "rest"){
                   alert("再開しましょう!!!!");
                   state = "work";
                   workTime = 1500;
               }
               timerStart();
           }
       }
   </script>

   <style type="text/css">
        html,body{height: 100%; width: 100%;}
        #background{height: 100%; width: 100%; background-image: url("./image/kandume_tomato.png"); background-size: 100% auto; background-position: center bottom;
background-repeat:no-repeat;}
        #start{background-color: #BAD3FF;}
        .button{border-radius: 50%; padding: 30px 30px; border: none;  margin: auto; background-color: #EEEEEE; outline:none;}
        #button{margin-top: 10px;}
        #container{width: 250px; margin: auto; border: 1px solid #CCC; text-align: center; position: center; border: none;}
        #current_time{font-size: 36px;}
        input[type="button"]{ width: 80px;}
    </style>
</head>
<body>
<div id="background">
    <div id="container">
        <div id="current_time">1500</div>
            <form action="">
                <button id="start" class="button" type="button" onClick="timerStart();" >start</button>
                <button id="stop" class="button" type="button" onClick="timerStop();" >stop</button>
                <button id="reset" class="button" type="button" onClick="timerReset();" >reset</button>
            </form>
    </div>
</div>
</body>
</html>

画面上ではこのような感じですね~
f:id:AdwaysEngineerBlog:20170511122940p:plain

一応、当初のポモドーロテクニックにはトマト型のキッチンタイマーが
用いられていた為(↓こんな感じの)、トマト添えで。
f:id:AdwaysEngineerBlog:20170511141835p:plain

とりあえずデザインは、ご愛嬌で。^^b

ではandroid用にビルドをしてみましょう。

まずはキーストアとエイリアスの設定を行っておきます。
リリースビルド版の Android アプリをビルドするときに、キーストアが必要となります。Monaca では、新規のキーストアを作成もしくは既存のキーストアをインポートすることができます。ここでは、新規に作成することを前提に新規作成をします。

クリアして新規作成をクリックします。 f:id:AdwaysEngineerBlog:20170511123218p:plain

キーストアを作成します。
エイリアス名とパスワード、そしてKeyStoreのパスワードを入力します。

  • エイリアス : アプリの署名時に使用する秘密鍵の名前です。1 つのキーストア内に、複数のエイリアスを格納できます。
  • エイリアスのパスワード : エイリアス ( 秘密鍵 ) 用のパスワードです。
  • キーストアのパスワード : キーストア用のパスワードです。このキーストアをインポートするときに、このパスワードが必要となります。

入力したらキーストアとエイリアスの作成を押します!
f:id:AdwaysEngineerBlog:20170511123238p:plain

これで、キーストアの作成が完了しました!

そしてビルド前にもう一つ、重要なことが…!
アプリケーション名アイコン を設定しましょう!
設定は 設定 → Androidアプリ設定 から
お好きなアプリケーション名とアイコンを設定することができます!
f:id:AdwaysEngineerBlog:20170511123248p:plain
今回はこんな感じで!準備OKです!

ではいよいよビルドをしていきます。
メニューバーのビルドからandroidアプリのビルドに進みます。
f:id:AdwaysEngineerBlog:20170511123259p:plain

次の画面で
リリース向けビルド → リリースビルド
と進んでいくと先ほど作成したキーストアとエイリアスが存在することを確認できますね~
f:id:AdwaysEngineerBlog:20170511123311p:plain

そのままエイリアスに設定したパスワードを打ち込みビルドを開始できます!

少々時間が掛かりますね。じっと待ちます。

f:id:AdwaysEngineerBlog:20170511123319p:plain

完了しました!

f:id:AdwaysEngineerBlog:20170511123327p:plain

ビルドしたアプリはローカルに落としてから、androidに入れるか、
QRコードから直接読み取りインストールすることができます。

ではQRコードからインストールしてみましょう。
ダウンロード後に開いてみると身元不明のアプリはインストール拒否される
可能性があるので一旦手動で許可します!
するとインストールが完了しました!!

お、

f:id:AdwaysEngineerBlog:20170511123343p:plain

なにかいますね。 どうやら成功しているようです…!

ではいざ起動。
f:id:AdwaysEngineerBlog:20170511123400p:plain

おぉ、無事起動できました!!
タイマーもしっかり動きました~!^^b

なんというか、開発画面ではしょぼいシンプルな感じでしたが、
実際にスマホ画面で見ると、ちゃんとしたものに見えますね。(気がする)
↓このような感じ。もしかしてedgeがカッコいいから?
f:id:AdwaysEngineerBlog:20170511123431j:plain

スマホアプリがこんなに簡単に…!

今回はこれにて終了です!!

まとめ

今回はじめてブログを書かせていただきました!
唯一扱える面白そうなネタがMonacaだったので、取り上げてみました。
業務でもWebサービスばかりなので、スマホアプリには全然乏しい府金ですが、こういった形で
取り組めてよかったです!
今回は簡単なものしか作れませんでしたが、フレームワークやプラグインを利用してもっと
本格的なアプリも開発できるので、今後も挑戦していきたいと思います!

読んでいただいた方ありがとうございました~!

Go言語 で Google App Engine のローカル開発環境から Google Cloud Storage へアクセスする

久保田です。

AppEngine、いいですよね〜

コードを書くだけでWeb上にアプリケーションが速攻で立ち上がるので初めてやった時は感動さえ覚えました。

さらにローカル環境で開発する用意もされており、簡単に開発を始めることもできます。

そこで今回は、App EngineからCloudStorageへアクセスするアプリケーションをローカル環境に作ってみます。

ローカル環境の設定

僕は以下を参考に整えました。

https://cloud.google.com/appengine/docs/standard/go/download

流れは、
1, Google Cloud SDKを入れる
2, App Engine SDK for Goを入れる
3, 認証し、ローカルからAPIを叩けるようにする。
4, プロジェクトを作成し、設定ファイル、プログラムを用意
5, App Engine SDK for Go内のdev_appserver.pyを使ってサーバーを立てる

といった流れです。

Google Cloud SDKを使ってgcloudコマンド経由でローカル環境でもAPIが叩けるように認証したり、必要なパッケージの管理もでき、App Engine SDK for Goでgo用の環境を手に入れることができます。

ただ、僕の場合はUbuntuでやったからか、App Engine SDK for Goがgcloudコマンド経由で入れられませんでした。ので、直接wgetで落としてくる方法で入れました。

パッケージの用意ができたら、APIがローカル環境から使えるように認証をしてあげます。
ブラウザが使える環境ならば

$ gcloud init

をやると色々と設定ができるようですが、僕はCLI環境だったので、

アカウントの認証と Application Default Credentials (ADC) を別々に取得する必要があります。

$ gcloud auth login

https://cloud.google.com/sdk/gcloud/reference/auth/login

でアカウントの認証をし、

$ gcloud auth application-default login

https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login

でADCを取得します。 どちらも、ホームディレクトリの.config/gcloud以下に収められているはずです。大切に扱いましょう。

ちなみに、ADCとは、

The Application Default Credentials provide a simple way to get authorization credentials for use in calling Google APIs.

と書いてある通り、簡単にAPIを使うの方法なようです。
https://developers.google.com/identity/protocols/application-default-credentials

ここまでやるとGoogleのAPIをコマンドから叩けるようになっているので、確認します。

$ gsutil ls

これでログイン時に指定したプロジェクトにあるストレージのバケット情報が出力されればOKです。

実装

まずはapp.yamlというプロジェクトの設定を書いたyamlファイルが必要です。

application: プロジェクト名
runtime: go
api_version: go1

handlers:
- url: /.*
  script: _go_app

次に実際に動かすプログラムです。 ストレージに入っている.mdファイルの一覧を取得し、表示します。

package main

import (
    "html/template"
    "log"
    "net/http"
    "regexp"

    "google.golang.org/api/iterator"
    "google.golang.org/appengine"

    "cloud.google.com/go/storage"
)

func init() {
    http.HandleFunc("/", handler)
}

type MdFiles struct {
    Files []string
}

func handler(w http.ResponseWriter, r *http.Request) {
    t, _ := template.ParseFiles("templates/index.html")
    files := MdFiles{Files: getMdFiles(r)}
    t.Execute(w, files)
}

func getMdFiles(r *http.Request) []string {
    ctx := appengine.NewContext(r)
    client, err := storage.NewClient(ctx)

    if err != nil {
        log.Fatalf("Failed to create client: %v", err)
    }

    it := client.Bucket(ストレージの名前 string).Objects(ctx, nil)
    files := make([]string, 0)
    for {
        objAttrs, err := it.Next()
        if err == iterator.Done {
            break
        }
        if err != nil {
            log.Fatalf("err: %v", err)
        }

        r := regexp.MustCompile(`\.md`)
        if r.MatchString(objAttrs.Name) {
            files = append(files, objAttrs.Name)
        }
    }

    return files
}

上の例では、templates/index.htmlというファイルを作り、
htmlを出力していますが、お好きな出力方法をお選びください。

これでストレージの中にあるファイルにアクセスできます。
また、このままapp engineにデプロイすればそのまま使えるので、非常に楽ですね。

データをストレージにためておくと簡単に色々とできると思うので、ぜひ試してみてください。