jsonpath做接口封装使用技巧
作者:德莱厄斯 发布时间:2024-04-18 09:52:01
前言
jsonpath是一个可以在复杂的json数据中根据用户指定的规则找到特定数据的库。
本文利用jsonpath对接口进行封装,旨在写一个对前端友好的、易维护的、高扩展性的、可读的api json
如果同学知道xPath,那么可以轻松的掌握jsonpath,如果从没听说过这两个东西,可以根据第一小节快速了解。写法不拘泥于以下代码,内容仅提供思路。
快速开始 jsonpath
let obj = {...}
let queryData = jsonpath.query(obj,"$..[?(@.name=='ni')]")
上述语法意思为:
$:从根元素开始,也就是`$.`,后面的`.` 意思是递归查询,即查询到最后一级子节点。
[?()]:条件语句,其中`@.`代指当前节点,可以理解为`forof`中的项(item)
如上所示,jsonpath最常用的query方法,有两个参数,第一个是数据源,第二个是查询语句。
此外,jsonpath还常用nodes和paths查询键值的路径、value查询值等。
使用jsonpath封装api
封装axios
封装axios的过程没有用到jsonpath,我们在这里只对方法做了统一。
以封装get为例:
import getUrl from "./apis" // 这个就是你自己写的接口json,下面会讲
get(topic, data) {
let url
if (topic.indexOf('http') === 0 || topic.indexOf('https') === 0) {
url = topic
} else {
url = getUrl(topic)
}
return new Promise((resolve, reject) => {
axios.get(url, {
params: data
})
.then(response => {
resolve(response.data)
}, err => {
reject(err)
})
})
},
我们传入一个topic(主题),和一个data(参数)。
data需要根据方法的不同做不同的处理,比如post函数中就应该直接axios.post(api(topic), data),而不是用上述语法。
topic的作用是在api中找出对应的url,后面会讲到,这是用jsonpath做到的。
axios到这里就可以了,相信各位小伙伴也有自己封装的方法,其实也都大差不差,你依然可以使用你自己的axios。
封装api
我们一直希望有一个易于管理和使用的api封装的方法,使用jsonpath可以轻松的做到这一点,我们完全可以写一个只给人类看的api文档,而不用考虑格式是否容易被读取。
比如,我们可以把api.js写成这样:
const apis = {
mainDomain: {
baseUrl: "https://yourmainDomain.com",
uri: {
introduction: {
topic: "introduction",
uri: "/introduction",
pramas: {
appCode: String,
type: Number
}
},
someData: {
topic: "someData",
uri: "/somepath/somewhere/someData",
},
}
},
other:{...}
}
由上可见,我们将api以 域名>uri+参数的形式写成了一个大的对象,就像写一个文档一样,这个格式的数据很有利于开发人员阅读,我们清楚的知道每个接口来自哪台主机、它的参数是什么,如果你愿意,你完全可以加一个method字段,那样我们就可以知道它的方法是什么。总之,你可以通过加字段的方式对这个文档进行维护,直到这个文档有你想要的一切信息,并且你自己可以看得懂。
如果没有jsonpath,我们可能需要对这个json进行一个稍微复杂的遍历,以找出我们需要的完整接口地址。
而根据以上结构,我们使用jsonpath很容易的就可以确定一个接口的完整地址,以及它需要的参数
const getUrl = (topic) => {
let path = jsonpath.paths(apis, `$..[?(@.topic=='${topic}')]`)
let { baseUrl } = jsonpath.query(apis, `$.${path[0][1]}`)[0]
let { uri } = jsonpath.query(apis, `$..[?(@.topic=='${topic}')]`)[0]
return baseUrl + uri //返回完整api地址
}
export default getUrl //这里就是暴露刚刚用到的方法
只需要传入一个topic,即可根据topic找出完整的地址。topic可以根据接口地址某字段取值或者直接取一个根接口功能高度相关的字符,比如,取用户信息的接口,我们把topic写成getUserInfo,管他接口长什么样子,我们调用只需要:
let userInfo = await request.get('getUserInfo')
根据上述思路,我们需要做的几步分别是:
根据自己的喜好封装axios
根据自己的喜好写一个接口json
根据自己写的json编写jsonpath查询
做完这三步后,就可以使用了。
一般我们把请求和接口json分开,假如我们定义request.js和api.js
那么,在request 中引入api.js的getUrl方法,用来解析开发者传入的topic,并返回一个axios的promise对象即可。我们将各种方法放在一个大对象中,比如:
import axios from "axios"
import api from "./apis"
import qs from "qs"
const request = {
//...post...get......
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name) == 0) return c.substring(name.length, c.length);
}
return "";
}
export default request
像这样,就完成了全部封装流程
完成后的效果
用起来的感受就像下面:
import request from '@/utils/request';
let bugsData = await request.get('getBugsData', {
beginTimeS: time.begin,
endTimeS: time.end
})
let bugsData = await request.post('setUserInfo', {
nickName: "德莱厄斯",
})
let bugsData = await request.put('someApi', {
someKey: "someValue",
})
可以看到,在使用此方法封装后,调用时,只需要传入一个字符串,一个对象代表参数即可,且不用随着method的变化更换参数格式,因为在封装axios时,我对他们做了统一处理,无论我们要调用get还是post,都只需按照一个格式写请求即可。
在这种封装模式下,是很容易拓展的,你可以按照自己的喜好给它加各种 * 。
来源:https://juejin.cn/post/7229257105797070909


