一樣開始前請記得在 local 端開好前端、後段:
後端:json-server --watch db.json --port 10000
前端:npm start
前幾天都圍繞在 axios
的 CRUD 上,
語法大概長這樣:
axios.get('http://localhost:10000/posts')
axios.post('http://localhost:10000/posts/', {
id: 4,
title: '我是第4篇文章',
author: 'Misado'
})
axios.patch('http://localhost:10000/posts/6', {
title: '我是第6篇文章 0914修改',
})
axios.delete(`http://localhost:10000/posts/${id}`)
無論是哪個動作,都需要帶 url
,
而我們下的都是 絕對位址, (EX. http://localhost:10000
)
但實際上前端不太會這樣下,
是因為:
假設 server 的 domain 換掉,
你就得來把 call 的 url 換掉,
那換一次就得改一次。
(雖然理論上不會常換就是了,但是光需要換就是一件麻煩事了。)
前端通常不是去 call 遠端的 API,(通常前後端是住一起)
所以不需要 call 到絕對位址
那問題來了,
前端該怎麼 call 跟它同一台 server 的 API url 呢?
也許有 call 過 API 經驗的人或是在一些範例看過像是以下這樣的 url:/api/v1/posts
/api/v1/order
/api/v1/PlantEpidemicType
後端 API url 通常都會是 /api/v1
開頭,
(要訂成別的當然也可以,但這應該已經是約定俗成了)
這個就是相對位址的概念哦,
當然該怎麼訂是後端的工作,
而訂完後端會跟前端說你要怎麼 call API,
例如你要取得會員資料要 call /api/v1/member
,
要取得訂單資料要 call /api/v1/order
...等等。
雖然前端不用知道怎麼訂 url,
但為了要讓我們自己可以試 call 這樣的 url,
我們就自己來試試看吧!
JSON server 有提供 routes
的功能,
官方文件有寫設定 routes
的教學,
那我們先跟著做做看,
首先準備一個 routes.json
,
{
"/api/*": "/$1",
}
設定完了,起 API 時記得下參數讓它吃到 routes 的設定,
像這樣:
json-server --watch db.json --port 10000 --routes routes.json
官方文件還有提到,
如果 routes 這樣設定,
那麼你的 url 下 /api/posts
就可以存取到 /posts
,
也就是 /api/
後面接怎樣的參數你就會可以存取到怎樣的資訊,
像這樣:
/api/posts # → /posts
/api/posts/1 # → /posts/1
因此我們可以先到瀏覽器這樣下下看:http://localhost:10000/posts
=> 原本是這樣下http://localhost:10000/api/posts
=> 新的下法
看起來都可以存取到一樣的資料。
那我們現在就來改 axios.get
的 url,
原本是這樣寫的:axios.get('http://localhost:10000/posts')
那我們改寫一下,像這樣:
const hostUrl = "http://localhost:10000";
... (略)
function fetchData(){
axios.get(`${hostUrl}/api/posts`)
.then(function (response) {
console.log(response);
setdataResult(response.data);
setDataFetchTimes(dataFetchTimes+1);
})
.catch(function (error) {
alert("抓取資料錯誤,請確認後再試");
console.log(error);
})
}
看起來沒有問題,
但我這邊要先說明一下,url
我暫時這樣寫 axios.get(`${hostUrl}/api/posts`)
,
不然會導致 call 不到 API,
這邊就小小試一下如果 axios.get('/api/posts')
只這樣 call 會發生什麼事↓
(因此一般通常來說 host
不需要寫,
在 server 或哪邊會進行設定,
不過我目前也不知道要在哪設定,
所以這邊的 /api/
前面還是有先帶 host。)
以上測試 OK 之後我們把 routes.json
改成 /api/v1
試試看,
像這樣:
{
"/api/v1/*": "/$1"
}
改完之後重起 JSON server,
那前端的語法我們先故意不要改試試看:
沒錯,現在是 call 不到的哦,
因為 API 現在只接收 /api/v1
開頭的語法,
那我們把前端語法改對試試看:
axios.get(`${hostUrl}/api/v1/posts`)
看起來就沒有問題了~
(PS. 可以用 console.log(response)
看 request 裡的 reponseURL 來確定 call 的 API url,
之後 call API 遇到問題都鼓勵 console.log 印出來看,拿來 trouble shooting 很好用)
那現在我們就把前幾天的 post
, patch
, delete
都改成新的 url 試試看,
像這樣:
axios.post(`${hostUrl}/api/v1/posts/`, {
id: 7,
title: '我是第7篇文章',
author: 'Misado'
})
axios.patch(`${hostUrl}/api/v1/posts/6`, {
title: '我是第6篇文章 0916修改',
})
axios.delete(`${hostUrl}/api/v1/posts/${id}`)
看起來都成功了,表示我們 call 的 url 沒有問題~
我會想特別拿 routes
出來講是因為,
之前後端大大就告訴我就這樣 call axios.get('/api/v1/....')
,
還有要傳入的資料格式,
但一開始我根本不知道 /api/v1/
是什麼意思,
然後就在自己開 API 試寫的時候也終於搞清楚了,
通常後端 API 都會提供像 axios.get('/api/v1/....')
這樣的 url 供前端 call,
這樣我們以後看到 /api/v1
就會知道是 API 的 url。
所以也把這段拿出來分享這樣~
前端應該是不用知道 routes 的設定之類的,
現在的情境只是因為我們自己起簡單的 API 來玩玩看所以才需要設,
因此今日重點不是擺在怎麼設 routes 哦!
今天是不是又更了解前端怎麼 call API 了呢?
那我們明天再見囉~~~
Add custom routes
json-server cannot access via local IP
今天終於來到一半orz