From 4a0cc8da77223605f3d628b6538f90aadceb8de7 Mon Sep 17 00:00:00 2001 From: crayon <873217631@qq.com> Date: Sat, 23 Oct 2021 19:09:50 +0800 Subject: [PATCH] =?UTF-8?q?optimization:=20=E5=89=8D=E7=AB=AF=20api=20modu?= =?UTF-8?q?le=20=E4=BB=A3=E7=A0=81=E7=94=9F=E6=88=90=E8=A7=84=E8=8C=83?= =?UTF-8?q?=E6=94=B9=E8=BF=9B(closed=20#228)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../management/commands/generate_api_js.py | 17 ++-- apps/utils/generate_api_js.py | 33 ++++--- dev_log/2.1.354/crayon_202110231905.yaml | 3 + docs/{ => workflows/release/api}/nodeman.yaml | 0 docs/workflows/release/api/readme.md | 93 +++++++++++++++++++ frontend/src/api/modules/installchannel.js | 20 ++-- frontend/src/api/modules/subscription.js | 2 - 7 files changed, 134 insertions(+), 34 deletions(-) create mode 100644 dev_log/2.1.354/crayon_202110231905.yaml rename docs/{ => workflows/release/api}/nodeman.yaml (100%) create mode 100644 docs/workflows/release/api/readme.md diff --git a/apps/node_man/management/commands/generate_api_js.py b/apps/node_man/management/commands/generate_api_js.py index 6aa39f929..fa647a4ae 100644 --- a/apps/node_man/management/commands/generate_api_js.py +++ b/apps/node_man/management/commands/generate_api_js.py @@ -13,14 +13,13 @@ from collections import defaultdict import yaml -from django.conf import settings from django.core.management.base import BaseCommand from apps.utils.generate_api_js import main -def esb_json2apigw_yaml(json_file_path: str): - with open(file=json_file_path, encoding="utf-8") as esb_json_file_stream: +def esb_json2apigw_yaml(esb_json_file_path: str, apigw_yaml_save_path: str): + with open(file=esb_json_file_path, encoding="utf-8") as esb_json_file_stream: esb_json = json.loads(esb_json_file_stream.read()) # 对相同api路径进行聚合 @@ -62,11 +61,7 @@ def esb_json2apigw_yaml(json_file_path: str): } apigw_json["paths"][api_path] = http_method_api_info_map - with open( - os.path.join(settings.BASE_DIR, settings.APP_CODE, "support-files", "nodeman.apigw.yaml"), - encoding="utf-8", - mode="w", - ) as f: + with open(apigw_yaml_save_path, encoding="utf-8", mode="w") as f: yaml.dump(apigw_json, f, encoding="utf-8", allow_unicode=True) @@ -74,11 +69,13 @@ class Command(BaseCommand): def add_arguments(self, parser): parser.add_argument("-g", "--is_apigw", action="store_true", help="whether for api_gateway") parser.add_argument("--is_apigw_yaml", action="store_true", help="convert esb json to apigw yaml") - parser.add_argument("-f", type=str, help="json file path, required when select --is-apigw-yaml") + parser.add_argument("-f", type=str, help="apigw yaml save path") def handle(self, **kwargs): if kwargs["is_apigw_yaml"]: - esb_json2apigw_yaml(kwargs["f"]) + esb_json_file_path = main(is_apigw=True) + esb_json2apigw_yaml(esb_json_file_path=esb_json_file_path, apigw_yaml_save_path=kwargs["f"]) + os.remove(esb_json_file_path) else: main(kwargs["is_apigw"]) diff --git a/apps/utils/generate_api_js.py b/apps/utils/generate_api_js.py index c325f040a..1edc422c3 100644 --- a/apps/utils/generate_api_js.py +++ b/apps/utils/generate_api_js.py @@ -9,18 +9,19 @@ specific language governing permissions and limitations under the License. """ import os +from typing import Dict import ujson as json from django.template import engines -TEMPLATE = """import { request } from '../base' +TEMPLATE = """import { request } from '../base'; -{% for api in apis %}export const {{ api.name }} = request('{{ api.type }}', '{{ api.url | safe }}') +{% for api in apis %}export const {{ api.name }} = request('{{ api.type }}', '{{ api.url | safe }}'); {% endfor %} export default { - {% for api in apis %}{% if forloop.last %}{{ api.name }}{% else %}{{ api.name }}, - {% endif %}{% endfor %} -} + {% for api in apis %}{% if forloop.last %}{{ api.name }},{% else %}{{ api.name }}, + {% endif %}{% endfor %} +}; """ Timeout = 30 @@ -46,6 +47,19 @@ def remove_first_slash(url): return url +def route(api: Dict[str, str]): + url = api["url"].format() + if api["url"] in ("/get_gse_config/", "/report_log/", "/package/upload/", "/export/download/"): + url = "/backend" + url + elif api["group"] in ("subscription", "backend_plugin"): + url = "/backend/api" + url + elif api["group"] in ["rsa"]: + url = "/core/api" + url + else: + url = "/api" + url + return url + + def main(is_apigw=False): apidoc_path = os.path.join("static", "apidoc") os.system(f"apidoc -i apps -o {apidoc_path}") @@ -58,13 +72,7 @@ def main(is_apigw=False): for api in apis: if api["group"] in GW_group_excludes and api.get("name") not in GW_api_includes: continue - url = api["url"].format() - if api["url"] in ("/get_gse_config/", "/report_log/", "/package/upload/", "/export/download/"): - url = "/backend" + url - elif api["group"] in ("subscription", "backend_plugin"): - url = "/backend/api" + url - else: - url = "/api" + url + url = route(api) data = { "path": url, "resource_name": api.get("name", "name"), @@ -80,6 +88,7 @@ def main(is_apigw=False): file_name = os.path.join("support-files", "api_gateway.json") with open(file_name, "w", encoding="utf-8") as fh: fh.write(json.dumps(output)) + return file_name else: for api in apis: api["name"] = underscore_to_camel(api["name"]) diff --git a/dev_log/2.1.354/crayon_202110231905.yaml b/dev_log/2.1.354/crayon_202110231905.yaml new file mode 100644 index 000000000..fc46796bc --- /dev/null +++ b/dev_log/2.1.354/crayon_202110231905.yaml @@ -0,0 +1,3 @@ +--- +optimization: + - "前端 api module 代码生成规范改进(closed #228)" diff --git a/docs/nodeman.yaml b/docs/workflows/release/api/nodeman.yaml similarity index 100% rename from docs/nodeman.yaml rename to docs/workflows/release/api/nodeman.yaml diff --git a/docs/workflows/release/api/readme.md b/docs/workflows/release/api/readme.md new file mode 100644 index 000000000..adb657640 --- /dev/null +++ b/docs/workflows/release/api/readme.md @@ -0,0 +1,93 @@ +# 接口管理 + + + +## ESB yaml +> 命名:nodeman.yaml +> +> 作用:用于注册到 ESB + +### 格式 + +```yaml +- api_type: operate + comp_codename: generic.v2.nodeman.nodeman_component + name: subscription_delete + label: test + label_en: null + dest_path: /backend/api/subscription/delete/ + path: /v2/nodeman/backend/api/subscription/delete/ + dest_http_method: POST + suggest_method: POST + is_hidden: true +``` + +### 新增方式 + +* 1⃣️ 在 [nodeman.yaml](nodeman.yaml) 加入新增的接口, +* 2⃣️ 将该 yaml 文件的同步到 ESB 仓库 + + + +## apigw yaml +> 命名:apigw.yaml +> +> 作用:注册到 APIGW + +### 格式 + +```yaml + /core/api/encrypt_rsa/fetch_public_keys/: + post: + description: 获取公钥列表 + operationId: rsa_fetch_public_keys + tags: + - rsa + x-bk-apigateway-resource: + allowApplyPermission: true + authConfig: + userVerifiedRequired: false + backend: + matchSubpath: false + method: post + path: /core/api/encrypt_rsa/fetch_public_keys/ + timeout: 30 + transformHeaders: {} + type: HTTP + upstreams: {} + disabledStages: [] + isPublic: true + matchSubpath: false +``` + +### 新增方式 + +自动生成 apigw.yaml +```shell +python manage.py generate_api_js --is_apigw_yaml -f docs/workflows/release/api/apigw.yaml +``` + +导入到 APIGW + +## 前端 API modules +> 作用:用于前端请求后台 + +### 格式 + +```js +import { request } from '../base'; + +export const fetchPublicKeys = request('POST', 'encrypt_rsa/fetch_public_keys/'); + +export default { + fetchPublicKeys, +}; +``` + +### 新增方式 + +* 后台定义好接口后,执行 `python manage.py generate_api_js`,该命名会生成代码到 `frontend/src/api/modules` + +* 和后台代码一并提交,前端基于该分支进行开发联调 + + diff --git a/frontend/src/api/modules/installchannel.js b/frontend/src/api/modules/installchannel.js index ffe75497d..ddb19a07d 100644 --- a/frontend/src/api/modules/installchannel.js +++ b/frontend/src/api/modules/installchannel.js @@ -1,13 +1,13 @@ -import { request } from '../base' +import { request } from '../base'; -export const createInstallChannel = request('POST', 'install_channel/') -export const deleteInstallChannel = request('DELETE', 'install_channel/{{pk}}/') -export const listInstallChannel = request('GET', 'install_channel/') -export const updateInstallChannel = request('PUT', 'install_channel/{{pk}}/') +export const createInstallChannel = request('POST', 'install_channel/'); +export const deleteInstallChannel = request('DELETE', 'install_channel/{{pk}}/'); +export const listInstallChannel = request('GET', 'install_channel/'); +export const updateInstallChannel = request('PUT', 'install_channel/{{pk}}/'); export default { - createInstallChannel, - deleteInstallChannel, - listInstallChannel, - updateInstallChannel -} + createInstallChannel, + deleteInstallChannel, + listInstallChannel, + updateInstallChannel, +}; diff --git a/frontend/src/api/modules/subscription.js b/frontend/src/api/modules/subscription.js index 992aec56d..8b377d73f 100644 --- a/frontend/src/api/modules/subscription.js +++ b/frontend/src/api/modules/subscription.js @@ -5,7 +5,6 @@ export const collectSubscriptionTaskResultDetail = request('POST', 'subscription export const createSubscription = request('POST', 'subscription/create/'); export const deleteSubscription = request('POST', 'subscription/delete/'); export const fetchCommands = request('POST', 'subscription/fetch_commands/'); -export const fetchPolicyTopo = request('POST', 'subscription/fetch_policy_topo/'); export const getGseConfig = request('POST', 'get_gse_config/'); export const listDeployPolicy = request('POST', 'subscription/search_deploy_policy/'); export const queryHostPolicy = request('GET', 'subscription/query_host_policy/'); @@ -31,7 +30,6 @@ export default { createSubscription, deleteSubscription, fetchCommands, - fetchPolicyTopo, getGseConfig, listDeployPolicy, queryHostPolicy,