初心者にMongoDBを教えようと自作パッケージを作って奮闘した話

# ごあいさつ
初投稿です。「せきぶん」などと名乗っているものです。積分は苦手です。
よろしくお願いします。

[駒場祭](https://www.komabasai.net/)という学園祭でプログラミングをしてました。
JavaScript(Node.js)を主に使って開発にあたっています。

# 注意
この記事はあくまでやったことの紹介であり、解決策は提示していません。

# この記事について
大学のサークル（学園祭実行委員会）において後輩への教育目的で自作パッケージに挑戦した、という内容です。

### 駒場祭委員会の事情
「駒場祭」を運営する駒場祭委員会には、「システム局」というIT分野を担当する部署があります。

[ウェブサイト](https://www.komabasai.net/)や、参加される企画が登録をしたり申請したりする「ウェブシステム」と呼ばれるウェブサービスなどを作っています。

無給の学生自治団体であるためか、プログラミング経験者は余り集まりません。また、駒場祭が1〜2年生用のキャンパスで行う学園祭であるという事情から、駒場祭委員会も1年生と2年生のみで構成されます。
よって2年生は引退するまでの約半年間で、初心者の1年生に来年度の開発に必要となる様々な知識を教え込む必要があります。

かく言う僕もHTMLなどを少し触ったことがあったとはいえ、初心者として駒場祭委員会システム局に入り、先輩に教えてもらいながら成長した1人です。

駒場祭のウェブサイトは多分みなさんが「学園祭のウェブサイト」と聞いて想像するよりはリッチな機能が（現在はもう使えませんが）あります。
例えば、当日に[公式グッズ](https://www.komabasai.net/70/visitor/goods)の売り上げや[キャンパスツアー企画](https://www.komabasai.net/70/visitor/kikaku/104)の参加賞配布状況が分かるページなどです。

このため、フロントエンド開発だけでなく、バックエンド開発も必要になっています。

### つまり、この記事は……？

この記事は、なかなか初心者には理解してもらいにくいバックエンド開発に関して、なるべくわかりやすく初心者に理解してもらおうとした僕の奮闘の記録です。

一番悩み、工夫したつもりのデータベース関係、MongoDBに関して特に扱います。

僕自身もまだ初心者であり、技術的にも内容的にもハイレベルとは程遠いです。
が、学園祭プログラマーの方や、「非IT企業でIT部門のメンバーがコロコロ変わってしまい技術引き継ぎが難しい...」などといった悩みをお抱えの方に役立てば幸いです。

# そもそも何が難しいのか
### バックエンドとは何か
初心者にとって「フロントエンド」「バックエンド」という言葉は余り聞き慣れないものでしょう。

「みんなの使ってるブラウザがフロントエンドだよ。」
「バックエンドってのはサーバーで動いてるもので、例えばログインデータはサーバーにないと改竄されちゃうよね。」
的な感じで説明しました。

### DBについて
「データベースってものが色々あってデータを同時に読み書きしたり、検索したりするのに便利だから使うんだ。駒場祭で使うデータはサーバーに入れておくんだ。」
といった感じで説明しました。

僕自身1年前にデータベースについて聞いた際に必要性がわからなかったので、何が便利なのかに重点を置いて説明しました。

当時の僕「え？jsonファイルで保存すればいいじゃんw」

また「MySQL？ DB？」ってなっていたので、データベースの種類としてMySQLや今回扱うMongoDBがあるということも説明しました。

# MongoDBの難しいところ
Node.jsでMongoDBを扱うためのパッケージはいくつかありますが、我々は[mongodb](https://www.npmjs.com/package/mongodb)という公式のパッケージを使っていました。

（[mongoose](https://www.npmjs.com/package/mongoose)などのパッケージもありますが、さらに複雑になるため初心者向けではないということで以下では無視します。）

これは扱うのがなかなか面倒で、データを持ってくるために

``` Javascript
const mongodb = require('mongodb');
const MongoClient = mongodb.MongoClient;
const client = await MongoClient.connect('mongodb://127.0.0.1:27017/', {
            useUnifiedTopology: true,
            useNewUrlParser: true,
        });
const db = await client.db('dbName');
const collection = db.collection('collectionName');
const data = await collection.find().toArray();
client.close();
```

と書く必要があります。
これでは初心者に「むずかしいおまじない」と思われても致し方ないでしょう。

さらに、そもそもasync/awaitを使っており、初心者が最初の最初に勉強する「はじめてのJavaScript」の範囲を逸脱しています。

よって、とりあえずasync/awaitを教えて.......となってしまいます。
非同期処理についてを教えるのも苦労しつつ工夫したのですが、ここでは話は長くなるので省略します。

もう1つ、「接続して、dbを選択して、collectionを選択して、......」となると複雑です。
「そもそもDBってなんや」となっている初心者に「collection」などの用語を叩き込むのは混乱を生むだけです。

さらにはMongoDBについて学ぼうとすると、Node.js以外の話なども出てきてしまいます。
「Node.jsとはなにか」があまりわかってない初心者は「ggってもよくわからない......」となってしうでしょう。

問題が山積みです。
どうすればいいのでしょうか......？

# 自作パッケージで解決だ！
さて上記の問題を解決しないといつまでたっても1年生がDBを使いこなせません。

そこで「ggるのが難しいならggれなくていいじゃないか！」「とりあえず単純にして慣れてもらおう！」ということでパッケージを自作しました！

それが[mongodbeginner](https://www.npmjs.com/package/mongodbeginner)（[GitHub](https://github.com/integral0523/mongodbeginner)）です。

内部で「DB体験」用に作成したものですので、色々と雑です。実用には耐えないでしょう。

### 使い方
mongodbeginnerでは「初心者が **とりあえず** DBを使える」ことのみを重視しています。
そのため、とても非効率的ですが、接続などの処理を毎回行います。

例えば `id` が `1` のデータをfindしたい際には

```JavaScript:mongodbeginnerのサンプル
const mob = require('mongodbeginner')
const data = await mob.find("dbName","collectionName",{id: 1})
```

と書くだけでOkです。

また、もし `{id: 1, count: 0}` というデータをinsertしたい場合は

```JavaScript:mongodbeginnerのサンプル2
const mob = require('mongodbeginner')
const data = await mob.insert("dbName","collectionName",{id: 1, count: 0})
```

などと書けば動きます。

とても強引ですが、「dbに接続して...」「collectionを選択して...」とお約束ごとが多くて複雑すぎるという問題を解決しています。


### 問題点/反省
こちらを開発したのが約半年前の8月ですので、既に直したいところも多々あります。
そもそも僕自身の実力不足もあり、なんとも言えない出来になってしまいました。

最大の問題は結局`await`が必要になってしまうことでしょう。
これの解決策は特に思いついていません。

結局やはりPromiseやasync/awaitを初心者にも覚えてもらうしかないのでしょうか......？。

# （おまけ）超簡易版 npmにパッケージを公開する方法

さて、今回初めてパッケージを公開したのですが、npmにパッケージを公開するのは思った数倍は簡単でした。
特に[こちらの記事](https://qiita.com/TsutomuNakamura/items/f943e0490d509f128ae2)が参考になりました。

内部向けパッケージということで、テストも省略させていただき、とても容易に公開できました。
せっかくですし、この記事の内容が薄すぎますし、一般のNode.jsアプリケーション開発と異なる部分をメモしておきます。

```bash:npmへのuser登録
$ npm set init.author.name "名前"
$ npm set init.author.email "メールアドレス"
$ npm set init.author.url "URL"
$ npm adduser
```

```bash:初回公開
$ git tag -a v1.0.0 -m "My first version v1.0.0"
$ git push origin tags/v1.0.0
$ npm publish ./
```

```bash:パッチアップデート（修正）
$ npm version patch
$ git push origin tags/v1.0.1  # ここは手動でやるしかない
$ npm publish ./
```

```bash:マイナーアップデート
$ npm version minor
$ git push origin tags/v1.1.0  # ここは手動でやるしかない
$ npm publish ./
```

```bash:メジャーアップデート
$ npm version major
$ git push origin tags/v2.0.0  # ここは手動でやるしかない
$ npm publish ./
```

# まとめ
プログラミング初心者の1年生がMongoDBに慣れられるよう、いろいろとやろうとしました。ただ、やはり理解が難しかった様子でした。

また、本題とはずれますが、自分の経験から「DBが難しい」という意識が強くなり、API開発などで使用するフレームワーク[Express.js](https://www.npmjs.com/package/express)の解説を軽視してしまい、詰まってしまった後輩も多かったように思います。

やはり（初心者が）初心者にバックエンド開発について教えるというのは難しいものでした。

ところで、ruby on railsでもやろうかなぁ。時代遅れって聞くこともあるけど...
（編注）この記事投稿から3年以上が経ちましたが、ruby on railsではHello, Worldすらしていません。、