5歳娘「パパ、変なAPIを作らないで？」

## とある休日
娘（**5歳**）「パパ、一緒に**技術ブログ**を始めない？」
娘「昔から私とパパが**ローカルに書き溜めてる技術記事**が、かなり溜まってきたでしょ？」
娘「それをブログとして公開してみようよ」

ワイ「おお、それは楽しそうやな」
ワイ「どこのブログサービスを使おうかいな」

娘「せっかくなら、ブログシステムから自分たちで作ってみようよ」
娘「私はフロントエンドを担当するから」
娘「パパはRuby on Railsか何かで、**API**を作ってよ」

ワイ「おお、Ruby on Railsなら昔やったことあるわ」
ワイ「Railsの**APIモード**で、ブログ記事を返すエンドポイントを作ればええんやな」

娘「そうそう」

## 次の日

ワイ「API、できたで！」
ワイ「`/api/articles`っていうエンドポイントにアクセスしてくれたら」
ワイ「ブログ記事が取得できるようにしておいたわ」

娘「さすがパパ」
娘「そういえば、10記事ごとにページを分けたいんだけど」
娘「どうしたらいいかな？」

ワイ「おお、**ページネーション**いうやつやな」
ワイ「`/api/articles?page=2`って感じでAPIにアクセスしてくれたら」
ワイ「2ページ目を取得できるようになってるで！」

娘「わ〜、気が利いてるね！」

ワイ「ゲヘヘ」

## また次の日
娘「フロントのコーディングもだいぶ進んだよ！」
娘「パパ、見てみて！」
娘「これが**TOPページ**だよ！」

<img width="832" alt="スクリーンショット 2020-07-20 22.10.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/1261c6e7-0c9b-b394-33a7-71744395ef3b.png">

ワイ「おお、バッチリやん」
ワイ「ナイスTOPページや」

娘「それでパパ、相談があるんだけど」

ワイ「なんや、娘ちゃん」

娘「あのね、TOPページはこれでいいんだけど・・・」

> 閲覧者「やめ太郎の記事は読みたくない！」
閲覧者「娘ちゃんの記事だけ読ませてくれや！」

娘「↑こんな閲覧者さんのニーズも、きっとあるじゃん？」

ワイ「せやな」

娘「だから、**私の記事だけを表示するページ**も作りたいんだけど」
娘「その場合は、どうAPIから取得すればいいの？」

ワイ「うーん、そんな方法は用意してないし、今後実現できる気もせんわ」
ワイ「・・・せや！」
ワイ「フロント側でフィルタリングして、ワイの記事だけ消してくれや」
ワイ「それで『娘ちゃんの記事だけのページ』ってことになるやろ」

娘「いや、それは駄目でしょ」
娘「そこはバックエンド側でフィルタリングしないと」

ワイ「なんでや、フロント側でもフィルターできるやろ」
ワイ「JavaScriptの配列の`filter()`メソッドとかで」

娘「うーん、駄目だと思う」

## なぜ駄目なのか

娘「まず、この技術ブログは」
娘「**1ページごとに10件の記事を表示**するじゃん？」

ワイ「せやな」

娘「つまり、10記事ぶんのデータをAPIから取得するわけ」

ワイ「そらせや」

娘「そこから、フロント側でフィルターして」
娘「パパの記事だけを取り除いちゃうと」
娘「画面上はこんな感じになっちゃうの」

<img width="832" alt="スクリーンショット 2020-07-20 22.22.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/5ae9da58-d714-4bb8-ceec-d49dbdf00b39.png">

ワイ「ああ、7件になってもうたな」

娘「この表示の仕方だと、閲覧者さんに**誤解を与えてしまう**可能性があるの」

ワイ「そうなん？」

娘「そうだよ」
娘「まず閲覧者さんが**TOPページ**を見て」

> 閲覧者「このブログは、**1ページに10件**表示するんやな」

娘「ってことを覚えたとして」
娘「次に、私の記事だけのページ」
娘「つまり**7件しか表示されていないページ**を見た場合に・・・」

> 閲覧者「娘ちゃんの記事は、まだ**7件だけ**か」
> 閲覧者「ほな、**2ページ目は無いんやな**」

娘「って誤解しちゃうかもしれないじゃん」
娘「ちゃんとページネーション部分を見れば、5ページ目まであることは分かるんだけど」
娘「パッと見で『7件だけか』って印象を与えるでしょ？」
娘「または逆に・・・」

