2019-07-19に更新

Koretteのオモテとウラ

読了目安:10分

こちらはCrieitの個人開発サービスに用いられている技術 Advent Calendar 2018の7日目の記事です。

前日は🍃🥜🗼sola🗼🥜🍃さんの「初めてのウェブサービスを WordPress + Vue.js で開発した話」についてでした!

Koretteって?

「Korette(コレッテ)」というのは、私が運営している、観光地の魅力を題材にしたクイズの回答と投稿ができるWebサービスのことです。

本業エンジニアではなく、IT業界の人間ですらなかった自分が、ほぼゼロから独学でプログラミングを学びながら、9ヶ月かけてリリースしました。

https://korette.jp/

topsc.jpg

このサービスを作ったのは、私が30代半ば頃から感じ始めた、「社会のために何か役立つことがしたい」、「組織の肩書きではなく個人として何かを成し遂げたい」、「自分が人に直接人の役に立つ実感が得られることがしたい」、そういったことを思うようになったことがきっかけです。

具体的になにをするかを延々と考えた末、「地域の人が自分の街の魅力を知り、好きになり、誰かに伝える、次の世代に残したくなる」そういう社会を実現しようと思い至り、それを実現するプラットフォームとしてKoretteを開発することにしました。

Koretteは観光地の魅力を歴史や音楽、人物などといった魅力を、クイズ化するというアプローチにより、さまざまな切り口に細分化し、訴求力の高い形で観光地に興味を持つ人に伝えることができるのが特徴です。

また、クイズの作成・投稿を地域に住む人や縁のある人が行うことにより、地域密着の情報が可視化されるという特徴や、地域に住む人が魅力を再発見できることも狙っています。

さらに、題材となる観光スポットのデータには自治体のオープンデータ(約1万件)を活用しており、2018年3月には東京都主催の「東京都オープンデータアプリコンテスト」で準優勝(優秀賞)を頂きました。

少し古いですが、東京都のコンテストに応募した際の企画書をSlideShereにアップしています。

サービスへの思い入れの強さもあって、2017年12月末にこのサービスをリリースしてから、ずっとこのサービス1本でやっています。

今日はこのKoretteのオモテとウラ、テーマに沿って、Webサービスで採用している技術をオモテ(フロントエンド)とウラ(バックエンド)ということで紹介していきたいと思います。

※サービス開発の背景やリリースするまでの話などは、こちらにもまとめています。
 良かったら読んでみてください。

「中年の危機」ど真ん中のオッサンがWEBサービス作ってみた(Qiita)

「中年の危機」ど真ん中のオッサンのWebサービスが東京都のコンテストで入賞するまで(はてなブログ)

基本的な構成

Koretteのサービスは、フロント・サーバーサイドともにASP.NET Core(MVC)を採用、MicrosoftAzureでWindowsServer(IIS)とSQLServerを使っています。

ASP.NET Core(MVC)は、Microsoft社が提供する、C#でWebアプリケーションを作るためのMVCフレームワーク(動作環境)です。

個人開発でWebサービスを開発するときは、PHPやRubyを活用している人が多いと思いますので異端に感じる方も多いのではないでしょうか。

これは、プログラミング経験がほぼ無い自分が、かろうじて持っていた数少ない知識や経験をもとに、そこから最小の学習コストでWebサービスをリリースできるだろうと考えたのが理由です。

その時の経験から、今回Webサービスを開発するにあたり、PHPやRubyやJavaも含めいろいろな言語や開発環境を試してみたところ、C#(とその開発環境のVisualStudio)が自分で一番しっくりくる感じがありました。
これは、大学生の頃にDelphiとVisual Basicを少しだけ触ったことがあり、Delphiの元開発者がC#の開発に関わっているそうなので思想が似ている感じを受けたのかなという気がします。

そいういうわけで、KoretteはASP.NET Core(MVC)をベースに開発スタートしました。
リリース後、機能改善を進めるなかで画面遷移させたくない箇所についてWebAPI+Ajaxでフロント側を更新するページを徐々に増やしていき、今の形になっています。

徐々にフロント側の動的更新の比重が増えてきたことから、現在はかなりJavaScriptを弄る比重が高くなっています。ただ、これもC#をベースに色々と学んだお陰で応用が利いていて、イチからJavaScriptを学ぶより遙かに習得が早くなってい気がしています(たぶん最初からJavaScriptだと発狂してリリースに至らなかったかも・・・)。

オモテ(フロントエンド)

採用しているフレームワーク・ライブラリなど

ASP.NET Core(MVC)で表示されたビューのHTMLのDOMをJQueryを使って書き換えるという古典的な手法を採用しています。

