[Design Pattern] Encapsulate a network request lib - 4. API Template

When company's API become huge and always changing, if request-busis maintained by developers manually, it's not only time consuming but also error prone.

We can introduce some standard automation process to resolve the problem.

 

Examples:

{
  "endpoints": {
    "article": {
      "publishArticle": {
        "path": "/api/article",
        "description": "Publish an article",
        "method": "POST",
        "auth": true,
        "idempotent": true,
        "cache": false,
        "pager": false
        // Other fields
      },
      "getArticles": {
        "path": "/api/article",
        "description": "Retrieve articles",
        "method": "GET",
        "auth": false,
        "idempotent": false,
        "cache": false,
        "pager": true
        // Other fields
      }
    }
  }
}

 

The generated code could be something like:

// /request-bus/template/article.ts

import { createIdempotentRequest } from 'request-core';

/**
 * Publish an article
 */
export const publishArticle = (() => {
	const req = createIdempotentRequest();
	return async (article: Article) => {
		return req.post('/api/article', article).then((resp) => resp.json());
	};
})();

/**
 * Retrieve articles
 */
export const getArticles = (() => {
	return async (page: number, size: number) => {
		const params = { page, size };
		return req.get('/api/article', { params }).then((resp) => resp.json());
	};
})();


/**
 * Retrieve articles
 */
export const getArticles = (() => {
  return async (page: number, size: number) => {
    return req.get('/api/article', {
      params: {
        page,
        size,
      },
    }).then((resp) => resp.json());
  };
})();

 

Override

It is possilbe that for the generated code, you might want to apply some changes. The way to do it is pretty simple:

export * from "./template"

export {publishArticle} from './patch'

We want have a patchfolder which contains the override, and using Javascript override directly to achieve the effect.

 

Summary

At the implementation level, I first consider the overall architecture of the request library.

I divide the request library into three layers, from bottom to top:

  1. Request Base Library: Responsible for the basic functionality of sending requests.
  2. Request Core Library: Responsible for implementing various upper-layer logics, such as concurrency, etc.
  3. Request Business Library: Responsible for encapsulating company-internal conventions at the code level.

From a structural perspective, considering that the specific implementation of the request base library may change (e.g., switching xhr to axios or fetch), to reduce the changes impacting upper-layer code, I apply the DIP (Dependency Inversion Principle). Inspired by front-end IOC (Inversion of Control) and DI (Dependency Injection) principles, the core library does not rely on a specific request base library. Instead, the request base library only needs to provide a TypeScript interface. The request core library can provide multiple implementation methods for the interface, and specific implementations can be injected into the business library. This completely decouples the core library from the specific implementation of the request library, allowing for flexible adjustments later.

Additionally, the business library is deeply tied to the company’s internal API documentation. In our project, there are an extremely large number of APIs. To reduce development and maintenance costs, I implemented an automated tool in Node.js. This tool parses standardized API documentation and automatically generates request template code for each endpoint. It also considers that some template code might not meet actual requirements, so a method is defined to supplement the template code. This approach reduces development workload while ensuring flexibility.


 

posted @   Zhentiw  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2022-12-01 [Typescript] 123. Hard - Intersection
2021-12-01 [AWS] Assign a public IP address to an EC2 instance after launched
2020-12-01 [Java Spring] Implementing Spring Security
2019-12-01 [Javascript] Sort by multi factors
2019-12-01 [Javascript] Keyword 'in' to check prop exists on Object
2015-12-01 [Javascript] Advanced Reduce: Common Mistakes
点击右上角即可分享
微信分享提示