今でも一針一針でMockDataを作っていますか?「Mock Service Worker」と書きましょう.🤡


What is Mock Service Worker !?


テストサーバを作成する必要がなく、サーバの最適な方法をシミュレートできます.msw!
通常、データを取得する必要がある場合は、通信によって応答するサーバが必要です.サーバがまだ完全に構築されていない段階で、フロントエンド開発者はAPI呼び出しに関するテストをシミュレートする.そして、この過程は一般的な煩雑な仕事ではない.もちろん、mockingサーバを別途製造することもできますが、これはもっと面倒な仕事です.これらの開発者の苦衷はmswによって解決された.


mswはどのようにAPIの真似を助けたのでしょうか。


Mock Service Workerの名称から分かるように、mswService Workerを用いる.Service Workder APIはすべてのモダンブラウザが提供する標準APIです!MDN公式文書を参照してください.「歩行者サービス」の詳細な概念について説明します.


msw学習の鍵の一つは、Service Workerがプロキシサーバと言えることです.Service Workerでは、リソースリクエストをブロックおよび変更したり、リソースをキャッシュおよび操作したりできます.つまり,ネットワークが利用できない場合でも,開発者は開発中のWebアプリケーションをどのように動作させるべきかを操作できる!



『p>mswの概念もService Workder APIとあまり変わらない!』br/>mswの公式ページから提供される画像です.



ブラウザからの要求がService Workerによってブロックされると、MSWが追跡された応答を返していることがわかります.



Mock Service Worker is an API mocking library that uses Service Worker API to intercept actual requests.



上記の公式文書mswの説明は間違いなく理解できるようになった.

すなわち、mswは、ユーザ要求をサーバに送信するのではなく、ネットワークレベルで中断し、任意のデータに応答するライブラリに要約することができる!


mswを使いましょう!


ではmswを試してみましょう!正式な書類を考察すると,mswはreactとgraphqlともに対応していることが分かった.また、Rest APIやGraphQLまで真似できます!


今日この記事では、Reactでmswを使用します!


ちなみに、npx create-ract-appは初めて

$ npx create-react-app msw-practice

まず、上記のようにreactプロジェクトを開始します.(もちろん、プロジェクト名は任意に命名できます.)


MSW頑張れ!

$ npm install msw --save-dev
# or
$ yarn add msw --dev

このようにインストールした後、package.jsonを検査し、開発依存モジュールでmswを検査することができる.



mocksフォルダを作成!


srcフォルダ内にmocksフォルダを作成します.
mocksフォルダの内部には2つのファイルが必要です!(node.js実行環境で実行する場合は、もう1つ必要ですが、ここでは省略します.このセクションは、公式ホームページのメイン画面で説明したサンプルコードで検証できます.)



プロセッサはmocksフォルダにあります。jsを生成します。


handlers.jsは、サーバ上でコントローラを記述するのと同様である.

これは、ブラウザが発行したリクエストを中断したときに、どのエンドポイントとリクエストに基づいてどのような結果を返すかを予め作成したプロセスです.

// graphql을 이용하려면, graphql을 꺼내오면 된다.
// 현재 여기서는 restAPI로 실습하기 위해 rest를 꺼내왔다.
import { rest } from "msw";

export const handlers = [
  rest.get("https://pokeapi.co/api/v2/pokemon/", async (req, res, ctx) => {
    return res(
      ctx.json({
        count: 1118,
        next: "https://pokeapi.co/api/v2/pokemon/?offset=20&limit=20",
        previous: null,
        results: [
          {
            name: "이상해씨",
            url: "https://pokeapi.co/api/v2/pokemon/1/",
          },
          {
            name: "이상해풀",
            url: "https://pokeapi.co/api/v2/pokemon/2/",
          },
          {
            name: "이상해꽃",
            url: "https://pokeapi.co/api/v2/pokemon/3/",
          },
          {
            name: "파이리",
            url: "https://pokeapi.co/api/v2/pokemon/4/",
          },
          {
            name: "리자드",
            url: "https://pokeapi.co/api/v2/pokemon/5/",
          },
          {
            name: "리자몽",
            url: "https://pokeapi.co/api/v2/pokemon/6/",
          },
          {
            name: "꼬부기",
            url: "https://pokeapi.co/api/v2/pokemon/7/",
          },
          {
            name: "어니부기",
            url: "https://pokeapi.co/api/v2/pokemon/8/",
          },
          {
            name: "거북왕",
            url: "https://pokeapi.co/api/v2/pokemon/9/",
          },
        ],
      })
    );
  }),
];

