【发布时间】:2017-11-15 08:12:36
【问题描述】:
我正在创建一个以 django rest 框架为后端并以响应为前端的 Web 应用程序。我从 create-react-app 生成的反应应用程序。要进行 api 调用,我使用 fetch Api。我在我的 api 调用中看到了一些需要重构的重复。但我知道这里哪种模式更好。
代码如下:
Api.js
let _options = {headers: new Headers({'Content-Type': 'application/json'})}
const _url = {
'users': '/api/users/',
'obtain-token': '/api/obtain-token/',
'verify-token': '/api/verify-token/',
'refresh-token': '/api/refresh-token/'
}
const _fetch = (request) => {
return fetch(request)
.then(res => {
if ( ! res.ok) {
let err = {
'status': res.status,
'statusText': res.statusText,
'data': {}
}
return res.json().then(
data => {
err.data = data
return Promise.reject(new Error(JSON.stringify(err)))
},
() => Promise.reject(new Error(JSON.stringify(err)))
)
}
return res.json()
})
.catch(err => {
return Promise.reject(err)
})
}
export const obtainToken = (username, password) => {
const credential = {username, password}
let options = _options
options.method = 'POST'
options.body = JSON.stringify(credential)
const request = new Request(_url['obtain-token'], options)
return _fetch(request)
}
export const verifyToken = (token) => {
let options = _options
options.method = 'POST'
options.body = JSON.stringify({token})
const request = new Request(_url['verify-token'], options)
return _fetch(request)
}
export const refreshToken = (token) => {
let options = _options
options.method = 'POST'
options.body = JSON.stringify({token})
const request = new Request(_url['refresh-token'], options)
return _fetch(request)
}
export const getUser = (username, token='') => {
let options = _options
options.method = 'GET'
if (token) options.headers.append('Authorization', `JWT ${token}`)
const request = new Request(`${_url['users']}/${username}`, options)
return _fetch(request)
}
我喜欢这段代码的地方是,当我需要请求资源时,我只是运行一个带有所需参数的函数,而不知道它是 get 或 post 还是其他,我不需要传递 header 配置和 url。
// example api call
let token = '4346h9r7yt47t9...'
verifyToken(token)
.then(data => {
// server response json available here
token = data.token
})
.catch(err => {
// handle network error and bad response here
console.log(err)
})
我正在关注@challenge 解决方案。并设法缩短它:
// Change _build function name to makeRequest and export it
const makeRequest = (name, _url='', body=undefined, headers={}) => {
let [method, url] = source[name]
let options = {
headers: new Headers({
'Content-Type': 'application/json',
...headers,
})
}
options.method = method
if (body) options.body = JSON.stringify(body)
return _fetch(url+_url, options)
}
export default makeRequest
但是,当然要调用这个函数,我需要提供附加的 url,如果需要,还需要一个自定义标题。但是随着这个项目的进行,证明需要附加 url(由用户详细资源使用)和 costum 标头(由需要身份验证的资源使用)。
【问题讨论】:
标签: javascript rest api design-patterns refactoring