http-client.js 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import { HttpError } from './http-error'
  2. import { parseApiResponse, snapshotEnvelope } from './response-evaluator'
  3. function finalizeResponse(res) {
  4. snapshotEnvelope(res)
  5. const parsed = parseApiResponse(res)
  6. if (parsed.kind === 'success' || parsed.kind === 'passthrough') {
  7. return {
  8. data: parsed.data,
  9. msg: parsed.message,
  10. raw: res
  11. }
  12. }
  13. throw HttpError.fromParsed(parsed)
  14. }
  15. export function request(options = {}) {
  16. return new Promise((resolve, reject) => {
  17. uni.request({
  18. ...options,
  19. success(res) {
  20. try {
  21. resolve(finalizeResponse(res))
  22. } catch (err) {
  23. reject(err)
  24. }
  25. },
  26. fail(err) {
  27. reject(HttpError.fromNetwork(err))
  28. }
  29. })
  30. })
  31. }
  32. export function get(url, data, extra = {}) {
  33. return request({ url, data, method: 'GET', ...extra })
  34. }
  35. export function post(url, data, extra = {}) {
  36. return request({ url, data, method: 'POST', ...extra })
  37. }
  38. export function put(url, data, extra = {}) {
  39. return request({ url, data, method: 'PUT', ...extra })
  40. }
  41. export function del(url, data, extra = {}) {
  42. return request({ url, data, method: 'DELETE', ...extra })
  43. }
  44. export function upload(url, options = {}) {
  45. return new Promise((resolve, reject) => {
  46. uni.uploadFile({
  47. url,
  48. ...options,
  49. success(res) {
  50. if (res.statusCode !== 200) {
  51. reject(HttpError.fromUpload(res))
  52. return
  53. }
  54. let data = res.data
  55. try {
  56. data = typeof data === 'string' ? JSON.parse(data) : data
  57. } catch (_) {}
  58. resolve({ data, raw: res })
  59. },
  60. fail(err) {
  61. reject(HttpError.fromNetwork(err))
  62. }
  63. })
  64. })
  65. }
  66. /**
  67. * 由路由表批量生成 API 方法
  68. * @example createApiModule({ profile: { path: buildRestPath('user/profile') } })
  69. */
  70. export function createApiModule(routes) {
  71. const module = {}
  72. Object.keys(routes).forEach((name) => {
  73. const spec = routes[name]
  74. const method = (spec.method || 'GET').toUpperCase()
  75. const caller = method === 'GET' ? get : post
  76. module[name] = (data, extra) => caller(spec.path, data, { method, ...extra })
  77. })
  78. return module
  79. }
  80. export function createHttpFacade() {
  81. return { request, get, post, put, del, upload, createApiModule }
  82. }