LoginSignup
1
0

More than 1 year has passed since last update.

Building Api Mock Environment

Last updated at Posted at 2021-07-29

Building Environment

  1. express
  2. connect-api-mocker
  3. axios
  4. VueX
  5. Impliment Todo App

1. express

http://expressjs.com/en/starter/installing.html

Hello world example

$ npm install express

$ mkdir api
$ touch api/index.js

$ vim api/index.js

// api/index.js
const express = require('express')
const app = express()
const port = 8080

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

module.exports = {
  path: '/api',
  handler: app
}

$ vim nuxt.config.js

// nuxt.config.js
export default {
  // ...
  serverMiddleware: ['../api']
}

2. connect-api-mocker

https://github.com/muratcorlu/connect-api-mocker

Using with Express

$ npm install connect-api-mocker --save-dev

$ vim api/index.js

// api/index.js
const express = require('express')
const apiMocker = require('connect-api-mocker')
const app = express()

app.use('/api', apiMocker('mocks/api'))
app.listen(8080)

module.exports = {
  path: '/api',
  handler: app
}

Endpoint not found on mock files:

Resolution

$ mkdir -p __mock__/api/messages
$ touch __mock__/api/messages/GET.json

$ vim __mock__/api/messages/GET.json

{ "message": "hello, api" }

$ vim api/index.js

// api/index.js
  // ...
  app.use('/api', apiMocker('mocks/api', '__mock__/api'))

3. axios

https://axios.nuxtjs.org/

Setup

$ yarn add @nuxtjs/axios

$ vim nuxt.config.js

// nuxt.config.js
export default {
  // ...
  modules: ['@nuxtjs/axios']
}

Usage

$ vim pages/index.vue

// pages/index.vue
export default {
  // ...
  async asyncData({ $axios }) {
    const ip = await $axios.$get('/messages')
    console.log(ip)
    return { ip }
  }
}

Uncaught (in promise) Error: Request failed with status code 404

Resolution

$ vim nuxt.config.js

// nuxt.config.js
export default {
  // ...
  axios: {
    prefix: '/api',
    proxy: true
  },
  proxy: {
    '/api/': 'http://localhost:8080'
  }
}

4. VueX

https://ja.nuxtjs.org/docs/2.x/directory-structure/store

モジュール

$ mkdir store
$ touch store/todos.js

$ vim store/todos.js

// store/todos.js
export const state = () => ({
  list: []
})

export const mutations = {
  add(state, text) {
    state.list.push({
      text,
      done: false
    })
  },
  remove(state, { todo }) {
    state.list.splice(state.list.indexOf(todo), 1)
  },
  toggle(state, todo) {
    todo.done = !todo.done
  }
}

$ touch pages/todos.vue

$ vim pages/todos.vue

// pages/todos.vue
<template>
  <ul>
    <li v-for="todo in todos" :key="todo.text">
      <input :checked="todo.done" @change="toggle(todo)" type="checkbox">
      <span :class="{ done: todo.done }">{{ todo.text }}</span>
    </li>
    <li><input @keyup.enter="addTodo" placeholder="What needs to be done?"></li>
  </ul>
</template>

<script>
import { mapMutations } from 'vuex'

export default {
  computed: {
    todos () {
      return this.$store.state.todos.list
    }
  },
  methods: {
    addTodo (e) {
      this.$store.commit('todos/add', e.target.value)
      e.target.value = ''
    },
    ...mapMutations({
      toggle: 'todos/toggle'
    })
  }
}
</script>

<style>
.done {
  text-decoration: line-through;
}
</style>

5. Impliment Todo App

$ mkdir __mock__/api/todos
$ touch __mock__/api/todos/GET.json

$ vim __mock__/api/todos/GET.json

{ "todos":
  [
    {
      "text": "aaa",
      "done": true
    },
    {
      "text": "bbb",
      "done": false
    }
  ]
}

$ vim store/todos.js

export const state = () => ({
  list: []
})

export const mutations = {
  add(state, data) {
    const list = Array.isArray(data) ? data : [{
      text: data,
      done: false
    }]
    list.forEach(data => {
      state.list.push(data)
    })
  },
  remove(state, { todo }) {
    state.list.splice(state.list.indexOf(todo), 1)
  },
  toggle(state, todo) {
    todo.done = !todo.done
  }
}

export const actions = {
   async fetch({ commit }) {
    const path = `/todos`
    const { todos } = await this.$axios.$get(path)
    commit('add', todos)
  }
}

$ vim pages/todos.vue

<template>
  <div>
    <ul>
      <li v-for="todo in todos" :key="todo.text">
        <v-checkbox
          v-model="checkedList"
          :class="{ done: todo.done }"
          :label="todo.text"
          :value="todo.text"
          @change="toggle(todo)"
        ></v-checkbox>
      </li>
      <li>
        <v-text-field @keyup.enter="addTodo" placeholder="What needs to be done?"></v-text-field>
      </li>
    </ul>
  </div>
</template>

<script>
  import { mapState, mapMutations } from 'vuex'
  export default {
    async fetch({ store, params }) {
      await store.dispatch('todos/fetch')
    },
    created() {
      this.todos.forEach(todo => {
        if (todo.done) this.checkedList.push(todo.text)
      })
    },
    data() {
      return {
        checkedList: []
      }
    },
    computed: {
      ...mapState ({
        todos: state => state.todos.list
      })
    },
    methods: {
      addTodo (e) {
        this.add(e.target.value)
        e.target.value = ''
      },
      ...mapMutations({
        toggle: 'todos/toggle',
        add: 'todos/add'
      })
    }
  }
</script>

<style>
  .done label {
    text-decoration: line-through;
  }
</style>
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0