> 閲覧者「このページは、**1ページに7件**表示するんやな」
> 閲覧者「TOPページは**1ページに10件**なのに」
> 閲覧者「このページは中途半端な数で区切って、**変なサイト！**」

娘「っていう誤解を与えちゃうかもしれないし」

> 閲覧者「あれ、1ページ目は**7件**、2ページ目は**9件**、3ページ目は**10件**表示されたで」
> 閲覧者「ページごとに表示件数ガタガタやん」

娘「ってことも起こりそうだよ？」

ワイ「ま、まあな」
ワイ「で、でもまあ、そこまでクリティカルではないやろ」

娘「それに、もしも1ページ目の10件が**たまたま全部パパの記事**だった場合は」
娘「こんなことになっちゃうよ？」

<img width="832" alt="スクリーンショット 2020-07-20 22.33.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/b89ad8bf-a280-57ab-deeb-cfac3e344782.png">

ワイ「Oh...」
ワイ「何も無いのに、ページネーションだけある・・・」

娘「ね、変でしょ？」
娘「だから、フロント側でデータのフィルターなんかしちゃ駄目」

ワイ「わ、分かったわ・・・」

## 次の日
ワイ「よっしゃ！」
ワイ「ワイの記事と娘ちゃんの記事を別々に取得できるエンドポイントも作成したで！」
ワイ「娘ちゃんの記事だけを取得するためのエンドポイントは」
ワイ「`/api/articles/musume`や！」

娘「ありがとう、パパ！」
娘「あれ、でも**TOPページ**がエラーになってるよ？」

ワイ「おお、実はな」
ワイ「APIを改修したときに」
ワイ「元のエンドポイントを**消してしもうたんや**」
ワイ「パパと娘ちゃんの記事を一緒に取得できる・・・」
ワイ「最初に作った`/api/articles`っていうエンドポイントな」

娘「え・・・消しちゃったの？」

ワイ「でも大丈夫や」
ワイ「パパの記事だけを取得するための`/api/articles/papa`っていうエンドポイントと」
ワイ「娘ちゃんの記事だけを取得するための`/api/articles/musume`っていうエンドポイント」
ワイ「その2つがあるからな」
ワイ「**2つのエンドポイントから5件ずつ**取得して、マージして表示すれば」
ワイ「同じことやろ？」

娘「いやいや、ぜんぜん駄目だよ・・・」

## なぜ駄目なのか

娘「例えば、私の記事が合計**20件**あって」
娘「パパの記事が合計**1件だけ**だった場合はどうなると思う？」

ワイ「ええと、娘ちゃんの記事用のエンドポイントから**5件**取得して」
ワイ「ワイの記事用のエンドポイントから**1件**取得するから」
ワイ「こんな感じになるな」

<img width="829" alt="スクリーンショット 2020-07-21 0.22.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/71de726a-4a9b-13fa-cfba-8ce4a79e7112.png">


ワイ「あ、また**10件未満**になってもうた・・・」

娘「今回の例だと、私とパパの記事を合わせて**合計21件**だから」
娘「本来は**3ページ目**まであるはずなのに」
娘「パッと見だと**10件未満しかない**から」

> 閲覧者「このブログの記事は、まだ6件だけか」
> 閲覧者「ほな、2ページ目は無い感じか・・・？」

娘「もしくは」

> 閲覧者「このブログは6件ごとにページネーションすんねやな」
> 閲覧者「キリ悪っ。**アホちゃうか**」

娘「って思わせちゃうでしょ？」

ワイ「た、確かに・・・」

娘「だから、フロント側でのマージはオススメしない」

ワイ「そうなんかぁ・・・」

娘「それにね」
娘「2つのエンドポイントから記事を取得して、フロント側でマージすると」
娘「1ページ目と2ページ目で、**記事の順番もおかしくなっちゃう**の」

ワイ「そうなん・・・？」
ワイ「ちゃんとソートもすれば大丈夫ちゃう？」

娘「じゃあ、それも説明するから見ててね」
娘「さっきマージした状態で、**一番新しい記事**は・・・」

<img width="829" alt="スクリーンショット 2020-07-21 0.22.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/71de726a-4a9b-13fa-cfba-8ce4a79e7112.png">

娘「↑この、一番下の記事。」
娘「パパが`2018/07/21`に書いた、」
娘「**変数って何か分からないから後輩に聞いてみた**、って記事でしょ？」