ポケモンに関する情報を簡単にロードする練習のために、上記の内容を記述した.


そしてブラウザです。jsファイルを書いてあげます。


browser.jsは、mswが提供するサービスキットを取得し、上記で作成したプロセッサをパラメータとして渡す.

import { setupWorker } from "msw";
import { handlers } from "./handlers";

export const worker = setupWorker(...handlers);

まだ終わってない!msw初期化しよう!


このようにしてmswを直接使用することはできません.

正式なドキュメントをよく見ると、cliは以下のコマンドを使用してinitを行う必要があります.

$ npx msw init <PUBLIC_DIR> --save

PUBLIC DIRは、使用するフレームワークやライブラリによって異なります.reactを使用しています.public/を入力すればいいです.


次に、APIを要求するコンポーネントを作成します。


コンポーネントフォルダ内にPokemonInfoというコンポーネントを作成します.以下に示します!

import React, { useEffect, useState } from 'react';
import axios from 'axios';

const PokemonCard = ({name, url}) => {

  const [photoUrl, setPhotoUrl] = useState("");

  useEffect(() => {
    axios.get(url)
    .then(res => {
      setPhotoUrl(res.data.sprites.front_default);
    })
    .catch(error => {
      console.log(error)
    })
  })

  return (
    <div>
      <img src={photoUrl} alt={`${name}-front-default`} />
      <h3>{name}</h3>
    </div>
  )
}

const mainUrl = "https://pokeapi.co/api/v2/pokemon/"

export default function PokemonList() {
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);

  const handleClick = () => {
    axios.get(mainUrl)
      .then(response => {
        setData(response.data);
      })
      .catch(error => {
        setError(`Something Wrong: ${error}`);
      })
  }

  if(error) {
    return <p>{error}</p>
  }

  return (
    <div>
      <button onClick={handleClick}>포켓몬 정보 조회하기</button>
      {data && (
        <div>
          {data.results.map((pokemon) => {
            return <PokemonCard 
              key={`${pokemon.name}-${pokemon.url}`} 
              name={pokemon.name} 
              url={pokemon.url}/>
          })}
        </div>
      )}
    </div>
  )
}

では、今からプロジェクトを実行しましょう。



<>どこがおかしい!明らかに、handlers.jsの中で、私たちはハングルでポケモンたちに名前をつけました.br/>
さらに、ネットワークラベルを表示すると、pokemonへの応答はサービスキットから来ていないことがわかります.現在の応答はPokeAPIから来ています!すなわち、サービス労働者は要求を中断しなかった.



index.jsに移動!


私たちが逃した最後のステップは、index.jsでService Walkerを実行することです!

//Start the mocking conditionally/
if (process.env.NODE_ENV === "development") {
  const { worker } = require("./mocks/browser");
  worker.start();
}

index.js renderの上部に上記のコードを追加!

プロジェクトを再実行し、APIリクエストを送信!



こんなに小さくて精巧でかわいいポケモンたちを見ることができます!

また、ネットワークタグを開くと、ステータスコードの横にfrom service workerのヒント語が表示されます.


これはなんと驚くべきことだろう。


先端ボランティア案内キャンプの生徒たち!

現在、プロジェクト計画が終了した後、バックエンドの同僚がAPIを導入するのを待たないでください.

urlをlocalhostに戻して、やり直す~後で修正しないで!

テストコードにすべての木材データを作成しないでください!


msw!