[英]Need insight on how to build javascript fetch API
我正在创建一个将Django rest框架作为后端的Web应用程序,并作为前端进行响应。 我从create-react-app生成的react应用程序。 要进行api调用,我使用访存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,否则我不需要传递标头配置和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)
})
我正在关注@挑战者解决方案。 并设法使它变得更短:
// 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标头(由需要身份验证的资源使用)。
let source = {
'getUser': ['GET', '/api/users/'],
'obtain-token': ['POST','/api/obtain-token/'],
'verify-token': ['POST','/api/verify-token/'],
'refresh-token':['POST', '/api/refresh-token/']
}
let _build = (name, _url, body, 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 new Request(url+_url, options)
}
接着
export const obtainToken = (username, password) => {
const credential = {username, password}
const request = _build('obtainToken','', credential, {})
return _fetch(request)
}
export const verifyToken = (token) => {
const request = _build('verifyToken', '',{token}, {})
return _fetch(request)
}
export const refreshToken = (token) => {
const request = _build('refreshToken', '', {token}, {})
return _fetch(request)
}
export const getUser = (username, token='') => {
let headers = {'Authorization': `JWT ${token}`}
const request = _build('getUser',`/${username}`, undefined, headers)
return _fetch(request)
}
甚至更多,而不是...
return new Request(url+_url, options)
在_build函数中,您可以将其替换为
return _fetch(new Request(url+_url, options))
这使您可以拥有:
export const obtainToken = (username, password) => {
const credential = {username, password}
return _build('obtainToken','', credential, {})
}
export const verifyToken = (token) => {
return _build('verifyToken', '',{token}, {})
}
export const refreshToken = (token) => {
retun _build('refreshToken', '', {token}, {})
}
export const getUser = (username, token='') => {
let headers = {'Authorization': `JWT ${token}`}
return _build('getUser',`/${username}`, undefined, headers)
}
let source = {
'getUser': (..._p) => ['GET', `/api/users/${_p[0]}`, undefined, {'Authorization': `JWT ${_p[1]}`}],
'obtainToken': (..._p) => ['POST','/api/obtain-token/', {username:_p[0], password:_p[1]}],
'verifyToken': (..._p) => ['POST','/api/verify-token/', {token:_p[0]}],
'refreshToken': (..._p) => ['POST', '/api/refresh-token/',{token:_p[0]}]
}
const requests = {}
Object.keys(source).forEach(key => {
requests[key] = (...params) => {
let [method, url, body, headers ={}] = source[key](...params)
let options = {
headers: new Headers({
'Content-Type': 'application/json',
...headers,
})
}
options.method = method
if (body) options.body = JSON.stringify(body)
return _fetch(new Request(url, options))
}
})
export default requests
它需要更多的测试和审查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.