herohoroブログ

APIのreq/resがいまいち分からないから作って遊んで浸透させることにした_Blog learn02



🔄   2022-08-02

前回レイアウトを再現していい感じになりました。

image block

https://herohoro.com/blog/blog-learn-layout_start

今回はこのレイアウトにAPI機能を追加してツヨツヨにするべく、

APIで頻出の「req」や「res」についてのモヤモヤと向き合いながら、

公式learnのサンプルを実装や、

Blog learn用に作ってきたレイアウトへの追加をしていきます。

Notion API前夜的な位置づけでお送りいたします🕺🏻🕺🏻🕺🏻🕺🏻🕺🏻🕺🏻🕺🏻🕺🏻🕺🏻🕺🏻

とにかく分からないreqとres

今まで果敢に攻めようとAPIの解説記事を読みあさったこともありましたが.......

reqとresの意味がチンプンカンプンでした。

図解があってもワカラナイ........

丁寧な解説動画を見てもワカラナイ.......

requestとresponseなんて言われたってもっとワカラナイ.....

reqが要求でres応答って訳されたってワカラナイ.......

😵‍💫
PCが何かを要請して、PCが応答する....ってどういうこと?自作自演じゃん!!

これは私の国語力の低さが影響しているのかもしれない.....

ということに気づき、

とにかく作ってみることにしました。

作ってうまく行かなければ捨てればいい。

エラーにハマったら迷わず作り直せばいい....。

やり直しをすぐにできるようになるべく数行で実装できて、

コードの内容もシンプルなものを選びました🙆🏻‍♀️

resとreqって簡単に言うと?

👉指定された注文に対して反応すること

イメージできないので

とりあえずNext.js learnにあるサンプルを実装してみることにしました。

resのみにするとどうなる?

👉反応(表示)したまま

https://nextjs.org/learn/basics/api-routes/creating-api-routes

export default function handler(req, res) {
  res.status(200).json({ text: 'Hello' })
}

image block

手入力でapi/helloをURLに追加してあげないと表示されないってことを理解。

何かをクリックするとパンって飛んでこの画面が表示されることはない。

入力してどうこうすることもない。。。。

😵
ファイル構成が分からない人には絶対表示することはできないね......

