README
anymock-openapi
可跨端的 Anymock Openapi SDK。可用于获取 Mock 数据以及其他众多 openapi。
—— 一款好用的 Anymock 平台 辅助工具
Install
tnpm install anymock-openapi --save
Concept
通过调用者使用不同环境下的的请求发生器,该 openapi sdk 可以灵活适配浏览器或 Node.js 场景。
请求发生器在本 SDK 中被抽象成“管道”,英文名 pipe。
Use
Browser
import AnymockOpenapi from 'anymock-openapi';
import { EClients, ETypes } from 'anymock-include';
const fetch = window.fetch;
const config = {
fromClient: EClients.chromeExtensionAnymock,
// 请前往 https://anymock.alipay.com/ 获取项目 token
projectToken: 'YOUR_ANYMOCK_PROJECT_TOKEN',
};
/**
* Pipe for browser.
* @params {IRequestOptions} options
* @return Promise<any>
*/
const pipe = (options) => {
// interface IRequestOptions {
// url: string;
// headers: { [key: string]: any };
// method: string;
// data: { [key: string]: any }
// }
const url = options.url;
const body = JSON.stringify(options.data);
delete options.url;
delete options.data;
return fetch(url, { ...options, body })
.then(res => res.json());
};
const openapi = new AnymockOpenapi(config, pipe);
main();
async function main() {
// 1. fetch mock data
const resp = await openapi.mock.query({
type: ETypes.HTTP,
subType: 'POST',
matching: '/post',
// parameters: {},
});
console.log('mock resp from https://anymock.alipay.com:\n', resp);
console.log();
console.log('mock data:')
console.log(resp.data.mock.data);
console.log();
console.log('typeof mock data:', typeof resp.data.mock.data);
// 2. fetch project details
const { data: projectDetails } = await openapi.project.get();
// projectDetails interface
// {
// id: string;
// name: string;
// cname: string;
// // ...
// }
}
Node.js
Playground: https://runkit.com/embed/qaym3apxzvma
const fetch = require('node-fetch');
const AnymockOpenapi = require('anymock-openapi').default;
const { EClients, ETypes } = require('anymock-include');
const config = {
fromClient: EClients.nodejsAnymock,
// 请前往 https://anymock.alipay.com/ 获取项目 token
projectToken: 'YOUR_ANYMOCK_PROJECT_TOKEN',
};
/**
* Pipe for Node.js.
* @params {IRequestOptions} options
* @return Promise<T>
*/
const pipe = (options) => {
// interface IRequestOptions {
// url: string;
// headers: { [key: string]: any };
// method: string;
// data: { [key: string]: any }
// }
const url = options.url;
const body = JSON.stringify(options.data);
delete options.url;
delete options.data;
return fetch(url, { ...options,body })
.then(res => res.json());
};
const openapi = new AnymockOpenapi(config, pipe);
main();
async function main() {
const resp = await openapi.mock.query({
type: ETypes.HTTP,
subType: 'POST',
matching: '/post',
});
console.log('mock resp from https://anymock.alipay.com:\n', resp);
console.log();
console.log('mock data:')
console.log(resp.data.mock.data);
console.log();
console.log('typeof mock data:', typeof resp.data.mock.data);
}
openapi
所有 openapi 方法返回值类型均遵循:
interface IAnymockResponse<T = null> {
success: boolean;
data: T;
errorMessage: string;
errorCode: string;
errorExtra: any;
}
公共类型:
// import { IAnymockConfigUpdate } from 'anymock-include';
export interface IAnymockConfigUpdate {
/**
* 用户是否自定义请求 mock 数据的 host
* 默认 https://anymock.alipay.com。注意无结尾斜杠“/”
*/
host?: string;
/**
* 用户 token
*/
userToken?: string;
/**
* 项目 token
* 必选
* 请前往 https://anymock.alipay.com/ 获取
*/
projectToken?: string;
/**
* 请求来源
*/
fromClient?: EClients | string;
}
Mock 数据
获取 Mock 数据
方法:openapi.mock.query({ payload: IMockQueryPayload, options?: IAnymockConfigUpdate })
入参:
// import { IMockQueryPayload } from 'anymock-include';
export interface IMockQueryPayload {
type: ETypes;
/** 如果是 type 是 HTTP,则 subType 可以是 GET POST 等 */
subType?: string;
matching: string;
/** 场景 ID。指定返回某个场景下的数据 */
sceneId?: string;
parameters?: any;
}
export enum ETypes {
HTTP = 'HTTP',
MTOP = 'MTOP',
JSAPI = 'JSAPI',
}
返回值:Promise<IAnymockResponse<IMockResp>>
export interface IMockResp {
mock: {
data: string;
};
}
示例:
const resp = await openapi.mock.query({
type: ETypes.HTTP,
subType: 'GET',
matching: '/api/projects',
// parameters: {},
});
更新 Mock 数据
方法:openapi.mock.update(requestId: ID, mockId: ID, payload: Partial<IMock>, config?: IAnymockConfigUpdate)
入参:
export type ID = string | number;
export interface IMock {
data: string;
dataType: number;
gmtCreate: string;
gmtModified: string;
id: number;
mockType: MockTypeEnum;
requestId: number;
}
返回值:Promise<IAnymockResponse<any>>
示例:
const resp = await openapi.mock.update({
requestId: 1001,
mockId: 2001,
payload: {
data: '{ success: false, name: "anymock" }'
},
});
项目
获取项目详情
方法:openapi.project.get(options?: IAnymockConfigUpdate, payload: IGetProjectPayload = {})
入参:可选
返回值:Promise<IAnymockResponse<IProject>>
export interface IProject {
id: number;
gmtCreate: string;
gmtModified: string;
name: string;
cname: string;
avatar?: any;
description: string;
spaceId: number;
status: number;
token: string;
members: IMember[];
}
export interface IMember {
id: number;
anymockId: string;
userId: string;
userName: string;
nickName: string;
avatar: string;
}
示例:
openapi.project.get()
接口
获取接口列表
方法:openapi.interface.list(options?: IAnymockConfigUpdate, payload?: IQuery = {})
入参:可选
export interface IQuery {
[key: string]: any;
}
返回值:Promise<IAnymockResponse<IInterface[]>>
export interface IInterface {
cname?: any;
description?: any;
gmtCreate: string;
gmtModified: string;
id: number;
matching: string;
matchingType: string;
name: string;
projectId: number;
request: IRequest[];
subType: string;
type: string;
}
export interface IRequest {
cname: string;
gmtCreate: string;
gmtModified: string;
id: number;
interfaceId: number;
isActive: boolean;
mock: IMock[];
status: number;
}
export interface IMock {
data: string;
dataType: number;
gmtCreate: string;
gmtModified: string;
id: number;
mockType: MockTypeEnum;
requestId: number;
}
export enum MockTypeEnum {
ResponseBody = 1,
ResponseHeader = 2,
RequestBody = 3,
RequestHeader = 4,
}
新增接口
方法:openapi.interface.create(payload: IInterfaceModifiableParams, options?: IAnymockConfigUpdate)
入参:必须
export interface IInterfaceModifiableParams {
type: string;
/** 若 HTTP 接口则该字段必须 */
subType?: string;
matching: string;
name?: string;
description?: string;
}
返回值:Promise<IAnymockResponse<number>>
返回新增接口的 id
示例:
openapi.interface.create({
type: ETypes.HTTP,
subType: 'GET',
matching: '/api/projects/:pid',
})
获取接口详情
方法:openapi.interface.get(interfaceId?: string | number, config?: IAnymockConfigUpdate)
入参:接口 id
返回值:Promise<IAnymockResponse<IInterface>>
// 已有,省略
示例:
openapi.interface.get(10001)
更新接口
方法:openapi.interface.update(interfaceId: ID, payload: IInterfaceModifiableParams, config?: IAnymockConfigUpdate)
入参:必须
export interface IQuery {
[key: string]: any;
}
返回值:Promise<IAnymockResponse<null>>
示例:
openapi.interface.update(1001, { matching: '/api/projects/:pid/interfaces' })
删除接口
方法:openapi.interface.delete(interfaceId: ID, config?: IAnymockConfigUpdate)
入参:必须
返回值:Promise<IAnymockResponse<null>>
示例:
openapi.interface.update(1001)
请求
创建请求(有明确的 interfaceId)
方法:openapi.request.create(interfaceId: ID, payload: Partial<IRequest>, config?: IAnymockConfigUpdate)
入参:必须
返回值:Promise<IAnymockResponse<object>>
示例:
openapi.request.create(1001, {
cname: '成功'
})
获取请求详情
方法:openapi.request.get(requestId: ID, config?: IAnymockConfigUpdate)
入参:必须
返回值:Promise<IAnymockResponse<IRequest>>
示例:
openapi.request.get(2001)
更新请求
方法:openapi.request.update(interfaceId: ID, requestId: ID, payload: Partial<IRequest>, config?: IAnymockConfigUpdate)
入参:必须
返回值:Promise<IAnymockResponse<object>>
示例:
openapi.request.update(1001, 2001, {
cname: '失败'
})
删除请求
方法:openapi.request.delete(requestId: ID, config?: IAnymockConfigUpdate)
入参:必须
返回值:Promise<IAnymockResponse<null>>
示例:
openapi.request.delete(2001)
新增请求(可能存在 interfaceId)
复合接口,有可能会先创建一个接口。
当接口存在则在接口下创建一个 request,否则先创建接口然后在其下新增一个 request
定位接口是否存在的规则:优先通过 interfaceId 或通过三要素(type / subType / matching)
方法:openapi.request.addRequest(payload: IAddRequestParam, config?: IAnymockConfigUpdate)
入参:必须
export interface IAddRequestParam {
/**
* 若有则通过 interfaceId 唯一定位一个 interface
* 否则通过三要素唯一定位(性能相对较差,但是为了客户端方便)
*/
interfaceId?: ID;
// 这些属性来自 interface
// 三要素
type: string;
subType: string;
matching: string;
description?: string;
name?: string;
// 这才是 request 的真正属性
request: {
cname: string;
mock: { data: string };
};
}
返回值:Promise<IAnymockResponse<{ interface: { id: ID }; request: any }>>
示例:
// 如果 type subType matching 相同的接口存在,则在该接口下新增一个 request
// 否则先创建接口,然后在其下新增一个 request
openapi.request.addRequest({
type: 'HTTP',
subType: 'POST',
matching: '/api/projects/:pid',
request: {
cname: '成功',
mock: {
data: "{ success: true, name: 'anymock' }"
}
}
});
场景
获取场景列表
方法:openapi.scene.list(options?: IAnymockConfigUpdate, payload?: IQuery = {})
入参:可选
返回值:Promise<IAnymockResponse<IScene[]>>
export interface IScene extends Omit<ISceneDBProps, 'id' | 'projectId' | 'status'> {
/** 场景 id */
id: string,
/** 所属项目 id */
projectId: string,
name: string,
description: string;
active: boolean;
records: ISceneRecord[];
sceneUser: ISceneUser,
}
interface ISceneRecord extends IBaseDBProps {
id: string;
sceneId: string;
interface: IInterface;
}
type ISceneUser = ISceneUserDB;
interface ISceneUserDB extends IBaseDBProps {
id: number;
sceneId: number;
userId: number;
interfaceId: number;
status: number;
}
interface IBaseDBProps {
gmtCreate: string;
gmtModified: string;
}
示例:
const resp = await openapi.scene.list();
Develop
UT
ANYMOCK_HOST=http://127.0.0.1:7002 yarn test packages/openapi/__tests__/scene.spec.ts
yarn test packages/openapi/__tests__/basic.spec.ts