npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

valor-request

v1.1.9

Published

基于`umi-request`的开箱即用的`request`库

Downloads

22

Readme

valor-request

基于umi-request的开箱即用的request

用法示例

示例 1: 后端返回标准的 Result 结构

如果后端返回的格式如下( response.status 总是返回 200 ) :

// 返回的httpCode===200!
interface Result<T = any> {
  // 由于response.httpStatus=200, 这里放实际的httpStatus
  code: number; //200| 201| 400 | 404 | 403

  // 所有有效数据将保存到这里, 比如分页信息应存为: {data: {meta: ..., data:[...]}}
  data?: T; // {user: [1,2]}

  // 不同于code, 这是业务Code, 比如'ProductionNotExists', 然后前端查取 错误描述
  // 然而: 多数程序直接返回 errorMsg, 所以实际上用不到errorCode

  errorCode?: string;

  errorMsg?: string; // 仅code不为200/201时生效
}

比如在nodejs时这样写:

正常:
response.send({code: 200, data: {users: [1]}}});
错误: 用msg表示错误
response.send({code: 404, errorMsg: '页面不存在'});

那么前端配置非常简单:

// rpc.ts
import getRequest from 'valor-request';
export default getRequest({
  prefix: 'http://localhost:3001/api',
})

使用时:

import request from './rpc';
function getUsers() {
  return request('/users');
}

示例 2: 后端用 http status 表示成功与失败

由于返回格式与Result格式不兼容, 需要进行转换(normalize):
后端返回:

正常: 用data表示数据
response.send({data: {users: [1]}}});
错误: 用msg表示错误
response.status(404).send({msg: '页面不存在'});

前端配置:

// rpc.ts
import getRequest from 'valor-request';
export default getRequest({
  prefix: 'http://localhost:3001/api',
  normalize: (result:any)  => ({
    code: 200,   <== 统一设为200
    data: result.data,
    errorMsg: result.msg
  })
})

使用:

import request from './getRequest';
function getUsers() {
  return request('/users');
}

示例 3: 后端返回的 http status 永远为 200, 用 result.code 表示成功与失败

此种情形与valor-request假设一致, 但可能字段名称与Result不匹配, 同样需要进行转换(normalize):
后端返回:

正常:
response.send({xcode: 200, xdata: {users: [1]}}});
错误: 用msg表示错误
response.send({xcode: 200, xmsg: '页面不存在'});

前端配置:

// rpc.ts
import getRequest from 'valor-request';
export default getRequest({
  prefix: 'http://localhost:3001/api',
  normalize: (result:any)  => ({
    code: result.xcode,   <== 统一设为200
    data: result.xdata,
    errorMsg: result.xmsg
  })
})

示例 4: 添加错误处理与 loading 状态

前端配置:

// rpc.ts
import getRequest from 'valor-request';
import uiStore from './UIStore';
export default getRequest({
  prefix: 'http://localhost:3001/api',
  onError: (e) => uiStore.addMsg(e.errorMsg),
  beforeRequest: () => uiStore.setLoading(true),
  afterRequest: () => uiStore.setLoading(false)
})

示例 5: 配置写 token 的方法

默认写入headers: {Authorization: Bearer ${token}}
默认tokenlocalStorage.getItem('token')读取
如果跟实际情况不一致, 请使用如下方式覆盖:

import getRequest from 'valor-request';
export default getRequest({
  setToken() {
    const token = localStorage.getItem('jwttoken');
    return {token};
  }
})

动机

每个项目, 总是要造一个request轮子
无论你使用axios, 还是最简单的fetch, 或是umi-request, 你总得考虑以下问题:

  • token如何整合
  • 如何处理错误处理, 错误是留到上层处理, 还是底层处理
  • loading状态要在底层处理, 还是由调用者自行处理
  • 后台应该返回status状态码, 还是全部返回200+error-data
  • 如何将后台返回的数据结构, 与你的前台数据结构进行对应

进一步, 你可能还得考虑:

  • 超时
  • 缓存(对报表型的应用尤其重要)

所以干脆再造一个轮子, 目的是上手即用

特性

实际上, valor-request是一个统一的(微型)请求框架:

  • 自动整合tokenrequest.header
  • 转换器: 实现前后台数据结构对应.
  • 全局错误处理
  • 请求生命周期 hook, 方便实现自己的 loading 状态管理
  • 可设置请求超时
  • 可实现GET型请求缓存

底层

基于umi-request
其实底层是什么都不重要, 选umi-request的原因是: 小而全(详见其官网对照表)\

用法

  1. yarn add valor-request
  2. 配置: 见下面的描述
  3. 使用: 见上面的例子

基本配置

import getRequest from 'valor-request';
getRequest({
  // 在ajax型请求前面加上/api前缀
  prefix: '/api',
  // 显示loading状态
  beforeRequest: () => uiStore.showLoading(true),
  afterResponse: () => uiStore.showLoading(false),
  // 显示错误
  onError: (e) => uiStore.addError(e)
});
export default request;

注意如下的精简配置, 必须满足以下条件:

  1. token来自`localStorage.getItem('token'),
  2. token将保存为request.header['Authorization']='Bearer ${token}'
  3. 后台返回数据结构:
type Result<T> {
  code: 200 | 403 | 404 |...;
  data?: T;
  errorMsg?: string;
}

这是目前比较通用的结构, 特点是:

  • response.status总是200
  • 错误码写在result.code
  • 一旦发生错误, 则dataundefined, errorMsg是中文错误信息
  • 字段级错误可以通过将 json 字符串写在errorMsg里解决
  • 不太符合 http 标准, 但在国内最常用
  1. 请求超时10秒
  2. cache

Result 转换

getRequest({
  normalize: (后台返回的result格式) => Result
})

参见前面的例子.
总之, 你得保证最后得到的Result刚好是valor-request的标准Result

错误处理

getRequest({
  onError(error:Result) => ...
})

注意这里收到的error, 是已转化为Result格式的!\

超时

getRequest({
  timeout: 5000
})

开启缓存

getRequest({
  cache: {max/*最多缓存记录*/, ttl/*缓存超时*/}
})

覆盖其它继承自umi-request的配置项

暂时只能一次性覆盖, 直到找到需要永久覆盖的场景:

import request from './rpc';
request(umi-request配置项).then(...)