それがres っていう役割か.......(´・ω・`)

🤔
これじゃ、待ちぼうけ状態で可愛そう.......

reqからresへ注文させよう

Next.js docにreq/resをつかったformサンプルが紹介されていたので、

入力フォームを作ってみることにしました。

image block

https://nextjs.org/docs/guides/building-forms

完全写経ではなく、使いたい部分のみ実装してます。m(_ _)m

image block

apiフォルダのuser.tsxへsubmitするんだよっていうform

image block

blogページ(index.tsx)でsubmitされたデータをres(表示)してねっていう注文

😃
入力formに記入されてsubmitボタンが押される=Zapierでいうところの「トリガー」として動き出すってことか......

reqからresへ注文が入ることで待ちぼうけしないですむってことだね\(^o^)/

🤔
でも、ブログって外部のNotionからデータを持ってきて表示しているから直接入力するのとは少し違うよな......

外部からデータを持ってくる_Data fetching

少しずつ難しくなってきましたが、

req/resがわかればこっちのもの。

作ってみた:選んだタイトルのデータを表示する....
image block

Choose a verseによって内容が切り替わります⭐

image block

https://codesandbox.io/embed/fetch-learn-yw6d60?fontsize=14&hidenavigation=1&theme=dark

👆code sandboxのリンクへ飛ぶとverseを選んで表示の確認操作を試せますよ——👯

このサンプルは、mdn web docsというサイトの解説で扱われていました⭐

実際のアプリケーションでは、PHP や Python、Node のようなサーバサイド言語を使ってデータベースから取り出したデータをリクエストする場合が多いでしょう。ですがここでは簡単にしておき、クライアント側のパートに集中します。

外部データをverse1.txtとverse2.txtとして、

実際組み立てるのはindex.htmlのみ!!

※ 今回verse3, verse4は省略しています.....

▼ ファイル構成

  • index.html
  • package.json
  • verce1.txt
  • verce2.txt

<script>
      const verseChoose = document.querySelector("select");
      const poemDisplay = document.querySelector("pre");

      verseChoose.onchange = function () {
        const verse = verseChoose.value;
        updateDisplay(verse);
      };
      function updateDisplay(verse) {
        verse = verse.replace(" ", "");
        verse = verse.toLowerCase();
        let url = verse + ".txt";

        let request = new XMLHttpRequest();
        request.open("GET", url);
        request.responseType = "text";
        request.onload = function () {
          poemDisplay.textContent = request.response;
        };
        request.send();
      }
      updateDisplay("Verse 1");
      verseChoose.value = "Verse 1";
    </script>
index.htmlのscript部分

script部分のコードの解説が詳しく載っていてreqにするまでの前処理の工程が勉強になりました。

image block

https://developer.mozilla.org/ja/docs/Learn/JavaScript/Client-side_web_APIs/Fetching_data#xmlhttprequest

解説の中でコードリンクがあるのですが......少し注意点を発見。

https://github.com/mdn/learning-area/tree/main/javascript/apis/fetching-data

image block
⚠️
説明ではajax-start.htmlとあるけど、リンクを踏むとエラー。ファイルの変更があったのかな......

部分的に?な要素があっても参照リンクが埋め込まれていて効率よく学ぶことができました(*^^*)

image block

document.querySelector("pre").textContent に書き換えれば納得!

▶ https://developer.mozilla.org/ja/docs/Web/API/Node/textContent

request.response はリクエストの内容を表示する

▶ https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest/response

Next.jsで実装してみよう

Next.js learnではmdファイルからデータを取り出して表示していました。

ファイル構成(関係あるファイルのみ抜粋)

  • posts
    • first-log.md
    • second-log.md
  • src
    • lib
      • posts.tsx
    • pages
      • index.tsx
    • styles

---
title: "Two Forms of Pre-rendering"
date: "2020-01-01"
---

Next.js has two forms of pre-rendering: **Static Generation** and **Server-side Rendering**. The difference is in **when** it generates the HTML for a page.

- **Static Generation** is the pre-rendering method that generates the HTML at **build time**. The pre-rendered HTML is then _reused_ on each request.
- **Server-side Rendering** is the pre-rendering method that generates the HTML on **each request**.

Importantly, Next.js lets you **choose** which pre-rendering form to use for each page. You can create a "hybrid" Next.js app by using Static Generation for most pages and using Server-side Rendering for others.
posts/first-log.md

import fs from "fs";
import path from "path";
import matter from "gray-matter";
//current working directory
const postsDirectory = path.join(process.cwd(), "posts");

export function getSortedPostsData() {
  // Get file names under /posts
  const fileNames = fs.readdirSync(postsDirectory);
  const allPostsData = fileNames.map((fileName) => {
    // Remove ".md" from file name to get id
    const id = fileName.replace(/\.md$/, "");

    // Read markdown file as string
    const fullPath = path.join(postsDirectory, fileName);
    const fileContents = fs.readFileSync(fullPath, "utf8");

    // Use gray-matter to parse the post metadata section
    // テキストデータ内上部にある「 ---」で囲まれた部分をdataとして位置づけて取得する
    const matterResult = matter(fileContents);

    // Combine the data with the id
    // Combine the data【---で囲まれた部分】 with the id【拡張子無しファイル名】
    return {
      id,
      ...(matterResult.data as { date: string; title: string })
    };
  });
  // Sort posts by date
  return allPostsData.sort((a, b) => {
    if (a.date < b.date) {
      return 1;
    } else {
      return -1;
    }
  });
}
src/lib/posts.tsx
import { getSortedPostsData } from "../lib/posts";
import { GetStaticProps } from "next";

export const getStaticProps: GetStaticProps = async () => {
  const allPostsData = getSortedPostsData();
  return {
    props: {
      allPostsData
    }
  };
};
src/pages/index.tsx のgetStaticsProps部分
💫
libで下ごしらえしたgetSortedPostsDataを使ってpropsとして使いまわしちゃうよってことか—(*´∀`*)!!!

export default function RenderPage({
  allPostsData
}: {
  allPostsData: {
    date: string;
    title: string;
    id: string;
  }[];
}) {
  return (
    <div className={styles.container}>
      <div>
        //省略
      </div>
      <section>
        <h3>verse data</h3> //正確にはverseではなくNext.jsのレンダリングについての内容でした....
        <ul>
          {allPostsData.map(({ id, date, title }) => (
            <li key={id}>
              {title}
              <br />
              {id}
              <br />
              {date}
            </li>
          ))}
        </ul>
      </section>
    </div>
  );
}
src/pages/index.tsx のexport default部分
🤔
allPostsDataに対してid, date, titleのセットを1セットずつ値を変えながら表示していってる......
image block

まとめ

reqで注文して、

resで反応する。

それがAPI routingと言われている動き。

外部からデータを持ってきて表示することを

data fetchingと言われていて、

表示させるために下準備をしておいて、

propsを使って差し替えながら使い回す。

こんな感じの動きをしていることが分かってきた\(^o^)/\(^o^)/

今回使ったコードはこちら
No.branchdescriptionリンクPR
7rseo19API routing _入力フォームhttps://github.com/herohoro/Blog_learn/pull/9#9
8rw064kData fetching _収納したディレクトリからテキストデータを表示_libhttps://github.com/herohoro/Blog_learn/pull/10#10

https://github.com/herohoro/Blog_learn/wiki

easy-notion-blogはNotionからデータを取ってくるので、

Notion APIの知識も必要そう.......

ってことで次回はいよいよNotion APIと戯れます\(^o^)/

Twitterでは更新のお知らせを随時行っています

興味ある方はLet'sフォロー★

▼ この記事に興味があったら同じタグから関連記事をのぞいてみてね

新着記事を通知したい??


RSSリーダーにatomのリンクを登録すると通知が行くよ🐌

https://herohoro.com/atom

やってみてね(*´ω`*)(*´ω`*)

Twitter Timeline


フォロー大歓迎\(^o^)/