# 在低代码中使用 GitLab API
低代码引擎的产出物是一份符合页面搭建协议的 JSON Schema,其可读性差,且浏览器不能直接运行,将 JSON Schema 转成最终可执行的代码,涉及到出码,流程如下图所示:
整个出码流程在服务端进行,与用户没有交互。由上图可知,出码需要的 JSON Schema 从 git 仓库得来,它输出的符合 icejs 项目框架的源码保存在另一个 git 仓库,本文主要介绍如何用 GitLab API 操作 git 仓库。
开发者手写代码时,会在开发分支编写代码,最终将代码合并到主分支,如 master 分支,存储 Schema 也采用类似的策略,低代码引擎生成的 Schema 被保存到开发分支,发布页面时,开发分支上的Schema 被 cherry-pick 到 master 分支,把 master 分支上的 Schema 转化成源码再打包构建,最后部署上线。
# access_token
使用 GitLab API 之前必须知道你的账号在 GitLab 上的 access_token,之后每一次调用 API 在请求头中携带该 access_token,访问 https://gitlab.com/-/profile/personal_access_tokens 查看账号的 access_token,在 https://docs.gitlab.com/ee/api/ 可查看全部 GitLab API。
在服务端使用 axios 发起 GitLab API 网络请求,这与在客户端使用 axios 一样,先创建一个 axios 实例,设置 baseURL 和 headers,代码如下:
import axios from "axios"
import ENV_CONFIG from '../../env.config.json'
const axiosInstance = axios.create({
baseURL: "https://gitlab.com",
headers: {
"PRIVATE-TOKEN": <这里填你的access_token>,
"Content-Type": 'application/json'
}
})
# 存储Schema
Schema 保存在仓库中,对 GitLab 而言,这里的仓库是指项目,如下图所示:
注意上图标记的 Project ID,该字段在后续存储 Schema 时会继续使用,调用 GitLab API 把某个 Schema 存储到仓库,需经历创建项目、创建分支和提交 commit 这 3 步。
# 创建项目
创建项目发生在新建业务单元的时候,要为每一个业务单元创建一个 GitLab 项目,代码如下:
async function createProject(name: string, description: string) {
const result = await axiosInstance.request({
method: 'POST',
url: '/api/v4/projects',
data: {
name,
description,
default_branch: 'develop',
initialize_with_readme: true,
visibility: 'public',
}
})
// 返回Project ID
return result.data.id
}
# 创建分支
上一步所建项目的默认分支名是 develop,这一步基于 develop 创建 master 分支,代码如下:
async function createBranch(projectId: string, branch: string, ref: string) {
const result = await axiosInstance.request({
method: 'POST',
url: `/api/v4/projects/${projectId}/repository/branches`,
params: {
branch,
ref
}
})
return result.data
}
# 提交 commit
提交 commit 将 Schema 保存到仓库,代码如下:
interface CreateCommitParam {
branch: string,
commit_message: string,
actions: Action[],
start_branch?: string,
start_sha?: string,
[attr: string]: any
}
async function createCommit(projectId: string, params: CreateCommitParam) {
const result = await axiosInstance.request({
method: 'POST',
url: `/api/v4/projects/${projectId}/repository/commits`,
data: params
})
return result.data
}
上述代码值得关注的是 CreateCommitParam.actions,它表示本次提交要执行的动作集合。Action 接口包含字段如下:
interface Action {
action: 'create' | 'delete' | 'move' | 'update' | 'chmod',
// action要处理的文件路径
file_path: string,
// 当action为move时,它表示被移动文件的原始路径
previous_path?: string,
// 当action为create或update时,它表示文件内容
content?: string,
// 取值为text或base64,默认值是text
encoding?: string,
// 主要action为delete、 move 或update时有效
last_commit_id?: string,
// action为chmod时有效
execute_filemode?: boolean
}
# 获取 Schema
Schema 保存到 git仓库,等需要使用的时候再取出来,代码如下:
async function getFileContent(projectId: string, ref: string, file_path: string) {
const result = await axiosInstance.request({
method: 'GET',
url: `/api/v4/projects/${projectId}/repository/files/${encodeURIComponent(file_path)}/raw`,
params: {
ref
}
})
return result.data
}
上述 API 能从特定 git 仓库获取文件的内容,ref 指分支名或 commit id。
# 总结
常规开发中,维护应用程序的版本相当重要,一个常见的例子是使用 git 来维护版本,对于特定版本而言,它一经创建便不可修改。低代码系统用来产生应用程序,因此它也有版本维护的需求,在这里不另辟蹊径,而是沿用常规的方法,用 git 维护版本,Schema 保存到仓库中,调用 GitLab API 时需要的参数被保存在数据库。