Web API+Flutterで学校の問題点を解決した話
1/7追記
今読んだらサーバーでxlsxファイルを読み込む方法が完全に自前実装みたいな感じで書かれていたので、xlsxファイルが扱えるパッケージを使用したことを追記しました。
まえがき
note.muでははじめましてになります。Twitterなんかでエンジニアっぽい呟きとCG屋っぽい呟きをしているKurogoma4Dです。
これは年末年始で開発した、弊学で起こりうる(個人的な)問題を解決するシステムをまとめた記事です。開発する上で思ったこととかも書いていくので、グダグダするかもしれませんが読んでいただけるとありがたいです。
正式にプロダクトとしてリリースしたわけではありません(リファクタリングしないとダメそうなので)が、前から研究室の教官と「こういうのが欲しいですね」っていう話はしていたのでもしかしたら…?
課題
自分は某高専に通っています。これを執筆している時点ではもう専攻科1年が終わりそうであり、かれこれ6年弱通っているわけですが、この学校には致命的な問題点があります。それは、
部屋の場所が分かりづらい!!!
はい。とても分かりづらいのです。流石に4、5年生になればなんとなくは掴めてきますが、長期休みに入るたびに分からなくなります(記憶力が疑われる)。
この「分かりづらい!」っていう叫びが個人の単なる遠吠えでないことを確認するために、その原因を考えてみました。
・そもそもキャンパス自体が結構広い
・部屋の名前が機械的なものが多い(第一講義室、第二講義室…など)
・数字が振ってあっても場所がバラバラ
大きいものであればまずこの辺ですね。位置と部屋名がマッチしないのです。更に、既存のシステムでは、
・学校HPに構内図はあるが、棟名とその場所までしかわからない
・棟の内部は学生便覧(校則とか書いてあるやつ)にしか載っていない
つまり、知らない部屋の名前を言われて、場所を特定しようとすると、学生便覧が必須になります。実は学生便覧もHPにてPDFで公開されているので、予めダウンロードしておくなり見やすいように加工しておくなりすればいいということも言えなくはないのですが、それはちょっと…ってなりますよね。
良くない事例
本科時代に個人的ありがちパターンとして以下の流れがありました。個人的とは言いますが周りを見る限り他の人もよくやってました。
① 次の講義どの部屋?
② 時間割表を見る → 部屋名が分かる
③ その部屋どこよ → 学生便覧を取り出す
④ 構内及び棟内の図とにらめっこ
これほんとムダだと思います。
ソリューション
「じゃあWebで簡単に部屋から場所を逆引きできればよいのでは?」
ということをどこかのタイミングで思ったので、今回作成するに至りました。今回作ったものがこちら↓
題して『それドコ?(仮)』です。何だその名前。
動画を見ていただければわかるように、部屋名を検索すると候補が表示されて、それを選択すると何棟の何階にあるかがわかるというものになります。
先に今回作ったもののGitLabリポジトリをば。
システム構成
システム構成は単純明快、Golangで記述したWeb APIにGETリクエストを送ると、部屋とそれがある建物、階数をまとめたJSON文字列が返ってくるため、それを表示するというものです。返すためのデータは、サーバー起動時にエクセルで記述されたものを読み込むようにしています。
なぜWeb API?
ここまで単純なシステムならば、Webフロントだけとか単純にネイティブアプリ作れば解決しそうなものです。
まず、ネイティブアプリを開発するという線は切りました。ここは開発、運用まで考えると何かとコストが掛かりそうという結構曖昧な理由です。最終的にFlutterを採用していますが、これは後ほど。
次にWebで単純に実装すればいいのでは?ということでしばらく構想を進めていました。その時、どこかのタイミングでAPIを作ろうと思いました。正直なところあまり切り替える理由はありませんでしたが、ユーザーから見えるのは検索画面とその結果くらいなので思い切ってシステムを小分けにしてしまって見通しをよくしようという気持ちがありました。
今回の開発は、実際に使えそうなものを作ると同時に学習の機会とも考えていたので、より普段扱わないような部分に踏み込んでみました。サーバーサイドは本当に経験ないですし。
更にもっともらしい理由として、APIという形にすることでクライアントサイドのプラットフォームを問わなくなりました。後々Webフロントの学習としてクライアントサイド実装もできるので、気分的には一石二鳥です。
ちなみに、扱うデータをxlsx形式にしたのは、見通しを良くする意味と、開発の速さ、メンテナンスのしやすさを考えた結果です。多分最適解はDB構築ですが理解するまでに時間がかかりすぎるかなということで…
なぜFlutter?
最初にネイティブアプリを切っておいて、最終的にFlutterでクライアントサイドをやろうという矛盾が起こりました。
これに関しては、完全に個人的理由で、「Flutterを使ってみたかったから」です…
「Material Designをさっくり実装できてかつクロスプラットフォームで開発できるFlutterが正式リリースされたぞー!」という感じで勝手にテンション上がってたらこれはもうやるしかないという感じになりましてその。
ただし、将来性を考えると結構アリだと思っていて、クロスプラットフォームだしXamarinより汎用性ありそうな感じだし、何よりwebにも応用できそうという利点があります。
サーバーサイド
ここからは少しだけ中身について書きます。
サーバーサイドでは、echoというフレームワークを使ってサーバーを立てます。echoは記述量も少なく、高速に動作するようです。実際に、取り掛かってからサーバーが立つまでは数分で、そこから調整で1日前後かかったくらいでサーバーサイドの作業はほぼ完了しました。mainもこんな感じです。
func main() {
e := echo.New()
roomData := ParseData.FromExcel("./assets/data.xlsx")
e.Use(middleware.Logger())
e.Use(middleware.Recover())
e.GET("/rooms", handler.NarrowedRoom(roomData))
e.Start(":8080")
}
ParseDataは、xlsxデータを読み込むための自前パッケージです。内部では、xlsxファイルを扱えるパッケージ「xlsx」を使って、構造体にデータを格納しています。つまり、サーバーを起動した時点で、↓の形式でデータを持っていることになります。
type JsonData struct {
Rooms []Room `json:"rooms"`
}
type Room struct {
Name string `json:"name"`
Building string `json:"building"`
Floor string `json:"floor"`
}
そしてGETリクエストを送るとこんな感じに返ってきます。
クエリストリングをつければ前方一致するものを抽出できるようにしているので、基本的にこれでリクエストを送ることにします。
クライアントサイド
クライアントサイドも動きは単純で、検索欄に部屋名を打ってEnterしたらAPIコールが入り、それを整形して表示するっていうだけです。作るにあたって参考になるものを探していたらまんまこれだっていう記事を見つけました。
本当にほぼ同じです。こういうのを見つけられると理解も進むし、ありがたいです。というかDevelopersIOさんにはお世話になってばかりな気がします。感謝です。
FlutterのDartは整形すると結構ソースが長くなりがちなので、別でFlutterはいいぞ的な記事を書きたいです。今回いろいろと発見もあったので。
まとめ
若干紆余曲折あったものの、これで弊学の問題点が一つ解決しました(なおデータ作成が最後まで終わっていないので使えない模様)。
構想自体は実は結構前からあったのですが、今回長期休みに入ったので開発してみたら結構すばやく動くものができたので、結構おぉ…ってなってます。しかもほぼいじったことのない言語を2つ使って。
実際に始まったのが12/25あたりで、そこから1/5までの作業で、更に大晦日から1/2まではほぼ動いてなくて…って考えると調べながらでも本当に早く開発できたんだな、って感じですね。
この記事はここで締めたいと思います。最後まで見ていただきありがとうございます!
この記事が気に入ったらサポートをしてみませんか?