Mirage.jsを使用してReactアプリでモックAPIを構築および使用する方法

フルスタックアプリケーションを開発する際、フロントエンドの作業の大部分はバックエンドからのリアルタイムデータに依存しています。

これは、APIが使用可能になるまでユーザーインターフェイスの開発を延期しなければならない可能性があることを意味します。しかし、フロントエンドをセットアップするためにAPIの準備を待つことは、生産性を大幅に低下させ、プロジェクトのタイムラインを延長する可能性があります。

この課題に対する優れた回避策には、モックAPIの活用が含まれます。これらのAPIを使用すると、実際のAPIに依存することなく、実際のデータの構造を模倣したデータを使用してフロントエンドを開発およびテストできます。

Mirage.jsモックAPIの概要

Mirage.jsは、Webアプリケーションのクライアント側で実行されるテストサーバーを備えたモックAPIを作成できるJavaScriptライブラリです。これは、実際のバックエンドAPIの可用性や動作を気にすることなく、フロントエンドコードをテストできることを意味します。

Mirage.jsを使用するには、まずモックAPIエンドポイントを作成し、それらが返すレスポンスを定義する必要があります。次に、Mirage.jsはフロントエンドコードが行うすべてのHTTPリクエストを傍受し、代わりにモックレスポンスを返します。

APIの準備ができたら、Mirage.jsの設定を変更するだけで簡単に使用に切り替えることができます。

このプロジェクトのソースコードは、このGitHubリポジトリにあります。

Mirage.jsでモックAPIサーバーを作成する

モックAPIのセットアップ方法を実証するために、Mirage.jsバックエンドを使用するシンプルなToDo Reactアプリを構築します。しかし、最初にcreate-react-appコマンドを使用してReactアプリケーションを作成します。または、Viteを使用してReactプロジェクトをセットアップすることもできます。次に、Mirage.jsの依存関係をインストールします。

npm install --save-dev miragejs

次に、リクエストを傍受し、APIレスポンスをモックするためのMirage.jsサーバーインスタンスを作成するには、createServerメソッドを使用します。このメソッドは、パラメータとして構成オブジェクトを受け取ります。

このオブジェクトには、APIの環境名前空間が含まれています。環境は、APIが開発などの開発段階を指定し、名前空間はすべてのAPIエンドポイントに追加される接頭辞です。

新しいsrc/server.jsファイルを作成し、次のコードを含めます。

import { createServer, Model } from 'miragejs';const DEFAULT_CONFIG = {environment: "development",namespace: "api",};export function makeServer({ environment, namespace } =DEFAULT_CONFIG) {let server = createServer({environment,namespace,models: {Todo: Model,},});return server;}

必要に応じて、バージョンを指定するなど、名前空間を実際のAPIのURL構造に合わせてカスタマイズできます。このようにして、APIの準備ができたら、最小限のコード変更でフロントエンドアプリケーションに簡単に統合できます。

さらに、サーバーインスタンスの構成内で、モック環境でのデータの格納と取得をシミュレートするためのデータモデルを定義することもできます。

最後に、index.jsxまたはmain.jsxファイルにサーバーオブジェクトをインポートして、Mirage.jsサーバーを起動します。

import React from 'react'import ReactDOM from 'react-dom/client'import App from './App.jsx'import { makeServer } from './server';if ( process.env.NODE_ENV === 'development' &&typeof makeServer === 'function') {makeServer();}ReactDOM.createRoot(document.getElementById('root')).render(,)

モックAPIにシードデータを追加する

Mirage.jsには、初期シードデータでモックAPIに事前に入力し、クライアントアプリケーションからテストデータを管理するために使用できるインメモリデータベースがあります。これは、モックデータベースからテストデータを格納して取得し、クライアントアプリケーションで使用できることを意味します。

モックAPIにシードデータを追加するには、server.jsファイルのmodelsオブジェクトのすぐ下に次のコードを追加します。

seeds(server) {server.create('Todo', {title: 'item no 1',body:'Do something nice for someone I care about',});server.create('Todo', {title: 'item no 2',body:'Memorize the fifty states and their capitals.',});server.create('Todo', {title: 'item no 3',body:'Watch a classic movie.',});},

seeds関数は、Mirage.jsサーバーにそれぞれタイトルと説明を持つ3つのToDoアイテムを入力します。オプションで、テストデータをハードコーディングする代わりに、Faker.jsなどのライブラリを統合して必要なテストデータを生成できます。

モックAPIルートの定義

次に、モックAPIのAPIルートを定義します。この場合、GET、POST、DELETEのモックAPIリクエストを処理するルートを指定します。

シードデータのすぐ下に、以下のコードを追加します。

routes() {this.namespace = 'api/todos';this.get('/', (schema, request) => {return schema.all('Todo');});this.post('/', (schema, request) => {let attrs = JSON.parse(request.requestBody);return schema.create('Todo', attrs);});this.delete('/:id', (schema, request) => {let id = request.params.id;return schema.find('Todo', id).destroy();});}

Reactクライアントを構築する

モックAPIがセットアップされたので、Reactクライアントを構築してAPIエンドポイントと対話し、それらを使用しましょう。お好きなUIコンポーネントライブラリを自由に使用できますが、このガイドではChakra UIを使用してアプリのスタイルを設定します。

最初に、これらの依存関係をインストールします。

npm install @chakra-ui/react @emotion/react @emotion/styled framer-motion

次に、新しいsrc/components/TodoList.jsxファイルを作成し、次のコードを含めます。

import React, { useState, useEffect } from 'react';import {Button,Box,Container,Text,Input,FormControl,Flex,} from '@chakra-ui/react';

次に、新しいタスクを追加するための入力フィールドと既存のタスクのリストを含む、ToDoリストのユーザーインターフェイスをレンダリングする関数コンポーネントを定義します。

export default function TodoList() {return (Todo List Add Todo{loading ? ( Loading... ) : (todos.map((todo) => ({todo.body} handleDelete(todo.id)}>Delete)))});}

次に、追加および削除操作のハンドラー関数を定義します。しかし、最初にこれらの状態を追加します。または、useReducerフックを使用して、ToDoリストアプリの状態管理ロジックを定義できます。

const [todos, setTodos] = useState([]);const [newTodo, setNewTodo] = useState({ title: '', body: '' });const [loading, setLoading] = useState(true);const [renderKey, setRenderKey] = useState(0);

次に、useEffectフックでfetchメソッドをラップして、アプリケーションが最初にブラウザにロードされたときにインメモリデータベース内のシードデータを取得して表示するロジックを定義します。

useEffect(() => {fetch('/api/todos').then((response) => response.json()).then((data) => {setTodos(data.todos);setLoading(false);});}, [renderKey]);

renderKey状態もuseEffectに含まれており、サーバーが実行されているときにインメモリデータベースに新しく追加されたデータの再レンダリングが確実にコードによってトリガーされます。

簡単に言えば、ユーザーがMirage.jsデータベースに新しいToDoデータを追加すると、コンポーネントは再レンダリングされて更新されたデータが表示されます。

APIにデータを追加する

次に、POSTリクエストを介してAPIにデータを追加するためのロジックを定義します。useEffectフックのすぐ下に、次のコードを含めます。

const handleInputChange = (e) => {const { name, value } = e.target;setNewTodo((prevTodo) => ({ ...prevTodo, [name]: value }));};const handleAddTodo = () => {setLoading(true);fetch('/api/todos', {method: 'POST',headers: {'Content-Type': 'application/json',},body: JSON.stringify(newTodo),}).then((response) => response.json()).then((createdTodo) => {setTodos((prevTodos) => [createdTodo, ...prevTodos]);setNewTodo({ title: '', body: '' });setRenderKey((prevKey) => prevKey + 1);setLoading(false);}).catch((error) => {console.error('Error adding todo:', error);setLoading(false);});};

ユーザーがToDo入力フィールドにデータを入力してTodoを追加ボタンをクリックすると、コードはnewTodo状態をユーザーの入力で更新します。次に、リクエストボディに新しいデータオブジェクトを含むモックPOSTリクエストをAPIに送信して、インメモリデータベースに保存します。

POSTリクエストが成功すると、コードは新しいアイテムをtodos配列に追加し、最後にコンポーネントの再レンダリングをトリガーして新しいToDoアイテムを表示します。

モックAPI DELETEリクエスト

次に、DELETEモックAPIリクエストを介してデータを削除するためのロジックを定義します。このプロセスには、インメモリデータベースからToDoアイテムを削除するためにDELETEリクエストを送信することが含まれます。成功した場合は、todosloadingの両方の状態を更新して削除プロセスを反映します。

const handleDelete = (id) => {let deleteInProgress = true;fetch(`/api/todos/${id}`, {method: 'DELETE',}).then((response) => {if (response.status === 204) {return null;} else {return response.json();}}) .then((data) => {if (data && data.error) {console.error('Error deleting todo:', data.error);} else {setTodos((prevTodos) => prevTodos.filter((todo) => todo.id !== id));setRenderKey((prevKey) => prevKey + 1);}deleteInProgress = false;}).catch((error) => {console.error('Error deleting todo:', error);deleteInProgress = false;}) .finally(() => {setLoading(deleteInProgress);});};

このプロセスでは、シードデータではなく、新しく追加されたデータのみを削除できることに注意してください。

最後に、App.jsxファイルにTodoListコンポーネントをインポートして、DOMでレンダリングします。

import TodoList from './components/TodoList';//code ...

素晴らしい!開発サーバーを起動すると、シードデータを取得し、ReactアプリのモックAPIから新しいデータを追加および削除できます。

モックAPIを使用して開発をスピードアップする

モックAPIは、個人でプロジェクトに取り組んでいる場合でも、チームの一員として取り組んでいる場合でも、フロントエンドの開発を加速させる素晴らしい方法です。モックAPIを使用することで、バックエンドの完成を待たずに、UIを迅速に構築してコードをテストできます。