背景
当我们在实际生产中做前后端分离的项目时,总是需要前端去封装调用后台给的接口服务、好烦怎么办?
目的
减少这部分工作,少做或不做。
演示场景
后端java使用swagger输出接口文档。别的后端服务类似,只要接口文档支持输出openApi规范的文档。
前端工程化使用的webpack、框架使用React/Typescript。
实现步骤
手动获取swagger对应的json描述文件,放入项目下指定文件夹下


npm/npx全局安装或下载 openapi-generator 的jar包放在本地,这里使用下载放入项目目录下。当然目录名字你可以随便。
npm install @openapitools/openapi-generator-cli -g

在npm配置文件下配置启动、输入、输出、依赖和一些配置参数(参考OpenAPI Generator官网根据自己实际需求修改)
{
"scripts":{
"_gen": "java -jar ./.bin/openapi-generator-cli-6.4.0.jar generate -i ./.scripts/swagger_api.json -o src/api/generated -g typescript-axios --additional-properties=withSeparateModelsAndApi=true,apiPackage=api,modelPackage=model",
}
}
/**
java -jar ./.bin/openapi-generator-cli-4.3.1.jar 运行代码生成jar包
generate 运行时默认需要
-i ./.scripts/swagger_DingBLOG.json 输入要生产代码的json文件
-o src/api/generated 输出位置
-g 指定生成器
--additional-properties=withSeparateModelsAndApi=true,apiPackage=api,modelPackage=model 针对生成器添加的参数配置
*/
一键生成服务代码
执行脚本生成服务
/* tslint:disable */
/* eslint-disable */
/**
* Dkw BLOG
* 本文档描述了微服务接口定义
*
* The version of the OpenAPI document: 0.0.1-SNAPSHOT
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import type { Configuration } from '../configuration';
import type { AxiosPromise, AxiosInstance, AxiosRequestConfig } from 'axios';
import globalAxios from 'axios';
// Some imports not used depending on template conditions
// @ts-ignore
import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';
// @ts-ignore
import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from '../base';
// @ts-ignore
import { Blog } from '../model';
// @ts-ignore
import { Result } from '../model';
/**
* BlogControllerApi - axios parameter creator
* @export 这里仅贴部分
*/
export const BlogControllerApiAxiosParamCreator = function (configuration?: Configuration) {
return {
/**
*
* @summary deleteBlog
* @param {number} id id
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
deleteBlogUsingPOST: async (id: number, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'id' is not null or undefined
assertParamExists('deleteBlogUsingPOST', 'id', id)
const localVarPath = `/blog/delete/{id}`
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @summary detail
* @param {number} id id
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
detailUsingGET: async (id: number, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'id' is not null or undefined
assertParamExists('detailUsingGET', 'id', id)
const localVarPath = `/blog/{id}`
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
5.具体使用
export class BlogControllerApi extends BaseAPI // 生成的服务继承BaseAPI
export class BaseAPI {
protected configuration: Configuration | undefined;
constructor(configuration?: Configuration, protected basePath: string = BASE_PATH, protected axios: AxiosInstance = globalAxios) {
if (configuration) {
this.configuration = configuration;
this.basePath = configuration.basePath || this.basePath;
}
}
};
const blogServer = new BlogControllerApi({},"xx",AxiosInstance);
blogServer.detailUsingGET(id); // 这里使用时可以自己封装一个服务类统一处理
如下:
export class blogService {
authApi: BlogControllerApi;
constructor(baseUrl: string, axios: AxiosInstance) {
this.blogServer = new BlogControllerApi({}, baseUrl, axios);
}
async delteBlogById(id:string) {
const res = this.blogServer.delteBlogById(id);
return res?.data
}
}
总结
我们要利用一切手段寻找可以“偷懒”的方法和技术,这是人类进步的动力。