猜你喜欢
- 一、Go语言通道基础概念1.channel产生背景 线程之间进行通信的时候,会因为资源的争夺而产生竟态问
- 一、根据条件在序列中筛选数据假设有一个数字列表 data, 过滤列表中的负数data = [1, 2, 3, 4, -5]# 使用列表推导式
- 异常的传递性在 Python 中,异常的传递性指的是,当一个异常没有被处理时,它会沿着调用栈向上抛出,直到被处理或者导致程序崩溃。具体来说,
- CocosCreator在1.8版本开始,就支持一键发布微信小程序,下面是详细的发布步骤:1、在微信公众平台下载微信开发者工具 地
- 本文为大家分享了微信小程序radio组件的使用方法,供大家参考,具体内容如下效果图WXML<view class="tui-
- 在应用中,有时候会 依赖第三方模块执行方法,比如调用某模块的上传下载,数据库查询等操作的时候,如果出现网络问题或其他问题,可能有超时重新请求
- Python中提供了两个关键字用来控制循环语句,分别是break和continuebreak在条件成立时,不会执行循环中的后续代码,并且会停
- 总的来讲,JavaSever PagesTM(JSP)和 微软的Active Sever Pages(ASP)在技术方面有许多相似之处。两者
- Python 中常用的数据类型包括:数字类型:包括整型(int)、长整型(long)、浮点型(float)、复数型(comple
- 备份MySQL数据库的命令mysqldump -hhostname -uusername -ppassword databasename &
- SqlBulkCopy 来自数据源的 String 类型的给定值不能转换为指定目标列的类型 nvarchar。 在网上找了下,大都说是因为数
- MySQL ERROR 1045 (28000): Access denied for user 'root'@'l
- 一、导入所需的库import turtleimport randomfrom math import *二、生成斐波那契数列斐波那契数列是指
- SQLServer中有五种约束,Primary Key约束、Foreign Key约束、Unique约束、Default约束和Check约束
- 系统环境centos7python2.7先在操作系统安装expect[root@V71 python]# vi 3s.py#!/usr/bi
- DJANGO_SETTINGS_MODULE使用Django时要通知Django当前使用的是哪个配置文件。可以改变环境变量 DJANGO_S
- Sql中in和not in中有null值的情况1)in的逻辑规则是or not in 的逻辑规则是 and2)判断null 的sql语句为
- 最近这段时间研究Node感觉不错,自己做了一个增删改查,虽然有些简陋,但是思想是想通的,其实所有项目都是增删改查,有助于初学者快速掌握Nod
- 一,进程的理论基础一个应用程序,归根结底是一堆代码,是静态的,而进程才是执行中的程序,在一个程序运行的时候会有多个进程并发执行。进程和线程的
- 一、关于XML解析XML在Java应用程序里变得越来越重要, 广泛应用于数据存储和交换. 比如我们常见的配置文件,都是以XML方式存储的.