miragejs
ในการพัฒนา Front-end นั้น บางกรณี เช่น ในขั้นตอนการพัฒนาแอพต้นแบบ นักพัฒนาอาจมีความจำเป็นจะต้องเรียกใช้ข้อมูลจาก Back-end API หลายคนอาจเลือกใช้ jsonserver
เพื่อจำลองเป็น Back-end API ในขณะที่ Backend-API ตัวจริง ยังพัฒนาไม่แล้วเสร็จ แต่ jsonserver
เองก็อาจจะสามารถตอบโจทย์การเรียกใช้ข้อมูลแบบง่ายได้เท่านั้น อีกครั้งยังไม่สามารถรองรับการทำ Authentication, JWT, Authorization ซึ่งเราสามารถแก้ปัญหาเหล่านี้ได้โดยใช้ไลบรารี่ที่ชื่อว่า miragejs
miragejs
การทำงานของ miragejs
จะใช้การ Intercept การส่ง XMLHttpRequest
ทั้งหมดของบราวเซอร์ เพื่อให้เราสามารถเขียน Process หรือ Response ได้ตามที่เราต้องการ ซึ่งเราสามารถใช้ miragejs
กับไลบรารี่ Front-end ที่พัฒนาบนภาษา JavaScript เช่น React.js, Vue.js และ อื่นๆ ได้ทุกตัว
miragejs
Terminal
yarn add miragejs
miragejs
โค้ดในส่วนนี้จะเป็นเสมือนการจำลองการ Response ของ Back-end API โดยเราจะกำหนด Route ตามที่แอพของเราต้องการจะเรียกใช้
Code
import { Server } from 'miragejs'
new Server({
routes() {
this.get('/users', () => {
return [
{ id: 1, name: 'Luke' },
{ id: 2, name: 'Leah' },
{ id: 3, name: 'Anakin' }
]
})
}
})
ใน Vue.js เราจะเขียนโค้ดส่วนนี้ไว้ที่ไฟล์ src/main.js, และ ที่ไฟล์ src/index.js ในกรณีของ React.js
สำหรับโค้ดในส่วนของ Front-end ก็จะเป็นการเรียกใช้ XMLHttpRequest
ตามปกติเหมือบกับในกรณีที่เป็นการเรียกข้อมูลจาก Back-end API จริง
Component
async function getUsers() {
const res = await axios.get('/users')
console.log(res.data)
}
เมื่อมีการส่ง
XMLHttpRequest
จากภายในแอพ บราวเซอร์ก็จะถูก Intercept โดยmiragejs
NODE_ENV
เราอาจจะตั้งค่าให้กับ NODE_ENV
สำหรับใช้ใน Development และ Production ตามตัวอย่างด้านล่าง
env.development
REACT_APP_API=
VUE_APP_API=
env.production
REACT_APP_API=https://jsonplaceholder.typicode.com
VUE_APP_API=https://jsonplaceholder.typicode.com
Code
if (process.env.NODE_ENV === 'development') {
new Server({
...
})
}
โดยปกติเราน่าจะมีการใช้งาน
miragejs
เฉพาะในขั้นตอน Development เท่านั้น
Component
async function getUsers() {
const res = await axios.get(`${ REACT_APP_API }/users`)
console.log(res.data)
}
การเขียนโค้ดเพื่อส่ง
XMLHttpRequest
ก็จะใช้ตัวแปรตามNODE_ENV
เราสามารถกำหนดให้ miragejs
ทำการ Response โดยมีการหน่วงเวลาเพื่อสะดวกในการทดสอบ เช่น กรณีของการใช้งาน Spinner
Code
new Server({
routes() {
this.get('/users', () => {
return [...]
}, { timing: 4000 })
}
})
ตัวอย่างการเขียนโค้ดเพื่อจำลองการทำงานของ ReSTful Back-end API
Code
new Server({
routes() {
this.get('/users', () => {
...
})
this.post('/users', () => {
...
})
this.patch('/users/:id', () => {
...
})
this.del('/users/:id', () => {
...
})
}
})
miragejs
สามารถรองรับ Parameterized Route ได้เช่นกัน ตามตัวอย่างโค้ดด้านล่าง
Code
new Server({
routes() {
this.get('/users/:id', (schema, request) => {
const { id } = request.params
return { id }
})
}
})
ตัวอย่างโค้ดในการอ่านค่าจาก Request Body
Code
new Server({
routes() {
this.post('/users', (schema, request) => {
const user = JSON.parse(request.requestBody) // parsing is required
return user
})
}
})
miragejs
สามารถทำ Custom Response เช่น การกำหนด Custom HTTP Status Code ได้เช่นกันตามตัวอย่างโค้ดด้านล่าง
Code
import { Response } from 'miragejs'
new Server({
routes() {
this.post('/users', (schema, request) => {
const user = request.requestBody
return new Response(
201,
{ 'x-custom-header': 'foo/bar' },
user // object or array
)
})
}
})
schema
เราสามารถใช้ schema
เพื่อเป็นเสมือนฐานข้อมูลของ miragejs
รองรับ Data Manipulation เช่น การทำ CRUD เป็นต้น
Code
new Server({
seeds(server) {
server.db.loadData({
users: [
{ name: 'Steve' }, // id will be added automatically
{ name: 'John' }
]
})
},
routes() {
this.get('/users', schema => {
return schema.db.users
})
this.get('/users', (schema, request) => {
const { id } = request.params
return schema.db.users.find(id) // schema's method
})
this.post('/users', (schema, request) => {
const user = JSON.parse(request.requestBody) // parsing is required
return schema.db.users.insert(user)
})
}
})
ตัวอย่างโค้ดในการทำ Authorization โดยใช้การอ่านค่า authorization
จาก Header ของ Request
Code
new Server({
routes() {
this.get('/users', (schema, request) => {
const header = request.requestHeaders
const authorization = header['authorization']
if (!authorization) {
return new Response(
401,
{},
{ message: '401 Unauthorized' }
)
}
return schema.db.users
})
}
})