ワイ「せやな」
ワイ「**古い順**に並んどるからな」

娘「じゃあ、2ページ目以降には**いつ頃の記事**が表示されると思う？」

ワイ「いつ頃って・・・」
ワイ「`2018/07/21`以降の記事が表示されるやろ」
ワイ「**古い順**なんやから」

娘「普通はそうだよね」
娘「閲覧者さんも・・・」

> 閲覧者「このページは、**古い順**に記事を表示してるんやな」
> 閲覧者「そして、1ページ目の1番下の記事は`2018/07/21`」
> 閲覧者「じゃあ、2ページ目は**それより新しい記事**が表示されるんやろな」

娘「って考えるわけ」

ワイ「せやな」

娘「でも、実際に表示されるページは・・・」

<img width="829" alt="スクリーンショット 2020-07-22 7.49.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/fb732a1d-e65f-976a-8192-5991b91200d7.png">

娘「↑こうなっちゃうの」
娘「**一番上**の記事を見て？」
娘「`2018/07/21`より**過去**である`2018/07/16`の記事が表示されてるでしょ？」
娘「2ページ目は**未来のはず**なのに」

ワイ「ほんまや・・・」
ワイ「フロント側でマージした後にソートするやり方だと」
ワイ「ページネーションが絡んだ場合に」
ワイ「ほんまの順番通りにはならへんのやな・・・」

娘「そういうことだね」

ワイ「ごめんな娘ちゃん」
ワイ「元々あったエンドポイント、つまりワイと娘ちゃんの記事を一緒に取得できるやつ」
ワイ「もう一回ちゃんと作り直すわ・・・」

## 次の日
ワイ「よっしゃ、できたで！」
ワイ「ワイと娘ちゃんの記事を一緒に取得できるエンドポイントも復活や！」
ワイ「これで完成やな！」

娘「パパ、待って」

<img width="832" alt="スクリーンショット 2020-07-20 22.10.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/1261c6e7-0c9b-b394-33a7-71744395ef3b.png">

娘「さっきも思ったんだけど」
娘「記事が**古い順**に並んでるよね？」
娘「普通は**新しい順**じゃない？」

ワイ「ついにその事に触れてもうたか・・・」

娘「新しい順でソートされた状態で記事を取得するには」
娘「どうすればいいの？」

ワイ「そ、それは・・・分からん・・・」

娘「・・・」

ワイ「フロント側で、新しい順にソートしてくれや・・・」

娘「だから、駄目だって」

ワイ「それも駄目なん・・・？」

## なぜ駄目なのか

娘「**サーバ側で古い順にソートされてる**ってことは」
娘「APIから**一番古い10件の記事**が返ってきてるってことじゃん？」

ワイ「せやな」

娘「それを、フロント側で新しい順にソートすると・・・」

<img width="829" alt="スクリーンショット 2020-07-21 0.24.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/1c6c739b-300d-4b12-dddc-998e312dd27e.png">

娘「↑こんな感じになるの」

ワイ「ええやん、新しい順に表示されとるやん」

娘「そうだね」
娘「新しい順に表示されてるよね」
娘「**一番古い10件が**ね」

ワイ「せや」
ワイ「問題ないやろ」

娘「いや大ありでしょ」
娘「すごく昔の記事が**最新の記事**みたくなっちゃってることが問題なの」

ワイ「どういうこと？」

娘「この画面を見た閲覧者さんは・・・」

> 閲覧者「ふむふむ、このブログは新しい順に記事を表示しとるな」
> 閲覧者「なになに、最新の記事の投稿日は・・・**2018年7月**！？」
> 閲覧者「2年間も更新されとらんやんけ！」
> 閲覧者「技術ブログとして終わっとるな・・・」

娘「って思われちゃうかもしれないよ？」
娘「実際には、**今月書いた記事**とかも沢山あるのに」

ワイ「Oh...」
ワイ「それはアカンわ・・・」

## まとめ
- APIから取得したデータをフロント側でフィルタ・マージ・ソートなどすると、色々と矛盾が生じる。

娘「だから、そういうのは**アンチパターン**なの」
娘「こんなの常識だよ？」
娘「パパ、幼稚園からやり直したら？」

ワイ「いや**幼稚園でAPIのアンチパターン教えてくれるんかい！**」

**〜おしまい〜**