VueやReactといったフレームワークは採用していないのは、プログラミング経験んがほとんどない自分がWebサービスをリリースするにあたり、フロントとバックと両方にフレームワークを学習するという二正面作戦は無理だと判断したためです。

  • Bootstrap4.0
    リリース当初は3.x系でしたが、ページデザインのリニューアルを機にアップデートしました。

  • JQuery 3.3.1
    リリース当初は2.2.x系でしたが、ページデザインのリニューアルを機にアップデートしました。

  • Material Design for Bootstrap 4(https://mdbootstrap.com/)
    マテリアルデアインのUIキットです。無料版もありますが有償版の方を使ってます。
    カード型のスタイルなど、Koretteのデザインのベースになっています。

  • leafletjs(https://leafletjs.com/)
    OpenStreetMapの地図操作ライブラリです。
    地図ライブラリは、当初はYahooMapを利用していましたが、OpenStreetMapの方がマッピングパーティといった地域の人が地図を更新するイベントが行われるなど、Koretteと目指すところが近いものを感じたことからOpenStreetMapに変更することにしました。
    観光スポット紹介ページの地図情報などで利用しています。

  • Croppie(https://foliotek.github.io/Croppie/)
    画像の縦横変換、切り抜き&リサイズライブラリ。
    クイズ投稿時の画像投稿機能で利用しています。
    当初はアップロードしてサーバーサイドでリサイズしていましたが、ネットワーク負荷軽減などを考慮し、クライアント側で行うように変更しました。

  • Garlic(http://garlicjs.org/)
     投稿フォームで入力中に別画面へ遷移した際に入力内容を保持しておくライブラリ。
     利用者さんからの要望で追加した機能です。

ウラ(バックエンド)

採用しているフレームワーク・ライブラリなど

  • CoreTweet(https://github.com/CoreTweet/CoreTweet)
     Twitter連携のライブラリ。Koretteのアカウントへのピックアップクイズの投稿に利用しています。

  • SixLabors.ImageSharp(https://github.com/SixLabors/ImageSharp)
    ASP.NET Core対応の画像処理ライブラリです。
    当初はユーザーの投稿画像をこのライブラリでリサイズしていましたが、現在はフロント側でリサイズされてサーバサイドに飛んできますので、飛んできた画像をもとにサムネイル用とOGP用の画像を生成する際に利用しています。 サムネイル用は単なるリサイズですが、OGP用は1200×630の白紙キャンパスに飛んできた画像をセンタリングして配置し縦横比を変換するという処理を行っています。
    また、このライブリでは、画像無しでクイズを投稿した際にタイトル名を画像化する機能としても利用しています。

バッチ処理

リリース後の機能追加で、人気クイズのランキングや、投稿者ランキングなどを実装しました。

これらの機能について、リリース当初はユーザーが表示リクエストをした際に、クイズの解答履歴データを都度集計してランキング表示をしていました。またクイズの回答数も回答履歴を都度集計して表示していました。

利用者が増え、徐々に回答履歴データが肥大化していくとともに、これらの処理が重くなっていきました。

そこで、これらの処理をバッチ処理化することにしました。

とはいっても、専用のジョブ管理ツールとか入れるまでのレベルではないと考えたので、ASP.NET CoreのWebAPIで処理を作成し、WindowsのタスクスケジューラからPowershellのスクリプトを定時キック、PowershellのスクリプトがWebAPIに鍵情報を付加したhttpリクエストを行うことにより処理を開始するという、「なんちゃってバッチ」で実装しています。

また、バッチ処理化にあたり、大量にデータ更新するテーブルについては、障害対応とロック対策のために2テーブル化を行いました。

PrimaryテーブルとSecondaryテーブルを作成し、Primaryテーブル参照時間帯にSecondaryテーブルをバッチで更新、時間経過後はその逆を行うという形にしています。
万が一バッチ処理の異常終了でテーブルがぶっ壊れた場合は、更新テーブールに切り替わるまでに復旧作業を行える時間稼ぎができるようになっています(実際はサラリーマンやってる時間にぶっ飛んだらどうにもなりませんがw)。

また、バッチ化により、ランキングアルゴリズムを回答数だけでなく、複数の要素を組み合わせて集計するといったより高度な処理にすることも可能となりました。

インフラ周り

MicrosoftAzureでWindowsServer2012R2のVMを立てて、WEB・APサーバーとDBサーバー(SQLServer2016)を同居させています。

VMのDISKは容量を最小にする代わりにPremium SSDを採用しIOのボトルネックを最小化。利用者の投稿画像などは別途BLOBストレージを用意し、そちらに配置するようにしています。

自分の学習コストを最小限にするためにAzureやWindowsServerを選択していますが、ASP.NET CoreはLinuxでも動作するようになったので、Linuxへ以降すれば運用コストを減らすことができると思います(現在移行を検討中)。

技術の選択には学習コストの視点も

冒頭に触れたように、私がプログラミングをほぼゼロから覚えてリリースできたのは、少しだけあった過去の経験から学習コストが最小となるWindows系とC#を選択したというのも大きかったのかなと思います。

サービスをリリースまで至るには、技術的にオーソドックスじゃない、古くてもイケてなくても、自分の学習コストが最小化できるのであれば、それを選択しても良いと思うのです。

一度、何かの技術を使ってサービスをリリースするまで至ることができれば、そこで得た基本的な知識や他の技術でもある程度応用がきいて、学習スピードは圧倒的に上がります。

なので、いくつか軽く触ってみて、わかりやすい、使いやすいと思った言語や技術でとりあえず作ってみると良いのだと思います。

プログラミングはハマると楽しくなって、ついつい新しい技術に手を出したくなることがあります。でもサービスをリリースするという視点で考えれば、学ぶことが目的ではなく、リリースするために学ぶのが目的のはずです。
であれば、最小の学習コストという視点も観点のひとつとしてあるのかなと思います。

まずは、自分で良さそうと思うものを決めて、あとは浮気せずリリースまで突っ走ってみると良いのではと思います。

サービスのリリースはゴールではなくスタートです。
まずはどんな形でもスタートラインに立ってみると、違う世界が見えてくると思いますよ。
私のサービスはリリースしてもうすぐ1年ですが、まだスタートラインをウロウロしている気もしなくはないですが・・・。

頑張ってリリースまで到達できたら、山のように迷うことや選択を迫られることが出てきます。
そのときは、必要に応じてアドバイスをもらえる環境も大切です。特に以下2つのSlackコミュニティは知見を持った人が沢山所属していて、アドバイスや情報交換ができるのでオススメです。私も所属させてもらっています。
門を叩いてみましょう。

・マシュマロの運営者でもあるダースさんが運営している「運営者ギルド

・SeekGeeksというプランナーとエンジニアのマッチングWebアプリを運営しているny(にぃ)さんが運営する「Monetize-Geek-JAM

上記のコミュニティの他に、私も場合は「Koretteサポーターズ」というコミュニティを自分で作ってしまいました。
Koretteの目指すところに共感頂ける有志の方を公募させていただき、現在6名のサポーターに支えられています。
支援者&利用者の立場で、UXの改善をはじめ、迷ったときの相談相手になって頂いていて、凄く助かっています。

Koretteのこれから

ここからは少し宣伝チックな内容です。

Koretteですが、皆様の応援に支えられ、少しづつですが利用者も増え、12月27日にリリース1周年を迎えるところです。

これまで個人サービスとしてやっていましたが、このタイミングで、非営利の運営団体を設立し、Koretteの運営を団体として行っていこうと思います。

設立する団体名は「CultiVision(カルティVision)」です。
Vison(ありたい将来)をCulti(耕す)という意味を込めて造った造語です。

「地域の人が自分の街の魅力を知り、好きになり、誰かに伝える、次の世代に残したくなる」
そんな社会の実現に向けた活動を、農業の土作りのように、地域の人とともに畑を耕すように長期的な実りを期待して活動をしていけたらと思っています。

団体化により、これまで個人名ではやりにくかった企業などとのコラボやイベントの開催などを行うなども予定しています。
Webサービスとリアルの活動を組み合わせながら、サービスのさらなる普及を目指し、ありたい将来の実現に向けて進めていく予定です。

まず、団体としての活動の第一弾として、12月中にKoretteのスマホアプリ版のリリースを予定しています!
スマホアプリ化により、より気軽に楽しく遊んで頂けるようにしていきたいと思っています。
その際は、プレスリリースも投げて、認知度を高めて行く予定です。

サービスのみためもUXもまだまだですが、サービスにかける想いだけは、他の方に負けないように、あとは沢山の人に助けてもらいながら頑張っていきたいと思っています。

今後とも応援の程、どうぞよろしくお願いいたします。

最後に

ちょっと読者ターゲットが絞れない記事になってしまったかもしれません・・。
この記事が、ほんの少しでも、みなさんのヒントになれれば幸いです。

個人開発サービスに用いられている技術 Advent Calendar 2018、明日はckoshienさんの「野球リーグスコア管理システムに用いている技術について」の記事です!お楽しみに!

ツイッターでシェア
みんなに共有、忘れないようにメモ

Hiroz

40代。小学生の2児の父。 クイズで観光地の魅力をみつけるWebサービス「Korette」の開発者。2018.3に「東京都オープンデータアプリコンテスト」で準優勝を受賞。 住む人が街を知り・好きになり・発信される魅力を観光したい人へ届ける。そのためのプラットフォームを目指してます。.NetCore/C#/Azure

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント