Help us understand the problem. What is going on with this article?

React.jsアプリケーションとREST APIのスタブをローカルで同時に起動する

More than 3 years have passed since last update.

背景

React.js(create-react-app)を元に
REST APIとのつなぎ込みが必要なフロントエンドの開発をしていると、
APIの返す値が異なる条件での動きを手元で検証したいときがある。

View側にモックを埋め込むのは微妙なので、APIのスタブが欲しい。

サーバ側にログインするのは面倒なので、開発機にAPIサーバを立て、
ローカルのjsonを編集するとレスポンスも変わるようにしたい。

概要

  • Expressを使ったREST APIのBoilerplateを改変し、ローカルのjsonファイルを参照させる
  • フロント側のpackage.jsonで、Reactのアプリケーションとスタブを同時起動させる

スタブのセットアップ

https://github.com/developit/express-es6-rest-api

を利用

ソースの取得

# githubからclone
git clone git@github.com:developit/express-es6-rest-api.git
# ディレクトリ名をstubに変更
mv express-es6-rest-api stub
# package.json生成
cd stub
rm -rf .git && npm init

DB依存箇所の削除

今回はローカルのjsonを返すので、DBに関わるファイルを削除。

rm src/db.js
rm src/api/facets.js
rm -r src/lib/
rm -r src/models/

DB依存箇所を書き換え

ファイル依存するように書き換えていく

src/index.js

import http from 'http'
import express from 'express'
import cors from 'cors'
import morgan from 'morgan'
import bodyParser from 'body-parser'
import middleware from './middleware'
import api from './api'
import config from './config.json'

let app = express()
app.server = http.createServer(app)

// logger
app.use(morgan('dev'))

// 3rd party middleware
app.use(cors({
  exposedHeaders: config.corsHeaders
}))

app.use(bodyParser.json({
  limit: config.bodyLimit
}))

// internal middleware
app.use(middleware({ config }))

// api router
app.use('/stub/api', api({ config }))

app.server.listen(process.env.PORT || config.port)

console.log(`Started on port ${app.server.address().port}`)

export default app

src/middleware/index.js

import { Router } from 'express'

export default () => {
  let routes = Router()

  // add middleware here

  return routes
}

src/api/index.js

import { version } from '../../package.json'
import { Router } from 'express'
import fs from 'fs'

const readJson = (path) => {
  // パスは stub/ からの相対パス
  return JSON.parse(fs.readFileSync(path, 'utf8'))
}

export default ({ config }) => {
    let api = Router()

    api.get('/users/me', (req, res) => {
        res.json(readJson('./src/api/users/GET/me.json'))
    })
    api.get('/users/:id', (req, res) => {
        res.json(readJson('./src/api/users/GET/id.json'))
    })

    return api;
}

apiのディレクトリに以下のファイルを設置

  • src/api/users/GET/me.json
  • src/api/users/GET/id.json

APIを起動し、疎通確認

# API起動
npm run start
# 動作確認 (先程設置したjsonが返ってくる)
curl -X GET 'http://localhost:8080/stub/api/users/me'
curl -X GET 'http://localhost:8080/stub/api/users/2'

フロント側の修正

React.jsアプリケーションとスタブを同時起動する設定

  • package.json の devDependencies に npm-run-all を追加 (複数タスクの並列実行に必要)
  • package.json の scripts に以下の3行を追加
    "local": "run-p local:*",
    "local:start": "react-scripts start",
    "local:stub": "cd ./stub; npm run start",

これを設定すると、 以後は npm run local
フロントとスタブが同時に起動するようになる。

stubの生成物をgitにcommitしないようにする

フロント側の .gitignore に 以下を追記

# stub
stub/dist
yumemi
みんなが知ってるあのサービス、実はゆめみが作ってます。スマホアプリ/Webサービスの企画・UX/UI設計、開発運用。Swift, Kotlin, PHP, Vue.js, React.js, Node.js, AWS等エンジニア・クリエイターの会社です。Twitterで情報配信中https://twitter.com/yumemiinc
http://www.yumemi.co.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away